mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-02 11:51:48 -05:00
fix: created at to integrations (#4343)
Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9dad06222d
commit
4ca6ee358b
+6
@@ -57,6 +57,7 @@ export type IntegrationModalInputs = {
|
||||
includeVariables: boolean;
|
||||
includeHiddenFields: boolean;
|
||||
includeMetadata: boolean;
|
||||
includeCreatedAt: boolean;
|
||||
};
|
||||
|
||||
const NoBaseFoundError = () => {
|
||||
@@ -87,6 +88,7 @@ export const AddIntegrationModal = ({
|
||||
const { handleSubmit, control, watch, setValue, reset } = useForm<IntegrationModalInputs>();
|
||||
const [includeHiddenFields, setIncludeHiddenFields] = useState(false);
|
||||
const [includeMetadata, setIncludeMetadata] = useState(false);
|
||||
const [includeCreatedAt, setIncludeCreatedAt] = useState(true);
|
||||
const airtableIntegrationData: TIntegrationAirtableInput = {
|
||||
type: "airtable",
|
||||
config: {
|
||||
@@ -104,6 +106,7 @@ export const AddIntegrationModal = ({
|
||||
setIncludeVariables(!!defaultData.includeVariables);
|
||||
setIncludeHiddenFields(!!defaultData.includeHiddenFields);
|
||||
setIncludeMetadata(!!defaultData.includeMetadata);
|
||||
setIncludeCreatedAt(!!defaultData.includeCreatedAt);
|
||||
} else {
|
||||
reset();
|
||||
}
|
||||
@@ -152,6 +155,7 @@ export const AddIntegrationModal = ({
|
||||
includeVariables: data.includeVariables,
|
||||
includeHiddenFields,
|
||||
includeMetadata,
|
||||
includeCreatedAt,
|
||||
};
|
||||
|
||||
if (isEditMode) {
|
||||
@@ -361,6 +365,8 @@ export const AddIntegrationModal = ({
|
||||
includeMetadata={includeMetadata}
|
||||
setIncludeHiddenFields={setIncludeHiddenFields}
|
||||
setIncludeMetadata={setIncludeMetadata}
|
||||
includeCreatedAt={includeCreatedAt}
|
||||
setIncludeCreatedAt={setIncludeCreatedAt}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
+1
@@ -128,6 +128,7 @@ export const ManageIntegration = (props: ManageIntegrationProps) => {
|
||||
includeVariables: !!data.includeVariables,
|
||||
includeHiddenFields: !!data.includeHiddenFields,
|
||||
includeMetadata: !!data.includeMetadata,
|
||||
includeCreatedAt: !!data.includeCreatedAt,
|
||||
index,
|
||||
});
|
||||
setIsModalOpen(true);
|
||||
|
||||
+6
-1
@@ -67,6 +67,7 @@ export const AddIntegrationModal = ({
|
||||
const [includeVariables, setIncludeVariables] = useState(false);
|
||||
const [includeHiddenFields, setIncludeHiddenFields] = useState(false);
|
||||
const [includeMetadata, setIncludeMetadata] = useState(false);
|
||||
const [includeCreatedAt, setIncludeCreatedAt] = useState(true);
|
||||
const googleSheetIntegrationData: TIntegrationGoogleSheetsInput = {
|
||||
type: "googleSheets",
|
||||
config: {
|
||||
@@ -95,6 +96,7 @@ export const AddIntegrationModal = ({
|
||||
setIncludeVariables(!!selectedIntegration.includeVariables);
|
||||
setIncludeHiddenFields(!!selectedIntegration.includeHiddenFields);
|
||||
setIncludeMetadata(!!selectedIntegration.includeMetadata);
|
||||
setIncludeCreatedAt(!!selectedIntegration.includeCreatedAt);
|
||||
return;
|
||||
} else {
|
||||
setSpreadsheetUrl("");
|
||||
@@ -108,7 +110,7 @@ export const AddIntegrationModal = ({
|
||||
throw new Error(t("environments.integrations.google_sheets.enter_a_valid_spreadsheet_url_error"));
|
||||
}
|
||||
if (!selectedSurvey) {
|
||||
throw new Error(t("environments.integrations.select_a_survey_error"));
|
||||
throw new Error(t("environments.integrations.please_select_a_survey_error"));
|
||||
}
|
||||
if (selectedQuestions.length === 0) {
|
||||
throw new Error(t("environments.integrations.select_at_least_one_question_error"));
|
||||
@@ -134,6 +136,7 @@ export const AddIntegrationModal = ({
|
||||
integrationData.includeVariables = includeVariables;
|
||||
integrationData.includeHiddenFields = includeHiddenFields;
|
||||
integrationData.includeMetadata = includeMetadata;
|
||||
integrationData.includeCreatedAt = includeCreatedAt;
|
||||
if (selectedIntegration) {
|
||||
// update action
|
||||
googleSheetIntegrationData.config!.data[selectedIntegration.index] = integrationData;
|
||||
@@ -278,6 +281,8 @@ export const AddIntegrationModal = ({
|
||||
includeMetadata={includeMetadata}
|
||||
setIncludeHiddenFields={setIncludeHiddenFields}
|
||||
setIncludeMetadata={setIncludeMetadata}
|
||||
includeCreatedAt={includeCreatedAt}
|
||||
setIncludeCreatedAt={setIncludeCreatedAt}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
+8
-1
@@ -144,8 +144,15 @@ export const AddIntegrationModal = ({
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
},
|
||||
];
|
||||
const createdAt = [
|
||||
{
|
||||
id: "createdAt",
|
||||
name: t("common.created_at"),
|
||||
type: TSurveyQuestionTypeEnum.OpenText,
|
||||
},
|
||||
];
|
||||
|
||||
return [...questions, ...variables, ...hiddenFields, ...Metadata];
|
||||
return [...questions, ...variables, ...hiddenFields, ...Metadata, ...createdAt];
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedSurvey?.id]);
|
||||
|
||||
|
||||
+6
-1
@@ -53,6 +53,7 @@ export const AddChannelMappingModal = ({
|
||||
const [includeVariables, setIncludeVariables] = useState(false);
|
||||
const [includeHiddenFields, setIncludeHiddenFields] = useState(false);
|
||||
const [includeMetadata, setIncludeMetadata] = useState(false);
|
||||
const [includeCreatedAt, setIncludeCreatedAt] = useState(true);
|
||||
const existingIntegrationData = slackIntegration?.config?.data;
|
||||
const slackIntegrationData: TIntegrationSlackInput = {
|
||||
type: "slack",
|
||||
@@ -86,6 +87,7 @@ export const AddChannelMappingModal = ({
|
||||
setIncludeVariables(!!selectedIntegration.includeVariables);
|
||||
setIncludeHiddenFields(!!selectedIntegration.includeHiddenFields);
|
||||
setIncludeMetadata(!!selectedIntegration.includeMetadata);
|
||||
setIncludeCreatedAt(!!selectedIntegration.includeCreatedAt);
|
||||
return;
|
||||
}
|
||||
resetForm();
|
||||
@@ -97,7 +99,7 @@ export const AddChannelMappingModal = ({
|
||||
throw new Error(t("environments.integrations.slack.please_select_a_channel"));
|
||||
}
|
||||
if (!selectedSurvey) {
|
||||
throw new Error(t("environments.integrations.integrations.please_select_a_survey_error"));
|
||||
throw new Error(t("environments.integrations.please_select_a_survey_error"));
|
||||
}
|
||||
|
||||
if (selectedQuestions.length === 0) {
|
||||
@@ -118,6 +120,7 @@ export const AddChannelMappingModal = ({
|
||||
includeVariables,
|
||||
includeHiddenFields,
|
||||
includeMetadata,
|
||||
includeCreatedAt,
|
||||
};
|
||||
if (selectedIntegration) {
|
||||
// update action
|
||||
@@ -274,6 +277,8 @@ export const AddChannelMappingModal = ({
|
||||
includeMetadata={includeMetadata}
|
||||
setIncludeHiddenFields={setIncludeHiddenFields}
|
||||
setIncludeMetadata={setIncludeMetadata}
|
||||
includeCreatedAt={includeCreatedAt}
|
||||
setIncludeCreatedAt={setIncludeCreatedAt}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
+4
-17
@@ -10,6 +10,7 @@ import Link from "next/link";
|
||||
import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { getPersonIdentifier } from "@formbricks/lib/person/utils";
|
||||
import { processResponseData } from "@formbricks/lib/responses";
|
||||
import { getFormattedDate, getFormattedTime } from "@formbricks/lib/utils/datetime";
|
||||
import { QUESTIONS_ICON_MAP, VARIABLES_ICON_MAP } from "@formbricks/lib/utils/questions";
|
||||
import { recallToHeadline } from "@formbricks/lib/utils/recall";
|
||||
import { TResponseTableData } from "@formbricks/types/responses";
|
||||
@@ -180,25 +181,11 @@ export const generateResponseTableColumns = (
|
||||
header: () => t("common.date"),
|
||||
size: 200,
|
||||
cell: ({ row }) => {
|
||||
const isoDateString = row.original.createdAt;
|
||||
const date = new Date(isoDateString);
|
||||
|
||||
const formattedDate = date.toLocaleString(undefined, {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
|
||||
const formattedTime = date.toLocaleString(undefined, {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
});
|
||||
|
||||
const date = new Date(row.original.createdAt);
|
||||
return (
|
||||
<div>
|
||||
<p className="text-slate-900">{formattedDate}</p>
|
||||
<p className="text-slate-900">{formattedTime}</p>
|
||||
<p className="text-slate-900">{getFormattedDate(date)}</p>
|
||||
<p className="text-slate-900">{getFormattedTime(date)}</p>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -4,6 +4,8 @@ import { getLocalizedValue } from "@formbricks/lib/i18n/utils";
|
||||
import { writeData as writeNotionData } from "@formbricks/lib/notion/service";
|
||||
import { processResponseData } from "@formbricks/lib/responses";
|
||||
import { writeDataToSlack } from "@formbricks/lib/slack/service";
|
||||
import { getFormattedDate } from "@formbricks/lib/utils/datetime";
|
||||
import { getFormattedTime } from "@formbricks/lib/utils/datetime";
|
||||
import { parseRecallInfo } from "@formbricks/lib/utils/recall";
|
||||
import { TAttributes } from "@formbricks/types/attributes";
|
||||
import { Result } from "@formbricks/types/error-handlers";
|
||||
@@ -37,6 +39,7 @@ const processDataForIntegration = async (
|
||||
includeVariables: boolean,
|
||||
includeMetadata: boolean,
|
||||
includeHiddenFields: boolean,
|
||||
includeCreatedAt: boolean,
|
||||
questionIds: string[],
|
||||
attributes?: TAttributes
|
||||
): Promise<string[][]> => {
|
||||
@@ -58,6 +61,11 @@ const processDataForIntegration = async (
|
||||
}
|
||||
});
|
||||
}
|
||||
if (includeCreatedAt) {
|
||||
const date = new Date(data.response.createdAt);
|
||||
values[0].push(`${getFormattedDate(date)} ${getFormattedTime(date)}`);
|
||||
values[1].push("Created At");
|
||||
}
|
||||
|
||||
return values;
|
||||
};
|
||||
@@ -127,6 +135,7 @@ const handleAirtableIntegration = async (
|
||||
!!element.includeVariables,
|
||||
!!element.includeMetadata,
|
||||
!!element.includeHiddenFields,
|
||||
!!element.includeCreatedAt,
|
||||
element.questionIds
|
||||
);
|
||||
await airtableWriteData(integration.config.key, element, values);
|
||||
@@ -162,6 +171,7 @@ const handleGoogleSheetsIntegration = async (
|
||||
!!element.includeVariables,
|
||||
!!element.includeMetadata,
|
||||
!!element.includeHiddenFields,
|
||||
!!element.includeCreatedAt,
|
||||
element.questionIds
|
||||
);
|
||||
const integrationData = structuredClone(integration);
|
||||
@@ -203,6 +213,7 @@ const handleSlackIntegration = async (
|
||||
!!element.includeVariables,
|
||||
!!element.includeMetadata,
|
||||
!!element.includeHiddenFields,
|
||||
!!element.includeCreatedAt,
|
||||
element.questionIds,
|
||||
attributes
|
||||
);
|
||||
@@ -339,6 +350,10 @@ const buildNotionPayloadProperties = (
|
||||
properties[map.column.name] = {
|
||||
[map.column.type]: getValue(map.column.type, convertMetaObjectToString(data.response.meta)),
|
||||
};
|
||||
} else if (map.question.id === "createdAt") {
|
||||
properties[map.column.name] = {
|
||||
[map.column.type]: getValue(map.column.type, data.response.createdAt.toISOString()),
|
||||
};
|
||||
} else {
|
||||
const value = responses[map.question.id];
|
||||
properties[map.column.name] = {
|
||||
|
||||
@@ -6,73 +6,71 @@ interface AdditionalIntegrationSettingsProps {
|
||||
includeVariables: boolean;
|
||||
includeHiddenFields: boolean;
|
||||
includeMetadata: boolean;
|
||||
includeCreatedAt: boolean;
|
||||
setIncludeVariables: (includeVariables: boolean) => void;
|
||||
setIncludeHiddenFields: (includeHiddenFields: boolean) => void;
|
||||
setIncludeMetadata: (includeHiddenFields: boolean) => void;
|
||||
setIncludeMetadata: (includeMetadata: boolean) => void;
|
||||
setIncludeCreatedAt: (includeCreatedAt: boolean) => void;
|
||||
}
|
||||
|
||||
export const AdditionalIntegrationSettings = ({
|
||||
includeVariables,
|
||||
includeHiddenFields,
|
||||
includeMetadata,
|
||||
includeCreatedAt,
|
||||
setIncludeVariables,
|
||||
setIncludeHiddenFields,
|
||||
setIncludeMetadata,
|
||||
setIncludeCreatedAt,
|
||||
}: AdditionalIntegrationSettingsProps) => {
|
||||
const t = useTranslations();
|
||||
|
||||
const checkboxes = [
|
||||
{
|
||||
id: "includeCreatedAt",
|
||||
checked: includeCreatedAt,
|
||||
onChange: setIncludeCreatedAt,
|
||||
label: t("environments.integrations.include_created_at"),
|
||||
},
|
||||
{
|
||||
id: "includeVariables",
|
||||
checked: includeVariables,
|
||||
onChange: setIncludeVariables,
|
||||
label: t("environments.integrations.include_variables"),
|
||||
},
|
||||
{
|
||||
id: "includeHiddenFields",
|
||||
checked: includeHiddenFields,
|
||||
onChange: setIncludeHiddenFields,
|
||||
label: t("environments.integrations.include_hidden_fields"),
|
||||
},
|
||||
{
|
||||
id: "includeMetadata",
|
||||
checked: includeMetadata,
|
||||
onChange: setIncludeMetadata,
|
||||
label: t("environments.integrations.include_metadata"),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<Label htmlFor="Surveys">{t("environments.integrations.additional_settings")}</Label>
|
||||
<div className="text-sm">
|
||||
<div className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={"includeVariables"} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
type="button"
|
||||
id={"includeVariables"}
|
||||
value={"includeVariables"}
|
||||
className="bg-white"
|
||||
checked={includeVariables}
|
||||
onCheckedChange={() => {
|
||||
setIncludeVariables(!includeVariables);
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2 w-[30rem] truncate">
|
||||
{t("environments.integrations.include_variables")}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={"includeHiddenFields"} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
type="button"
|
||||
id={"includeHiddenFields"}
|
||||
value={"includeHiddenFields"}
|
||||
className="bg-white"
|
||||
checked={includeHiddenFields}
|
||||
onCheckedChange={() => {
|
||||
setIncludeHiddenFields(!includeHiddenFields);
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2 w-[30rem] truncate">
|
||||
{t("environments.integrations.include_hidden_fields")}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={"includeMetadata"} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
type="button"
|
||||
id={"includeMetadata"}
|
||||
value={"includeMetadata"}
|
||||
className="bg-white"
|
||||
checked={includeMetadata}
|
||||
onCheckedChange={() => {
|
||||
setIncludeMetadata(!includeMetadata);
|
||||
}}
|
||||
/>
|
||||
<span className="ml-2 w-[30rem] truncate">{t("environments.integrations.include_metadata")}</span>
|
||||
</label>
|
||||
</div>
|
||||
{checkboxes.map(({ id, checked, onChange, label }) => (
|
||||
<div key={id} className="my-1 flex items-center space-x-2">
|
||||
<label htmlFor={id} className="flex cursor-pointer items-center">
|
||||
<Checkbox
|
||||
type="button"
|
||||
id={id}
|
||||
value={id}
|
||||
className="bg-white"
|
||||
checked={checked}
|
||||
onCheckedChange={() => onChange(!checked)}
|
||||
/>
|
||||
<span className="ml-2 w-[30rem] truncate">{label}</span>
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -638,6 +638,7 @@
|
||||
"no_integrations_yet": "Deine verknüpften Tabellen werden hier angezeigt, sobald Du sie hinzufügst ⏲️",
|
||||
"spreadsheet_url": "Tabellen-URL"
|
||||
},
|
||||
"include_created_at": "Erstellungsdatum einbeziehen",
|
||||
"include_hidden_fields": "Versteckte Felder (hidden fields) einbeziehen",
|
||||
"include_metadata": "Metadaten einbeziehen (Browser, Land, etc.)",
|
||||
"include_variables": "Variablen einbeziehen",
|
||||
|
||||
@@ -638,6 +638,7 @@
|
||||
"no_integrations_yet": "Your google sheet integrations will appear here as soon as you add them. ⏲️",
|
||||
"spreadsheet_url": "Spreadsheet URL"
|
||||
},
|
||||
"include_created_at": "Include Created At",
|
||||
"include_hidden_fields": "Include Hidden Fields",
|
||||
"include_metadata": "Include Metadata (Browser, Country, etc.)",
|
||||
"include_variables": "Include Variables",
|
||||
|
||||
@@ -638,6 +638,7 @@
|
||||
"no_integrations_yet": "Suas integrações do Google Sheets vão aparecer aqui assim que você adicioná-las. ⏲️",
|
||||
"spreadsheet_url": "URL da planilha"
|
||||
},
|
||||
"include_created_at": "Incluir Data de Criação",
|
||||
"include_hidden_fields": "Incluir Campos Ocultos",
|
||||
"include_metadata": "Incluir Metadados (Navegador, País, etc.)",
|
||||
"include_variables": "Incluir Variáveis",
|
||||
|
||||
@@ -67,3 +67,19 @@ export const isValidDateString = (value: string) => {
|
||||
const date = new Date(value);
|
||||
return date;
|
||||
};
|
||||
|
||||
export const getFormattedDate = (date: Date) => {
|
||||
return date.toLocaleString(undefined, {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
};
|
||||
|
||||
export const getFormattedTime = (date: Date) => {
|
||||
return date.toLocaleString(undefined, {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
hour12: false,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -11,6 +11,7 @@ export const ZIntegrationBaseSurveyData = z.object({
|
||||
includeVariables: z.boolean().optional(),
|
||||
includeHiddenFields: z.boolean().optional(),
|
||||
includeMetadata: z.boolean().optional(),
|
||||
includeCreatedAt: z.boolean().optional(),
|
||||
questions: z.string(),
|
||||
surveyId: z.string(),
|
||||
surveyName: z.string(),
|
||||
|
||||
Reference in New Issue
Block a user