fix: code simplification and fixes the key validation in bulk contacts upload api

This commit is contained in:
pandeymangg
2026-02-06 12:59:03 +05:30
parent 38765edd0c
commit 5a215fcbf7
21 changed files with 117 additions and 71 deletions

View File

@@ -604,6 +604,7 @@ checksums:
environments/contacts/create_key: 0d385c354af8963acbe35cd646710f86
environments/contacts/create_new_attribute: c17d407dacd0b90f360f9f5e899d662f
environments/contacts/create_new_attribute_description: cc19d76bb6940537bbe3461191f25d26
environments/contacts/custom_attributes: fffc7722742d1291b102dc737cf2fc9e
environments/contacts/data_type: 1ea127ba2c18d0d91fb0361cc6747e2b
environments/contacts/data_type_cannot_be_changed: 22603f6193fdac3784eeef8315df70de
environments/contacts/data_type_description: 800bf4935df15e6cb14269e1b60c506e
@@ -619,6 +620,7 @@ checksums:
environments/contacts/edit_attributes_success: 39f93b1a6f1605bc5951f4da5847bb22
environments/contacts/generate_personal_link: 9ac0865f6876d40fe858f94eae781eb8
environments/contacts/generate_personal_link_description: b9dbaf9e2d8362505b7e3cfa40f415a6
environments/contacts/invalid_csv_column_names: dcb8534e7d4c00b9ea7bdaf389f72328
environments/contacts/invalid_date_format: 5bad9730ac5a5bacd0792098f712b1c4
environments/contacts/invalid_number_format: bd0422507385f671c3046730a6febc64
environments/contacts/no_published_link_surveys_available: 9c1abc5b21aba827443cdf87dd6c8bfe
@@ -634,13 +636,16 @@ checksums:
environments/contacts/search_contact: 020205a93846ab3e12c203ac4fa97c12
environments/contacts/select_a_survey: 1f49086dfb874307aae1136e88c3d514
environments/contacts/select_attribute: d93fb60eb4fbb42bf13a22f6216fbd79
environments/contacts/select_attribute_key: 673a6683fab41b387d921841cded7e38
environments/contacts/system_attributes: eadb6a8888c7b32c0e68881f945ae9b6
environments/contacts/unlock_contacts_description: c5572047f02b4c39e5109f9de715499d
environments/contacts/unlock_contacts_title: a8b3d7db03eb404d9267fd5cdd6d5ddb
environments/contacts/upload_contacts_modal_attribute_header: 263246ad2a76f8e2f80f0ed175d7629a
environments/contacts/upload_contacts_modal_attributes_description: e2cedbd4a043423002cbb2048e2145ac
environments/contacts/upload_contacts_modal_attributes_new: 9829382598c681de74130440a37b560f
environments/contacts/upload_contacts_modal_attributes_search_or_add: 1874839e465650d353282b43b00247a9
environments/contacts/upload_contacts_modal_attributes_should_be_mapped_to: 693dfe5836e90b1c4c7c65b015418174
environments/contacts/upload_contacts_modal_attributes_title: 86d0ae6fea0fbb119722ed3841f8385a
environments/contacts/upload_contacts_modal_csv_column_header: f181add48fb8325efaa40579fe8c343e
environments/contacts/upload_contacts_modal_description: 41566d40d25cc882aa9f82d87b4e2f03
environments/contacts/upload_contacts_modal_download_example_csv: 7a186fc4941b264452ee6c9e785769de
environments/contacts/upload_contacts_modal_duplicates_description: 112ce4641088520469a83a0bd740b073

View File

@@ -676,11 +676,12 @@
"system_attributes": "Systemattribute",
"unlock_contacts_description": "Verwalte Kontakte und sende gezielte Umfragen",
"unlock_contacts_title": "Kontakte mit einem höheren Plan freischalten",
"upload_contacts_modal_attribute_header": "Formbricks-Attribut",
"upload_contacts_modal_attributes_description": "Ordne die Spalten in deiner CSV den Attributen in Formbricks zu.",
"upload_contacts_modal_attributes_new": "Neues Attribut",
"upload_contacts_modal_attributes_search_or_add": "Attribut suchen oder hinzufügen",
"upload_contacts_modal_attributes_should_be_mapped_to": "sollte zugeordnet werden zu",
"upload_contacts_modal_attributes_title": "Attribute",
"upload_contacts_modal_csv_column_header": "CSV-Spalte",
"upload_contacts_modal_description": "Lade eine CSV hoch, um Kontakte mit Attributen schnell zu importieren",
"upload_contacts_modal_download_example_csv": "Beispiel-CSV herunterladen",
"upload_contacts_modal_duplicates_description": "Wie sollen wir vorgehen, wenn ein Kontakt bereits existiert?",

View File

@@ -680,7 +680,6 @@
"upload_contacts_modal_attributes_description": "Map the columns in your CSV to the attributes in Formbricks.",
"upload_contacts_modal_attributes_new": "New attribute",
"upload_contacts_modal_attributes_search_or_add": "Search or add attribute",
"upload_contacts_modal_attributes_should_be_mapped_to": "should be mapped to",
"upload_contacts_modal_attributes_title": "Attributes",
"upload_contacts_modal_csv_column_header": "CSV Column",
"upload_contacts_modal_description": "Upload a CSV to quickly import contacts with attributes",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Atributos del sistema",
"unlock_contacts_description": "Gestiona contactos y envía encuestas dirigidas",
"unlock_contacts_title": "Desbloquea contactos con un plan superior",
"upload_contacts_modal_attribute_header": "Atributo de Formbricks",
"upload_contacts_modal_attributes_description": "Asigna las columnas de tu CSV a los atributos en Formbricks.",
"upload_contacts_modal_attributes_new": "Nuevo atributo",
"upload_contacts_modal_attributes_search_or_add": "Buscar o añadir atributo",
"upload_contacts_modal_attributes_should_be_mapped_to": "debe asignarse a",
"upload_contacts_modal_attributes_title": "Atributos",
"upload_contacts_modal_csv_column_header": "Columna CSV",
"upload_contacts_modal_description": "Sube un CSV para importar rápidamente contactos con atributos",
"upload_contacts_modal_download_example_csv": "Descargar CSV de ejemplo",
"upload_contacts_modal_duplicates_description": "¿Cómo deberíamos manejar si un contacto ya existe en tus contactos?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Attributs système",
"unlock_contacts_description": "Gérer les contacts et envoyer des enquêtes ciblées",
"unlock_contacts_title": "Débloquez des contacts avec un plan supérieur.",
"upload_contacts_modal_attribute_header": "Attribut Formbricks",
"upload_contacts_modal_attributes_description": "Mappez les colonnes de votre CSV aux attributs dans Formbricks.",
"upload_contacts_modal_attributes_new": "Nouvel attribut",
"upload_contacts_modal_attributes_search_or_add": "Rechercher ou ajouter un attribut",
"upload_contacts_modal_attributes_should_be_mapped_to": "devrait être mappé à",
"upload_contacts_modal_attributes_title": "Attributs",
"upload_contacts_modal_csv_column_header": "Colonne CSV",
"upload_contacts_modal_description": "Téléchargez un fichier CSV pour importer rapidement des contacts avec des attributs.",
"upload_contacts_modal_download_example_csv": "Télécharger un exemple de CSV",
"upload_contacts_modal_duplicates_description": "Que faire si un contact existe déjà ?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "システム属性",
"unlock_contacts_description": "連絡先を管理し、特定のフォームを送信します",
"unlock_contacts_title": "上位プランで連絡先をアンロック",
"upload_contacts_modal_attribute_header": "Formbricks属性",
"upload_contacts_modal_attributes_description": "CSVの列をFormbricksの属性にマッピングします。",
"upload_contacts_modal_attributes_new": "新しい属性",
"upload_contacts_modal_attributes_search_or_add": "属性を検索または追加",
"upload_contacts_modal_attributes_should_be_mapped_to": "は以下にマッピングする必要があります",
"upload_contacts_modal_attributes_title": "属性",
"upload_contacts_modal_csv_column_header": "CSV列",
"upload_contacts_modal_description": "CSVをアップロードして、属性を持つ連絡先をすばやくインポート",
"upload_contacts_modal_download_example_csv": "CSVの例をダウンロード",
"upload_contacts_modal_duplicates_description": "連絡先がすでに存在する場合、どのように処理しますか?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Systeemkenmerken",
"unlock_contacts_description": "Beheer contacten en verstuur gerichte enquêtes",
"unlock_contacts_title": "Ontgrendel contacten met een hoger abonnement",
"upload_contacts_modal_attribute_header": "Formbricks attribuut",
"upload_contacts_modal_attributes_description": "Wijs de kolommen in uw CSV toe aan de attributen in Formbricks.",
"upload_contacts_modal_attributes_new": "Nieuw attribuut",
"upload_contacts_modal_attributes_search_or_add": "Kenmerk zoeken of toevoegen",
"upload_contacts_modal_attributes_should_be_mapped_to": "in kaart moeten worden gebracht",
"upload_contacts_modal_attributes_title": "Kenmerken",
"upload_contacts_modal_csv_column_header": "CSV kolom",
"upload_contacts_modal_description": "Upload een CSV om snel contacten met attributen te importeren",
"upload_contacts_modal_download_example_csv": "Voorbeeld-CSV downloaden",
"upload_contacts_modal_duplicates_description": "Hoe moeten we omgaan als er al een contact bestaat in uw contacten?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Atributos do sistema",
"unlock_contacts_description": "Gerencie contatos e envie pesquisas direcionadas",
"unlock_contacts_title": "Desbloqueie contatos com um plano superior",
"upload_contacts_modal_attribute_header": "Atributo do Formbricks",
"upload_contacts_modal_attributes_description": "Mapeie as colunas do seu CSV para os atributos no Formbricks.",
"upload_contacts_modal_attributes_new": "Novo atributo",
"upload_contacts_modal_attributes_search_or_add": "Buscar ou adicionar atributo",
"upload_contacts_modal_attributes_should_be_mapped_to": "deve ser mapeado para",
"upload_contacts_modal_attributes_title": "Atributos",
"upload_contacts_modal_csv_column_header": "Coluna CSV",
"upload_contacts_modal_description": "Faça upload de um CSV para importar contatos com atributos rapidamente",
"upload_contacts_modal_download_example_csv": "Baixar exemplo de CSV",
"upload_contacts_modal_duplicates_description": "O que devemos fazer se um contato já existir nos seus contatos?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Atributos do sistema",
"unlock_contacts_description": "Gerir contactos e enviar inquéritos direcionados",
"unlock_contacts_title": "Desbloqueie os contactos com um plano superior",
"upload_contacts_modal_attribute_header": "Atributo Formbricks",
"upload_contacts_modal_attributes_description": "Mapeie as colunas no seu CSV para os atributos no Formbricks.",
"upload_contacts_modal_attributes_new": "Novo atributo",
"upload_contacts_modal_attributes_search_or_add": "Pesquisar ou adicionar atributo",
"upload_contacts_modal_attributes_should_be_mapped_to": "deve ser mapeado para",
"upload_contacts_modal_attributes_title": "Atributos",
"upload_contacts_modal_csv_column_header": "Coluna CSV",
"upload_contacts_modal_description": "Carregue um ficheiro CSV para importar rapidamente contactos com atributos",
"upload_contacts_modal_download_example_csv": "Descarregar exemplo de CSV",
"upload_contacts_modal_duplicates_description": "Como devemos proceder se um contacto já existir nos seus contactos?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Atribute de sistem",
"unlock_contacts_description": "Gestionează contactele și trimite sondaje țintite",
"unlock_contacts_title": "Deblocați contactele cu un plan superior.",
"upload_contacts_modal_attribute_header": "Atribut Formbricks",
"upload_contacts_modal_attributes_description": "Mapează coloanele din CSV-ul tău la atributele din Formbricks.",
"upload_contacts_modal_attributes_new": "Atribut nou",
"upload_contacts_modal_attributes_search_or_add": "Căutați sau adăugați atribut",
"upload_contacts_modal_attributes_should_be_mapped_to": "ar trebui să fie mapat către",
"upload_contacts_modal_attributes_title": "Atribute",
"upload_contacts_modal_csv_column_header": "Coloană CSV",
"upload_contacts_modal_description": "Încărcați un fișier CSV pentru a importa rapid contactele cu atribute.",
"upload_contacts_modal_download_example_csv": "Descărcați exemplul CSV",
"upload_contacts_modal_duplicates_description": "Cum ar trebui să procedăm dacă un contact există deja în agenda dumneavoastră?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Системные атрибуты",
"unlock_contacts_description": "Управляйте контактами и отправляйте целевые опросы",
"unlock_contacts_title": "Откройте доступ к контактам с более высоким тарифом",
"upload_contacts_modal_attribute_header": "Атрибут Formbricks",
"upload_contacts_modal_attributes_description": "Сопоставьте столбцы в вашем CSV с атрибутами в Formbricks.",
"upload_contacts_modal_attributes_new": "Новый атрибут",
"upload_contacts_modal_attributes_search_or_add": "Найти или добавить атрибут",
"upload_contacts_modal_attributes_should_be_mapped_to": "должен быть сопоставлен с",
"upload_contacts_modal_attributes_title": "Атрибуты",
"upload_contacts_modal_csv_column_header": "Столбец CSV",
"upload_contacts_modal_description": "Загрузите CSV, чтобы быстро импортировать контакты с атрибутами",
"upload_contacts_modal_download_example_csv": "Скачать пример CSV",
"upload_contacts_modal_duplicates_description": "Как поступить, если контакт уже существует в вашей базе?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "Systemattribut",
"unlock_contacts_description": "Hantera kontakter och skicka ut riktade enkäter",
"unlock_contacts_title": "Lås upp kontakter med en högre plan",
"upload_contacts_modal_attribute_header": "Formbricks-attribut",
"upload_contacts_modal_attributes_description": "Mappa kolumnerna i din CSV till attributen i Formbricks.",
"upload_contacts_modal_attributes_new": "Nytt attribut",
"upload_contacts_modal_attributes_search_or_add": "Sök eller lägg till attribut",
"upload_contacts_modal_attributes_should_be_mapped_to": "ska mappas till",
"upload_contacts_modal_attributes_title": "Attribut",
"upload_contacts_modal_csv_column_header": "CSV-kolumn",
"upload_contacts_modal_description": "Ladda upp en CSV för att snabbt importera kontakter med attribut",
"upload_contacts_modal_download_example_csv": "Ladda ner exempel-CSV",
"upload_contacts_modal_duplicates_description": "Hur ska vi hantera om en kontakt redan finns i dina kontakter?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "系统属性",
"unlock_contacts_description": "管理 联系人 并 发送 定向 调查",
"unlock_contacts_title": "通过 更 高级 划解锁 联系人",
"upload_contacts_modal_attribute_header": "Formbricks 属性",
"upload_contacts_modal_attributes_description": "将您 CSV 中的列映射到 Formbricks 中的属性。",
"upload_contacts_modal_attributes_new": "新 属性",
"upload_contacts_modal_attributes_search_or_add": "搜索或添加属性",
"upload_contacts_modal_attributes_should_be_mapped_to": "应该映射到",
"upload_contacts_modal_attributes_title": "属性",
"upload_contacts_modal_csv_column_header": "CSV 列",
"upload_contacts_modal_description": "上传 CSV快速 导入 具有 属性 的 联系人",
"upload_contacts_modal_download_example_csv": "下载 示例 CSV",
"upload_contacts_modal_duplicates_description": "如果联系人已经存在,应该如何处理?",

View File

@@ -676,11 +676,12 @@
"system_attributes": "系統屬性",
"unlock_contacts_description": "管理聯絡人並發送目標問卷",
"unlock_contacts_title": "使用更高等級的方案解鎖聯絡人",
"upload_contacts_modal_attribute_header": "Formbricks 屬性",
"upload_contacts_modal_attributes_description": "將 CSV 中的欄位對應到 Formbricks 中的屬性。",
"upload_contacts_modal_attributes_new": "新增屬性",
"upload_contacts_modal_attributes_search_or_add": "搜尋或新增屬性",
"upload_contacts_modal_attributes_should_be_mapped_to": "應對應到",
"upload_contacts_modal_attributes_title": "屬性",
"upload_contacts_modal_csv_column_header": "CSV 欄位",
"upload_contacts_modal_description": "上傳 CSV 以快速匯入具有屬性的聯絡人",
"upload_contacts_modal_download_example_csv": "下載範例 CSV",
"upload_contacts_modal_duplicates_description": "如果聯絡人已存在於您的聯絡人中,我們應該如何處理?",

View File

@@ -1,8 +1,12 @@
import { z } from "zod";
import { ZContactAttributeDataType } from "@formbricks/types/contact-attribute-key";
import { isSafeIdentifier } from "@/lib/utils/safe-identifier";
export const ZContactAttributeKeyCreateInput = z.object({
key: z.string(),
key: z.string().refine((val) => isSafeIdentifier(val), {
message:
"Key must be a safe identifier: only lowercase letters, numbers, and underscores, and must start with a letter",
}),
description: z.string().optional(),
type: z.enum(["custom"]),
dataType: ZContactAttributeDataType.optional(),
@@ -14,7 +18,13 @@ export type TContactAttributeKeyCreateInput = z.infer<typeof ZContactAttributeKe
export const ZContactAttributeKeyUpdateInput = z.object({
description: z.string().optional(),
name: z.string().optional(),
key: z.string().optional(),
key: z
.string()
.refine((val) => isSafeIdentifier(val), {
message:
"Key must be a safe identifier: only lowercase letters, numbers, and underscores, and must start with a letter",
})
.optional(),
dataType: ZContactAttributeDataType.optional(),
});

View File

@@ -4,6 +4,7 @@ import { prisma } from "@formbricks/database";
import { logger } from "@formbricks/logger";
import { TContactAttributeDataType } from "@formbricks/types/contact-attribute-key";
import { Result, err, ok } from "@formbricks/types/error-handlers";
import { isSafeIdentifier } from "@/lib/utils/safe-identifier";
import { ApiErrorResponseV2 } from "@/modules/api/v2/types/api-error";
import { prepareAttributeColumnsForStorage } from "@/modules/ee/contacts/lib/attribute-storage";
import { detectAttributeDataType } from "@/modules/ee/contacts/lib/detect-attribute-type";
@@ -497,6 +498,22 @@ export const upsertBulkContacts = async (
}),
]);
// Validate new attribute keys are safe identifiers before proceeding
const existingKeySet = new Set(existingAttributeKeys.map((ak) => ak.key));
const invalidNewKeys = attributeKeys.filter((key) => !existingKeySet.has(key) && !isSafeIdentifier(key));
if (invalidNewKeys.length > 0) {
return err({
type: "bad_request",
details: [
{
field: "attributes",
issue: `Invalid attribute key(s): ${invalidNewKeys.join(", ")}. Keys must only contain lowercase letters, numbers, and underscores, and must start with a letter.`,
},
],
});
}
// Type Detection Phase
const attributeValuesByKey = buildAttributeValuesByKey(contacts);
const attributeTypeMap = determineAttributeTypes(attributeValuesByKey, existingAttributeKeys);

View File

@@ -283,11 +283,51 @@ export const UploadContactsCSVButton = ({
// Function to download an example CSV
const handleDownloadExampleCSV = () => {
const exampleData = [
{ email: "user1@example.com", userId: "1001", first_name: "John", last_name: "Doe" },
{ email: "user2@example.com", userId: "1002", first_name: "Jane", last_name: "Smith" },
{ email: "user3@example.com", userId: "1003", first_name: "Mark", last_name: "Jones" },
{ email: "user4@example.com", userId: "1004", first_name: "Emily", last_name: "Brown" },
{ email: "user5@example.com", userId: "1005", first_name: "David", last_name: "Wilson" },
{
email: "user1@example.com",
userId: "1001",
first_name: "John",
last_name: "Doe",
age: "28",
plan: "premium",
signup_date: "2024-01-15",
},
{
email: "user2@example.com",
userId: "1002",
first_name: "Jane",
last_name: "Smith",
age: "34",
plan: "free",
signup_date: "2024-02-20",
},
{
email: "user3@example.com",
userId: "1003",
first_name: "Mark",
last_name: "Jones",
age: "45",
plan: "enterprise",
signup_date: "2023-11-08",
},
{
email: "user4@example.com",
userId: "1004",
first_name: "Emily",
last_name: "Brown",
age: "22",
plan: "premium",
signup_date: "2024-03-01",
},
{
email: "user5@example.com",
userId: "1005",
first_name: "David",
last_name: "Wilson",
age: "31",
plan: "free",
signup_date: "2024-01-28",
},
];
const headers = Object.keys(exampleData[0]);

View File

@@ -3,7 +3,6 @@ import { cache as reactCache } from "react";
import { prisma } from "@formbricks/database";
import { ZId, ZString } from "@formbricks/types/common";
import { TContactAttributes } from "@formbricks/types/contact-attribute";
import { TContactAttributeDataType } from "@formbricks/types/contact-attribute-key";
import { DatabaseError } from "@formbricks/types/errors";
import { ZUserEmail } from "@formbricks/types/user";
import { validateInputs } from "@/lib/utils/validate";
@@ -132,55 +131,24 @@ export const hasUserIdAttribute = reactCache(
);
export const getDistinctAttributeValues = reactCache(
async (attributeKeyId: string, dataType: TContactAttributeDataType, limit: number = 50) => {
async (attributeKeyId: string, limit: number = 50): Promise<string[]> => {
validateInputs([attributeKeyId, ZId]);
try {
// Determine which column to query based on data type
let selectField: "value" | "valueNumber" | "valueDate";
if (dataType === "number") {
selectField = "valueNumber";
} else if (dataType === "date") {
selectField = "valueDate";
} else {
selectField = "value";
}
// Build where clause - only filter by attributeKeyId, we'll filter nulls in JS
const results = await prisma.contactAttribute.findMany({
where: {
attributeKeyId,
value: { not: "" },
},
select: {
value: true,
valueNumber: true,
valueDate: true,
},
distinct: [selectField as any],
distinct: ["value"],
take: limit * 2, // Get more than needed to account for filtering
orderBy: { [selectField]: "asc" },
orderBy: { value: "asc" },
});
// Extract and filter values based on data type
let values: any[];
if (dataType === "number") {
values = results
.map((r) => r.valueNumber)
.filter((v) => v !== null && v !== undefined)
.slice(0, limit);
} else if (dataType === "date") {
values = results
.map((r) => r.valueDate)
.filter((v) => v !== null && v !== undefined)
.slice(0, limit);
} else {
values = results
.map((r) => r.value)
.filter((v) => v !== null && v !== undefined && v !== "")
.slice(0, limit);
}
return values;
return results.map((r) => r.value);
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError) {
throw new DatabaseError(error.message);

View File

@@ -315,7 +315,6 @@ export const resetSegmentFiltersAction = authenticatedActionClient.schema(ZReset
const ZGetDistinctAttributeValuesAction = z.object({
environmentId: ZId,
attributeKeyId: ZId,
dataType: z.enum(["string", "number", "date"]),
});
export const getDistinctAttributeValuesAction = authenticatedActionClient
@@ -337,5 +336,5 @@ export const getDistinctAttributeValuesAction = authenticatedActionClient
],
});
return await getDistinctAttributeValues(parsedInput.attributeKeyId, parsedInput.dataType);
return await getDistinctAttributeValues(parsedInput.attributeKeyId);
});

View File

@@ -1,7 +1,6 @@
"use client";
import { useEffect, useMemo, useState } from "react";
import { TContactAttributeDataType } from "@formbricks/types/contact-attribute-key";
import { cn } from "@/lib/cn";
import { InputCombobox, TComboboxOption } from "@/modules/ui/components/input-combo-box";
import { getDistinctAttributeValuesAction } from "../actions";
@@ -9,9 +8,8 @@ import { getDistinctAttributeValuesAction } from "../actions";
interface AttributeValueInputProps {
attributeKeyId: string;
environmentId: string;
dataType: TContactAttributeDataType;
value: string | number;
onChange: (value: string | number) => void;
value: string;
onChange: (value: string) => void;
disabled?: boolean;
className?: string;
valueError?: string;
@@ -20,7 +18,6 @@ interface AttributeValueInputProps {
export const AttributeValueInput = ({
attributeKeyId,
environmentId,
dataType,
value,
onChange,
disabled,
@@ -45,14 +42,14 @@ export const AttributeValueInput = ({
const result = await getDistinctAttributeValuesAction({
environmentId,
attributeKeyId,
dataType,
});
if (!isCancelled && result?.data) {
const comboboxOptions: TComboboxOption[] = result.data.map((val) => ({
label: String(val),
label: val,
value: val,
}));
setOptions(comboboxOptions);
}
} catch (error) {
@@ -71,7 +68,7 @@ export const AttributeValueInput = ({
return () => {
isCancelled = true;
};
}, [environmentId, attributeKeyId, dataType]);
}, [environmentId, attributeKeyId]);
const emptyDropdownText = useMemo(() => {
if (loading) return "Loading values...";
@@ -85,7 +82,7 @@ export const AttributeValueInput = ({
id={`attribute-value-${attributeKeyId}`}
options={options}
value={value}
onChangeValue={(newValue) => onChange(newValue as string | number)}
onChangeValue={(newValue) => onChange(newValue as string)}
withInput={true}
showSearch={true}
clearable={true}

View File

@@ -315,8 +315,7 @@ function AttributeSegmentFilter({
<AttributeValueInput
attributeKeyId={attributeKey.id}
environmentId={segment.environmentId}
dataType={attributeDataType}
value={resource.value as string | number}
value={resource.value as string}
onChange={(newValue) => {
updateValueInLocalSurvey(resource.id, newValue);
}}