fix: created at to integrations (#4343)

Co-authored-by: Piyush Gupta <piyushguptaa2z123@gmail.com>
This commit is contained in:
Dhruwang Jariwala
2024-11-22 11:49:54 +05:30
committed by GitHub
parent 9dad06222d
commit 4ca6ee358b
13 changed files with 114 additions and 70 deletions
@@ -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>
)}
@@ -128,6 +128,7 @@ export const ManageIntegration = (props: ManageIntegrationProps) => {
includeVariables: !!data.includeVariables,
includeHiddenFields: !!data.includeHiddenFields,
includeMetadata: !!data.includeMetadata,
includeCreatedAt: !!data.includeCreatedAt,
index,
});
setIsModalOpen(true);
@@ -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>
)}
@@ -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]);
@@ -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>
)}
@@ -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>
);
+1
View File
@@ -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",
+1
View File
@@ -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",
+1
View File
@@ -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",
+16
View File
@@ -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(),