Compare commits

..

1 Commits

Author SHA1 Message Date
Johannes
42b5528c1d use patched version 2025-10-06 13:18:07 +02:00
24 changed files with 2551 additions and 2695 deletions

View File

@@ -54,10 +54,6 @@ inputs:
description: "Whether this is a prerelease (auto-tags for staging/production)"
required: false
default: "false"
make_latest:
description: "Whether to tag as latest/production (from GitHub release 'Set as the latest release' option)"
required: false
default: "false"
# Build options
dockerfile:
@@ -158,7 +154,6 @@ runs:
DEPLOY_PRODUCTION: ${{ inputs.deploy_production }}
DEPLOY_STAGING: ${{ inputs.deploy_staging }}
IS_PRERELEASE: ${{ inputs.is_prerelease }}
MAKE_LATEST: ${{ inputs.make_latest }}
run: |
set -euo pipefail
@@ -169,9 +164,9 @@ runs:
if [[ "${IS_PRERELEASE}" == "true" ]]; then
TAGS="${TAGS}\n${ECR_REGISTRY}/${ECR_REPOSITORY}:staging"
echo "Adding staging tag for prerelease"
elif [[ "${IS_PRERELEASE}" == "false" && "${MAKE_LATEST}" == "true" ]]; then
elif [[ "${IS_PRERELEASE}" == "false" ]]; then
TAGS="${TAGS}\n${ECR_REGISTRY}/${ECR_REPOSITORY}:production"
echo "Adding production tag for stable release marked as latest"
echo "Adding production tag for stable release"
fi
# Handle manual deployment overrides
@@ -201,7 +196,6 @@ runs:
VERSION: ${{ steps.version.outputs.version }}
IMAGE_NAME: ${{ inputs.ghcr_image_name }}
IS_PRERELEASE: ${{ inputs.is_prerelease }}
MAKE_LATEST: ${{ inputs.make_latest }}
run: |
set -euo pipefail
@@ -220,10 +214,10 @@ runs:
echo "Added SemVer tags: ${MAJOR}.${MINOR}, ${MAJOR}"
fi
# Add latest tag for stable releases marked as latest
if [[ "${IS_PRERELEASE}" == "false" && "${MAKE_LATEST}" == "true" ]]; then
# Add latest tag for stable releases
if [[ "${IS_PRERELEASE}" == "false" ]]; then
TAGS="${TAGS}\nghcr.io/${IMAGE_NAME}:latest"
echo "Added latest tag for stable release marked as latest"
echo "Added latest tag for stable release"
fi
echo "Generated GHCR tags:"
@@ -257,7 +251,6 @@ runs:
echo "Experimental Mode: ${{ inputs.experimental_mode }}"
echo "Event Name: ${{ github.event_name }}"
echo "Is Prerelease: ${{ inputs.is_prerelease }}"
echo "Make Latest: ${{ inputs.make_latest }}"
echo "Version: ${{ steps.version.outputs.version }}"
if [[ "${{ inputs.registry_type }}" == "ecr" ]]; then

View File

@@ -32,11 +32,6 @@ on:
required: false
type: boolean
default: false
MAKE_LATEST:
description: "Whether to tag for production (from GitHub release 'Set as the latest release' option)"
required: false
type: boolean
default: false
outputs:
IMAGE_TAG:
description: "Normalized image tag used for the build"
@@ -85,7 +80,6 @@ jobs:
deploy_production: ${{ inputs.deploy_production }}
deploy_staging: ${{ inputs.deploy_staging }}
is_prerelease: ${{ inputs.IS_PRERELEASE }}
make_latest: ${{ inputs.MAKE_LATEST }}
env:
DEPOT_PROJECT_TOKEN: ${{ secrets.DEPOT_PROJECT_TOKEN }}
DUMMY_DATABASE_URL: ${{ secrets.DUMMY_DATABASE_URL }}

View File

@@ -8,75 +8,6 @@ permissions:
contents: read
jobs:
check-latest-release:
name: Check if this is the latest release
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: read
outputs:
is_latest: ${{ steps.compare_tags.outputs.is_latest }}
# This job determines if the current release was marked as "Set as the latest release"
# by comparing it with the latest release from GitHub API
steps:
- name: Harden the runner
uses: step-security/harden-runner@ec9f2d5744a09debf3a187a3f4f675c53b671911 # v2.13.0
with:
egress-policy: audit
- name: Get latest release tag from API
id: get_latest_release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
# Get the latest release tag from GitHub API with error handling
echo "Fetching latest release from GitHub API..."
# Use curl with error handling - API returns 404 if no releases exist
http_code=$(curl -s -w "%{http_code}" -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${REPO}/releases/latest" -o /tmp/latest_release.json)
if [[ "$http_code" == "404" ]]; then
echo "⚠️ No previous releases found (404). This appears to be the first release."
echo "latest_release=" >> $GITHUB_OUTPUT
elif [[ "$http_code" == "200" ]]; then
latest_release=$(jq -r .tag_name /tmp/latest_release.json)
if [[ "$latest_release" == "null" || -z "$latest_release" ]]; then
echo "⚠️ API returned null/empty tag_name. Treating as first release."
echo "latest_release=" >> $GITHUB_OUTPUT
else
echo "Latest release from API: ${latest_release}"
echo "latest_release=${latest_release}" >> $GITHUB_OUTPUT
fi
else
echo "❌ GitHub API error (HTTP ${http_code}). Treating as first release."
echo "latest_release=" >> $GITHUB_OUTPUT
fi
echo "Current release tag: ${{ github.event.release.tag_name }}"
- name: Compare release tags
id: compare_tags
env:
CURRENT_TAG: ${{ github.event.release.tag_name }}
LATEST_TAG: ${{ steps.get_latest_release.outputs.latest_release }}
run: |
set -euo pipefail
# Handle first release case (no previous releases)
if [[ -z "${LATEST_TAG}" ]]; then
echo "🎉 This is the first release (${CURRENT_TAG}) - treating as latest"
echo "is_latest=true" >> $GITHUB_OUTPUT
elif [[ "${CURRENT_TAG}" == "${LATEST_TAG}" ]]; then
echo "✅ This release (${CURRENT_TAG}) is marked as the latest release"
echo "is_latest=true" >> $GITHUB_OUTPUT
else
echo " This release (${CURRENT_TAG}) is not the latest release (latest: ${LATEST_TAG})"
echo "is_latest=false" >> $GITHUB_OUTPUT
fi
docker-build-community:
name: Build & release community docker image
permissions:
@@ -85,11 +16,8 @@ jobs:
id-token: write
uses: ./.github/workflows/release-docker-github.yml
secrets: inherit
needs:
- check-latest-release
with:
IS_PRERELEASE: ${{ github.event.release.prerelease }}
MAKE_LATEST: ${{ needs.check-latest-release.outputs.is_latest }}
docker-build-cloud:
name: Build & push Formbricks Cloud to ECR
@@ -101,9 +29,7 @@ jobs:
with:
image_tag: ${{ needs.docker-build-community.outputs.VERSION }}
IS_PRERELEASE: ${{ github.event.release.prerelease }}
MAKE_LATEST: ${{ needs.check-latest-release.outputs.is_latest }}
needs:
- check-latest-release
- docker-build-community
helm-chart-release:
@@ -148,10 +74,8 @@ jobs:
contents: write # Required for tag push operations in called workflow
uses: ./.github/workflows/move-stable-tag.yml
needs:
- check-latest-release
- docker-build-community # Ensure release is successful first
with:
release_tag: ${{ github.event.release.tag_name }}
commit_sha: ${{ github.sha }}
is_prerelease: ${{ github.event.release.prerelease }}
make_latest: ${{ needs.check-latest-release.outputs.is_latest }}

View File

@@ -16,11 +16,6 @@ on:
required: false
type: boolean
default: false
make_latest:
description: "Whether to move stable tag (from GitHub release 'Set as the latest release' option)"
required: false
type: boolean
default: false
permissions:
contents: read
@@ -37,8 +32,8 @@ jobs:
timeout-minutes: 10 # Prevent hung git operations
permissions:
contents: write # Required to push tags
# Only move stable tag for non-prerelease versions AND when make_latest is true
if: ${{ !inputs.is_prerelease && inputs.make_latest }}
# Only move stable tag for non-prerelease versions
if: ${{ !inputs.is_prerelease }}
steps:
- name: Harden the runner
uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0

View File

@@ -13,11 +13,6 @@ on:
required: false
type: boolean
default: false
MAKE_LATEST:
description: "Whether to tag as latest (from GitHub release 'Set as the latest release' option)"
required: false
type: boolean
default: false
outputs:
VERSION:
description: release version
@@ -98,7 +93,6 @@ jobs:
ghcr_image_name: ${{ env.IMAGE_NAME }}
version: ${{ steps.extract_release_tag.outputs.VERSION }}
is_prerelease: ${{ inputs.IS_PRERELEASE }}
make_latest: ${{ inputs.MAKE_LATEST }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEPOT_PROJECT_TOKEN: ${{ secrets.DEPOT_PROJECT_TOKEN }}

View File

@@ -1,18 +1,5 @@
"use client";
import { useTranslate } from "@tolgee/react";
import { PlusIcon, TrashIcon } from "lucide-react";
import Image from "next/image";
import React, { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import toast from "react-hot-toast";
import { TIntegrationInput } from "@formbricks/types/integration";
import {
TIntegrationNotion,
TIntegrationNotionConfigData,
TIntegrationNotionDatabase,
} from "@formbricks/types/integration/notion";
import { TSurvey, TSurveyQuestionTypeEnum } from "@formbricks/types/surveys/types";
import { createOrUpdateIntegrationAction } from "@/app/(app)/environments/[environmentId]/project/integrations/actions";
import {
ERRORS,
@@ -36,6 +23,19 @@ import {
} from "@/modules/ui/components/dialog";
import { DropdownSelector } from "@/modules/ui/components/dropdown-selector";
import { Label } from "@/modules/ui/components/label";
import { useTranslate } from "@tolgee/react";
import { PlusIcon, TrashIcon } from "lucide-react";
import Image from "next/image";
import React, { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import toast from "react-hot-toast";
import { TIntegrationInput } from "@formbricks/types/integration";
import {
TIntegrationNotion,
TIntegrationNotionConfigData,
TIntegrationNotionDatabase,
} from "@formbricks/types/integration/notion";
import { TSurvey, TSurveyQuestionTypeEnum } from "@formbricks/types/surveys/types";
interface AddIntegrationModalProps {
environmentId: string;
@@ -134,12 +134,13 @@ export const AddIntegrationModal = ({
type: TSurveyQuestionTypeEnum.OpenText,
})) || [];
const hiddenFields =
selectedSurvey?.hiddenFields.fieldIds?.map((fId) => ({
id: fId,
name: `${t("common.hidden_field")} : ${fId}`,
type: TSurveyQuestionTypeEnum.OpenText,
})) || [];
const hiddenFields = selectedSurvey?.hiddenFields.enabled
? selectedSurvey?.hiddenFields.fieldIds?.map((fId) => ({
id: fId,
name: `${t("common.hidden_field")} : ${fId}`,
type: TSurveyQuestionTypeEnum.OpenText,
})) || []
: [];
const Metadata = [
{
id: "metadata",

View File

@@ -1,3 +1,5 @@
import { ResponseCardModal } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseCardModal";
import { SingleResponseCard } from "@/modules/analysis/components/SingleResponseCard";
import { cleanup, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
@@ -6,8 +8,6 @@ import { TResponse } from "@formbricks/types/responses";
import { TSurvey } from "@formbricks/types/surveys/types";
import { TTag } from "@formbricks/types/tags";
import { TUser, TUserLocale } from "@formbricks/types/user";
import { ResponseCardModal } from "@/app/(app)/environments/[environmentId]/surveys/[surveyId]/(analysis)/responses/components/ResponseCardModal";
import { SingleResponseCard } from "@/modules/analysis/components/SingleResponseCard";
vi.mock("@/modules/analysis/components/SingleResponseCard", () => ({
SingleResponseCard: vi.fn(() => <div data-testid="single-response-card">SingleResponseCard</div>),
@@ -46,11 +46,6 @@ vi.mock("@/modules/ui/components/dialog", () => ({
)),
DialogBody: vi.fn(({ children }) => <div data-testid="dialog-body">{children}</div>),
DialogFooter: vi.fn(({ children }) => <div data-testid="dialog-footer">{children}</div>),
DialogTitle: vi.fn(({ children }) => <div data-testid="dialog-title">{children}</div>),
}));
vi.mock("@radix-ui/react-visually-hidden", () => ({
VisuallyHidden: vi.fn(({ children }) => <div data-testid="visually-hidden">{children}</div>),
}));
const mockResponses = [

View File

@@ -1,4 +1,6 @@
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
import { SingleResponseCard } from "@/modules/analysis/components/SingleResponseCard";
import { Button } from "@/modules/ui/components/button";
import { Dialog, DialogBody, DialogContent, DialogFooter } from "@/modules/ui/components/dialog";
import { ChevronLeft, ChevronRight } from "lucide-react";
import { useEffect, useState } from "react";
import { TEnvironment } from "@formbricks/types/environment";
@@ -6,9 +8,6 @@ import { TResponse } from "@formbricks/types/responses";
import { TSurvey } from "@formbricks/types/surveys/types";
import { TTag } from "@formbricks/types/tags";
import { TUser, TUserLocale } from "@formbricks/types/user";
import { SingleResponseCard } from "@/modules/analysis/components/SingleResponseCard";
import { Button } from "@/modules/ui/components/button";
import { Dialog, DialogBody, DialogContent, DialogFooter, DialogTitle } from "@/modules/ui/components/dialog";
interface ResponseCardModalProps {
responses: TResponse[];
@@ -78,9 +77,6 @@ export const ResponseCardModal = ({
return (
<Dialog open={open} onOpenChange={handleClose}>
<DialogContent width="wide">
<VisuallyHidden asChild>
<DialogTitle>Survey Response Details</DialogTitle>
</VisuallyHidden>
<DialogBody>
<SingleResponseCard
survey={survey}

View File

@@ -1204,7 +1204,7 @@
"add_ending": "Abschluss hinzufügen",
"add_ending_below": "Abschluss unten hinzufügen",
"add_fallback": "Hinzufügen",
"add_fallback_placeholder": "Platzhalter hinzufügen, falls kein Wert zur Verfügung steht.",
"add_fallback_placeholder": "Hinzufügen eines Platzhalters, der angezeigt wird, wenn die Frage übersprungen wird:",
"add_hidden_field_id": "Verstecktes Feld ID hinzufügen",
"add_highlight_border": "Rahmen hinzufügen",
"add_highlight_border_description": "Füge deiner Umfragekarte einen äußeren Rahmen hinzu.",

View File

@@ -1204,7 +1204,7 @@
"add_ending": "Add ending",
"add_ending_below": "Add ending below",
"add_fallback": "Add",
"add_fallback_placeholder": "Add a placeholder to show if there is no value to recall.",
"add_fallback_placeholder": "Add a placeholder to show if the question gets skipped:",
"add_hidden_field_id": "Add hidden field ID",
"add_highlight_border": "Add highlight border",
"add_highlight_border_description": "Add an outer border to your survey card.",

View File

@@ -1204,7 +1204,7 @@
"add_ending": "Ajouter une fin",
"add_ending_below": "Ajouter une fin ci-dessous",
"add_fallback": "Ajouter",
"add_fallback_placeholder": "Ajouter un espace réservé à afficher s'il n'y a pas de valeur à rappeler.",
"add_fallback_placeholder": "Ajouter un espace réservé pour montrer si la question est ignorée :",
"add_hidden_field_id": "Ajouter un champ caché ID",
"add_highlight_border": "Ajouter une bordure de surlignage",
"add_highlight_border_description": "Ajoutez une bordure extérieure à votre carte d'enquête.",

View File

@@ -1204,7 +1204,7 @@
"add_ending": "Adicionar encerramento",
"add_ending_below": "Adicionar encerramento abaixo",
"add_fallback": "Adicionar",
"add_fallback_placeholder": "Adicionar um espaço reservado para mostrar se não houver valor para recordar.",
"add_fallback_placeholder": "Adicionar um espaço reservado para mostrar se a pergunta for ignorada:",
"add_hidden_field_id": "Adicionar ID do campo oculto",
"add_highlight_border": "Adicionar borda de destaque",
"add_highlight_border_description": "Adicione uma borda externa ao seu cartão de inquérito.",

View File

@@ -1204,7 +1204,7 @@
"add_ending": "Adaugă finalizare",
"add_ending_below": "Adaugă finalizare mai jos",
"add_fallback": "Adaugă",
"add_fallback_placeholder": "Adaugă un placeholder pentru a afișa dacă nu există valoare de reamintit",
"add_fallback_placeholder": "Adaugă un substituent pentru a afișa dacă întrebarea este omisă:",
"add_hidden_field_id": "Adăugați ID câmp ascuns",
"add_highlight_border": "Adaugă bordură evidențiată",
"add_highlight_border_description": "Adaugă o margine exterioară cardului tău de sondaj.",

View File

@@ -1204,7 +1204,7 @@
"add_ending": "添加结尾",
"add_ending_below": "在下方 添加 结尾",
"add_fallback": "添加",
"add_fallback_placeholder": "添加 占位符 显示 如果 没有 值以 回忆",
"add_fallback_placeholder": "添加 一个 占位符,以显示该问题是否被跳过:",
"add_hidden_field_id": "添加 隐藏 字段 ID",
"add_highlight_border": "添加 高亮 边框",
"add_highlight_border_description": "在 你的 调查 卡片 添加 外 边框。",

View File

@@ -1204,7 +1204,7 @@
"add_ending": "新增結尾",
"add_ending_below": "在下方新增結尾",
"add_fallback": "新增",
"add_fallback_placeholder": "新增 預設 以顯示是否沒 有 值 可 回憶 。",
"add_fallback_placeholder": "新增用于顯示問題被跳過時的佔位符",
"add_hidden_field_id": "新增隱藏欄位 ID",
"add_highlight_border": "新增醒目提示邊框",
"add_highlight_border_description": "在您的問卷卡片新增外邊框。",

View File

@@ -1,12 +1,12 @@
"use client";
import { getLocalizedValue } from "@/lib/i18n/utils";
import { parseRecallInfo } from "@/lib/utils/recall";
import { ResponseCardQuotas } from "@/modules/ee/quotas/components/single-response-card-quotas";
import { useTranslate } from "@tolgee/react";
import { CheckCircle2Icon } from "lucide-react";
import { TResponseWithQuotas } from "@formbricks/types/responses";
import { TSurvey } from "@formbricks/types/surveys/types";
import { getLocalizedValue } from "@/lib/i18n/utils";
import { parseRecallInfo } from "@/lib/utils/recall";
import { ResponseCardQuotas } from "@/modules/ee/quotas/components/single-response-card-quotas";
import { isValidValue } from "../util";
import { HiddenFields } from "./HiddenFields";
import { QuestionSkip } from "./QuestionSkip";
@@ -118,7 +118,7 @@ export const SingleResponseCardBody = ({
{survey.variables.length > 0 && (
<ResponseVariables variables={survey.variables} variablesData={response.variables} />
)}
{survey.hiddenFields.fieldIds && (
{survey.hiddenFields.enabled && survey.hiddenFields.fieldIds && (
<HiddenFields hiddenFields={survey.hiddenFields} responseData={response.data} />
)}

View File

@@ -1,5 +1,13 @@
"use client";
import { cn } from "@/lib/cn";
import { extractRecallInfo } from "@/lib/utils/recall";
import { findHiddenFieldUsedInLogic, isUsedInQuota } from "@/modules/survey/editor/lib/utils";
import { Button } from "@/modules/ui/components/button";
import { Input } from "@/modules/ui/components/input";
import { Label } from "@/modules/ui/components/label";
import { Switch } from "@/modules/ui/components/switch";
import { Tag } from "@/modules/ui/components/tag";
import { useAutoAnimate } from "@formkit/auto-animate/react";
import * as Collapsible from "@radix-ui/react-collapsible";
import { useTranslate } from "@tolgee/react";
@@ -9,13 +17,6 @@ import { toast } from "react-hot-toast";
import { TSurveyQuota } from "@formbricks/types/quota";
import { TSurvey, TSurveyHiddenFields, TSurveyQuestionId } from "@formbricks/types/surveys/types";
import { validateId } from "@formbricks/types/surveys/validation";
import { cn } from "@/lib/cn";
import { extractRecallInfo } from "@/lib/utils/recall";
import { findHiddenFieldUsedInLogic, isUsedInQuota } from "@/modules/survey/editor/lib/utils";
import { Button } from "@/modules/ui/components/button";
import { Input } from "@/modules/ui/components/input";
import { Label } from "@/modules/ui/components/label";
import { Tag } from "@/modules/ui/components/tag";
interface HiddenFieldsCardProps {
localSurvey: TSurvey;
@@ -144,6 +145,21 @@ export const HiddenFieldsCard = ({
<p className="text-sm font-semibold">{t("common.hidden_fields")}</p>
</div>
</div>
<div className="flex items-center space-x-2">
<Label htmlFor="hidden-fields-toggle">
{localSurvey?.hiddenFields?.enabled ? t("common.on") : t("common.off")}
</Label>
<Switch
id="hidden-fields-toggle"
checked={localSurvey?.hiddenFields?.enabled}
onClick={(e) => {
e.stopPropagation();
updateSurvey({ enabled: !localSurvey.hiddenFields?.enabled });
}}
/>
</div>
</div>
</Collapsible.CollapsibleTrigger>
<Collapsible.CollapsibleContent className={`flex flex-col px-4 ${open && "pb-6"}`} ref={parent}>
@@ -202,7 +218,7 @@ export const HiddenFieldsCard = ({
onChange={(e) => setHiddenField(e.target.value.trim())}
placeholder={t("environments.surveys.edit.type_field_id") + "..."}
/>
<Button variant="secondary" type="submit" className="h-10 whitespace-nowrap">
<Button variant="secondary" type="submit" size="sm" className="whitespace-nowrap">
{t("environments.surveys.edit.add_hidden_field_id")}
</Button>
</div>

View File

@@ -1,24 +1,5 @@
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { createId } from "@paralleldrive/cuid2";
import { useTranslate } from "@tolgee/react";
import DOMpurify from "isomorphic-dompurify";
import {
ArrowDownIcon,
EyeOffIcon,
HandshakeIcon,
MailIcon,
TriangleAlertIcon,
UserIcon,
ZapIcon,
} from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import toast from "react-hot-toast";
import { TSurveyFollowUpAction, TSurveyFollowUpTrigger } from "@formbricks/database/types/survey-follow-up";
import { TSurvey, TSurveyQuestionTypeEnum } from "@formbricks/types/surveys/types";
import { TUserLocale } from "@formbricks/types/user";
import { getLocalizedValue } from "@/lib/i18n/utils";
import { recallToHeadline } from "@/lib/utils/recall";
import { getSurveyFollowUpActionDefaultBody } from "@/modules/survey/editor/lib/utils";
@@ -60,6 +41,25 @@ import {
SelectValue,
} from "@/modules/ui/components/select";
import { cn } from "@/modules/ui/lib/utils";
import { zodResolver } from "@hookform/resolvers/zod";
import { createId } from "@paralleldrive/cuid2";
import { useTranslate } from "@tolgee/react";
import DOMpurify from "isomorphic-dompurify";
import {
ArrowDownIcon,
EyeOffIcon,
HandshakeIcon,
MailIcon,
TriangleAlertIcon,
UserIcon,
ZapIcon,
} from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useForm } from "react-hook-form";
import toast from "react-hot-toast";
import { TSurveyFollowUpAction, TSurveyFollowUpTrigger } from "@formbricks/database/types/survey-follow-up";
import { TSurvey, TSurveyQuestionTypeEnum } from "@formbricks/types/surveys/types";
import { TUserLocale } from "@formbricks/types/user";
interface AddFollowUpModalProps {
localSurvey: TSurvey;
@@ -118,9 +118,10 @@ export const FollowUpModal = ({
return false;
});
const hiddenFields = localSurvey.hiddenFields.fieldIds
? { fieldIds: localSurvey.hiddenFields.fieldIds }
: { fieldIds: [] };
const hiddenFields =
localSurvey.hiddenFields.enabled && localSurvey.hiddenFields.fieldIds
? { fieldIds: localSurvey.hiddenFields.fieldIds }
: { fieldIds: [] };
const updatedTeamMemberDetails = teamMemberDetails.map((teamMemberDetail) => {
if (teamMemberDetail.email === userEmail) {

View File

@@ -28,12 +28,6 @@ const nextConfig = {
experimental: {},
transpilePackages: ["@formbricks/database"],
images: {
// Optimize image processing to reduce CPU time and prevent timeouts
deviceSizes: [640, 750, 828, 1080, 1200, 1920], // Removed 3840 to avoid processing huge images
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384], // Standard sizes for smaller images
formats: ["image/webp"], // WebP is faster to process and smaller than JPEG/PNG
minimumCacheTTL: 60, // Cache optimized images for at least 60 seconds
dangerouslyAllowSVG: true, // Allow SVG images
remotePatterns: [
{
protocol: "https",

View File

@@ -106,7 +106,7 @@
"next-auth": "4.24.11",
"next-safe-action": "7.10.8",
"node-fetch": "3.3.2",
"nodemailer": "7.0.9",
"nodemailer": "7.0.2",
"otplib": "12.0.1",
"papaparse": "5.5.2",
"posthog-js": "1.240.0",
@@ -148,7 +148,7 @@
"@types/lodash": "4.17.16",
"@types/markdown-it": "14.1.2",
"@types/mime-types": "2.1.4",
"@types/nodemailer": "7.0.2",
"@types/nodemailer": "6.4.17",
"@types/papaparse": "5.3.15",
"@types/qrcode": "1.5.5",
"@types/testing-library__react": "10.2.0",

View File

@@ -145,7 +145,7 @@ install_formbricks() {
acme:
email: $email_address
storage: acme.json
caServer: "https://acme-v02.api.letsencrypt.org/directory"
caServer: "https://acme-v01.api.letsencrypt.org/directory"
tlsChallenge: {}"
else
certResolver=""
@@ -157,14 +157,8 @@ entryPoints:
web:
address: ":80"
$http_redirection
transport:
respondingTimeouts:
readTimeout: 60s
websecure:
address: ":443"
transport:
respondingTimeouts:
readTimeout: 60s
http:
tls:
$certResolver
@@ -496,7 +490,7 @@ EOF
if [[ $insert_traefik == "y" ]]; then
cat >> "$services_snippet_file" << EOF
traefik:
image: "traefik:v2.11.29"
image: "traefik:v2.7"
restart: always
container_name: "traefik"
depends_on:
@@ -525,7 +519,7 @@ EOF
cat > "$services_snippet_file" << EOF
traefik:
image: "traefik:v2.11.29"
image: "traefik:v2.7"
restart: always
container_name: "traefik"
depends_on:

View File

@@ -78,11 +78,7 @@
"next-auth@4.24.11": "patches/next-auth@4.24.11.patch"
},
"overrides": {
"axios": ">=1.12.2",
"tar-fs": "2.1.4"
},
"comments": {
"overrides": "Security fixes for transitive dependencies. Remove when upstream packages update: axios (CVE-2025-58754) - awaiting @boxyhq/saml-jackson update | tar-fs (Dependabot #205) - awaiting upstream dependency updates"
}
}
}

View File

@@ -1373,7 +1373,7 @@ export const ZSurvey = z
return false;
})
.map((q) => q.id),
...(survey.hiddenFields.fieldIds ?? []),
...(survey.hiddenFields.enabled ? (survey.hiddenFields.fieldIds ?? []) : []),
];
if (validOptions.findIndex((option) => option === followUp.action.properties.to) === -1) {

4947
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff