diff --git a/apps/web/modules/ee/contacts/segments/components/edit-segment-modal.tsx b/apps/web/modules/ee/contacts/segments/components/edit-segment-modal.tsx
index 472cca0d4b..3eff432ad6 100644
--- a/apps/web/modules/ee/contacts/segments/components/edit-segment-modal.tsx
+++ b/apps/web/modules/ee/contacts/segments/components/edit-segment-modal.tsx
@@ -4,7 +4,7 @@ import { UsersIcon } from "lucide-react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
-import { TSegment, TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TSegment, TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { SegmentSettings } from "@/modules/ee/contacts/segments/components/segment-settings";
import {
Dialog,
@@ -15,23 +15,63 @@ import {
DialogTitle,
} from "@/modules/ui/components/dialog";
import { SegmentActivityTab } from "./segment-activity-tab";
+import { TSegmentActivitySummary } from "./segment-activity-utils";
interface EditSegmentModalProps {
environmentId: string;
open: boolean;
setOpen: (open: boolean) => void;
- currentSegment: TSegmentWithSurveyNames;
+ currentSegment: TSegmentWithSurveyRefs;
+ activitySummary: TSegmentActivitySummary;
segments: TSegment[];
contactAttributeKeys: TContactAttributeKey[];
isContactsEnabled: boolean;
isReadOnly: boolean;
}
+const SegmentSettingsTab = ({
+ activitySummary,
+ contactAttributeKeys,
+ currentSegment,
+ environmentId,
+ isContactsEnabled,
+ isReadOnly,
+ segments,
+ setOpen,
+}: Pick<
+ EditSegmentModalProps,
+ | "activitySummary"
+ | "contactAttributeKeys"
+ | "currentSegment"
+ | "environmentId"
+ | "isContactsEnabled"
+ | "isReadOnly"
+ | "segments"
+ | "setOpen"
+>) => {
+ if (!isContactsEnabled) {
+ return null;
+ }
+
+ return (
+
+ );
+};
+
export const EditSegmentModal = ({
environmentId,
open,
setOpen,
currentSegment,
+ activitySummary,
contactAttributeKeys,
segments,
isContactsEnabled,
@@ -40,31 +80,25 @@ export const EditSegmentModal = ({
const { t } = useTranslation();
const [activeTab, setActiveTab] = useState(0);
- const SettingsTab = () => {
- if (isContactsEnabled) {
- return (
-
- );
- }
-
- return null;
- };
-
const tabs = [
{
title: t("common.activity"),
- children: ,
+ children: ,
},
{
title: t("common.settings"),
- children: ,
+ children: (
+
+ ),
},
];
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-activity-tab.tsx b/apps/web/modules/ee/contacts/segments/components/segment-activity-tab.tsx
index b0f37a9e4a..9fe3bc42c0 100644
--- a/apps/web/modules/ee/contacts/segments/components/segment-activity-tab.tsx
+++ b/apps/web/modules/ee/contacts/segments/components/segment-activity-tab.tsx
@@ -1,19 +1,20 @@
"use client";
import { useTranslation } from "react-i18next";
-import { TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { convertDateTimeStringShort } from "@/lib/time";
import { IdBadge } from "@/modules/ui/components/id-badge";
import { Label } from "@/modules/ui/components/label";
+import { TSegmentActivitySummary } from "./segment-activity-utils";
interface SegmentActivityTabProps {
- currentSegment: TSegmentWithSurveyNames;
+ currentSegment: TSegmentWithSurveyRefs;
+ activitySummary: TSegmentActivitySummary;
}
-export const SegmentActivityTab = ({ currentSegment }: SegmentActivityTabProps) => {
+export const SegmentActivityTab = ({ currentSegment, activitySummary }: SegmentActivityTabProps) => {
const { t } = useTranslation();
-
- const { activeSurveys, inactiveSurveys } = currentSegment;
+ const { activeSurveys, inactiveSurveys } = activitySummary;
return (
@@ -22,20 +23,20 @@ export const SegmentActivityTab = ({ currentSegment }: SegmentActivityTabProps)
{!activeSurveys?.length &&
-
}
- {activeSurveys?.map((survey, index) => (
-
- {survey}
-
+ {activeSurveys?.map((surveyName) => (
+
))}
{!inactiveSurveys?.length &&
-
}
- {inactiveSurveys?.map((survey, index) => (
-
- {survey}
-
+ {inactiveSurveys?.map((surveyName) => (
+
))}
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-activity-utils.ts b/apps/web/modules/ee/contacts/segments/components/segment-activity-utils.ts
new file mode 100644
index 0000000000..9dc10d8356
--- /dev/null
+++ b/apps/web/modules/ee/contacts/segments/components/segment-activity-utils.ts
@@ -0,0 +1,99 @@
+import { TBaseFilters, TSegmentWithSurveyRefs } from "@formbricks/types/segment";
+import { TSurvey } from "@formbricks/types/surveys/types";
+
+type TSurveySummary = Pick;
+type TReferencingSegmentSurveyGroup = {
+ segmentId: string;
+ segmentTitle: string;
+ surveys: TSurveySummary[];
+};
+
+export type TSegmentActivitySummary = {
+ activeSurveys: string[];
+ inactiveSurveys: string[];
+};
+
+export const doesSegmentReferenceSegment = (filters: TBaseFilters, targetSegmentId: string): boolean => {
+ for (const filter of filters) {
+ const { resource } = filter;
+
+ if (Array.isArray(resource)) {
+ if (doesSegmentReferenceSegment(resource, targetSegmentId)) {
+ return true;
+ }
+ continue;
+ }
+
+ if (resource.root.type === "segment" && resource.root.segmentId === targetSegmentId) {
+ return true;
+ }
+ }
+
+ return false;
+};
+
+export const getReferencingSegments = (
+ segments: TSegmentWithSurveyRefs[],
+ targetSegmentId: string
+): TSegmentWithSurveyRefs[] =>
+ segments.filter(
+ (segment) =>
+ segment.id !== targetSegmentId && doesSegmentReferenceSegment(segment.filters, targetSegmentId)
+ );
+
+export const buildSegmentActivitySummary = (
+ directSurveys: TSurveySummary[],
+ indirectSurveyGroups: TReferencingSegmentSurveyGroup[]
+): TSegmentActivitySummary => {
+ const surveyMap = new Map();
+
+ for (const survey of directSurveys) {
+ surveyMap.set(survey.id, survey);
+ }
+
+ for (const segment of indirectSurveyGroups) {
+ for (const survey of segment.surveys) {
+ if (!surveyMap.has(survey.id)) {
+ surveyMap.set(survey.id, survey);
+ }
+ }
+ }
+
+ const surveys = Array.from(surveyMap.values());
+
+ return {
+ activeSurveys: surveys.filter((survey) => survey.status === "inProgress").map((survey) => survey.name),
+ inactiveSurveys: surveys
+ .filter((survey) => survey.status === "draft" || survey.status === "paused")
+ .map((survey) => survey.name),
+ };
+};
+
+export const buildSegmentActivitySummaryFromSegments = (
+ currentSegment: TSegmentWithSurveyRefs,
+ segments: TSegmentWithSurveyRefs[]
+): TSegmentActivitySummary => {
+ const activeSurveyMap = new Map(currentSegment.activeSurveys.map((s) => [s.id, s.name]));
+ const inactiveSurveyMap = new Map(currentSegment.inactiveSurveys.map((s) => [s.id, s.name]));
+ const allDirectIds = new Set([...activeSurveyMap.keys(), ...inactiveSurveyMap.keys()]);
+
+ const referencingSegments = getReferencingSegments(segments, currentSegment.id);
+ for (const segment of referencingSegments) {
+ for (const survey of segment.activeSurveys) {
+ if (!allDirectIds.has(survey.id) && !activeSurveyMap.has(survey.id)) {
+ activeSurveyMap.set(survey.id, survey.name);
+ }
+ }
+
+ for (const survey of segment.inactiveSurveys) {
+ if (!allDirectIds.has(survey.id) && !inactiveSurveyMap.has(survey.id)) {
+ inactiveSurveyMap.set(survey.id, survey.name);
+ }
+ }
+ }
+
+ return {
+ activeSurveys: Array.from(activeSurveyMap.values()),
+ inactiveSurveys: Array.from(inactiveSurveyMap.values()),
+ };
+};
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-settings.tsx b/apps/web/modules/ee/contacts/segments/components/segment-settings.tsx
index 664e2c0fb9..cf55daa0e4 100644
--- a/apps/web/modules/ee/contacts/segments/components/segment-settings.tsx
+++ b/apps/web/modules/ee/contacts/segments/components/segment-settings.tsx
@@ -6,7 +6,7 @@ import { type Dispatch, type SetStateAction, useMemo, useState } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
-import type { TBaseFilter, TSegment, TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import type { TBaseFilter, TSegment, TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { ZSegmentFilters } from "@formbricks/types/segment";
import { cn } from "@/lib/cn";
import { structuredClone } from "@/lib/pollyfills/structuredClone";
@@ -16,18 +16,21 @@ import { Button } from "@/modules/ui/components/button";
import { ConfirmDeleteSegmentModal } from "@/modules/ui/components/confirm-delete-segment-modal";
import { Input } from "@/modules/ui/components/input";
import { AddFilterModal } from "./add-filter-modal";
+import { TSegmentActivitySummary } from "./segment-activity-utils";
import { SegmentEditor } from "./segment-editor";
interface TSegmentSettingsTabProps {
+ activitySummary: TSegmentActivitySummary;
environmentId: string;
setOpen: (open: boolean) => void;
- initialSegment: TSegmentWithSurveyNames;
+ initialSegment: TSegmentWithSurveyRefs;
segments: TSegment[];
contactAttributeKeys: TContactAttributeKey[];
isReadOnly: boolean;
}
export function SegmentSettings({
+ activitySummary,
environmentId,
initialSegment,
setOpen,
@@ -38,7 +41,7 @@ export function SegmentSettings({
const router = useRouter();
const { t } = useTranslation();
const [addFilterModalOpen, setAddFilterModalOpen] = useState(false);
- const [segment, setSegment] = useState(initialSegment);
+ const [segment, setSegment] = useState(initialSegment);
const [isUpdatingSegment, setIsUpdatingSegment] = useState(false);
const [isDeletingSegment, setIsDeletingSegment] = useState(false);
@@ -257,9 +260,9 @@ export function SegmentSettings({
{isDeleteSegmentModalOpen ? (
) : null}
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-table-columns.tsx b/apps/web/modules/ee/contacts/segments/components/segment-table-columns.tsx
index 685d6f48c7..895b06458e 100644
--- a/apps/web/modules/ee/contacts/segments/components/segment-table-columns.tsx
+++ b/apps/web/modules/ee/contacts/segments/components/segment-table-columns.tsx
@@ -4,10 +4,10 @@ import { ColumnDef } from "@tanstack/react-table";
import { format, formatDistanceToNow } from "date-fns";
import { TFunction } from "i18next";
import { UsersIcon } from "lucide-react";
-import { TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TSegmentWithSurveyRefs } from "@formbricks/types/segment";
-export const generateSegmentTableColumns = (t: TFunction): ColumnDef[] => {
- const titleColumn: ColumnDef = {
+export const generateSegmentTableColumns = (t: TFunction): ColumnDef[] => {
+ const titleColumn: ColumnDef = {
id: "title",
accessorKey: "title",
header: t("common.title"),
@@ -28,7 +28,7 @@ export const generateSegmentTableColumns = (t: TFunction): ColumnDef = {
+ const updatedAtColumn: ColumnDef = {
id: "updatedAt",
accessorKey: "updatedAt",
header: t("common.updated_at"),
@@ -41,7 +41,7 @@ export const generateSegmentTableColumns = (t: TFunction): ColumnDef = {
+ const createdAtColumn: ColumnDef = {
id: "createdAt",
accessorKey: "createdAt",
header: t("common.created_at"),
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-table-data-row-container.tsx b/apps/web/modules/ee/contacts/segments/components/segment-table-data-row-container.tsx
deleted file mode 100644
index 8e33b7089e..0000000000
--- a/apps/web/modules/ee/contacts/segments/components/segment-table-data-row-container.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
-import { TSegment } from "@formbricks/types/segment";
-import { getSurveysBySegmentId } from "@/lib/survey/service";
-import { SegmentTableDataRow } from "./segment-table-data-row";
-
-type TSegmentTableDataRowProps = {
- currentSegment: TSegment;
- segments: TSegment[];
- contactAttributeKeys: TContactAttributeKey[];
- isContactsEnabled: boolean;
- isReadOnly: boolean;
-};
-
-export const SegmentTableDataRowContainer = async ({
- currentSegment,
- segments,
- contactAttributeKeys,
- isContactsEnabled,
- isReadOnly,
-}: TSegmentTableDataRowProps) => {
- const surveys = await getSurveysBySegmentId(currentSegment.id);
-
- const activeSurveys = surveys?.length
- ? surveys.filter((survey) => survey.status === "inProgress").map((survey) => survey.name)
- : [];
-
- const inactiveSurveys = surveys?.length
- ? surveys.filter((survey) => ["draft", "paused"].includes(survey.status)).map((survey) => survey.name)
- : [];
-
- const filteredSegments = segments.filter((segment) => segment.id !== currentSegment.id);
-
- return (
-
- );
-};
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-table-data-row.tsx b/apps/web/modules/ee/contacts/segments/components/segment-table-data-row.tsx
index 45943498aa..bd624a45d2 100644
--- a/apps/web/modules/ee/contacts/segments/components/segment-table-data-row.tsx
+++ b/apps/web/modules/ee/contacts/segments/components/segment-table-data-row.tsx
@@ -4,11 +4,13 @@ import { format, formatDistanceToNow } from "date-fns";
import { UsersIcon } from "lucide-react";
import { useState } from "react";
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
-import { TSegment, TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TSegment, TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { EditSegmentModal } from "./edit-segment-modal";
+import { TSegmentActivitySummary } from "./segment-activity-utils";
type TSegmentTableDataRowProps = {
- currentSegment: TSegmentWithSurveyNames;
+ currentSegment: TSegmentWithSurveyRefs;
+ activitySummary: TSegmentActivitySummary;
segments: TSegment[];
contactAttributeKeys: TContactAttributeKey[];
isContactsEnabled: boolean;
@@ -17,6 +19,7 @@ type TSegmentTableDataRowProps = {
export const SegmentTableDataRow = ({
currentSegment,
+ activitySummary,
contactAttributeKeys,
segments,
isContactsEnabled,
@@ -62,6 +65,7 @@ export const SegmentTableDataRow = ({
open={isEditSegmentModalOpen}
setOpen={setIsEditSegmentModalOpen}
currentSegment={currentSegment}
+ activitySummary={activitySummary}
contactAttributeKeys={contactAttributeKeys}
segments={segments}
isContactsEnabled={isContactsEnabled}
diff --git a/apps/web/modules/ee/contacts/segments/components/segment-table.tsx b/apps/web/modules/ee/contacts/segments/components/segment-table.tsx
index 16b2fed651..2d862c9536 100644
--- a/apps/web/modules/ee/contacts/segments/components/segment-table.tsx
+++ b/apps/web/modules/ee/contacts/segments/components/segment-table.tsx
@@ -4,13 +4,15 @@ import { Header, getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { TContactAttributeKey } from "@formbricks/types/contact-attribute-key";
-import { TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/modules/ui/components/table";
import { EditSegmentModal } from "./edit-segment-modal";
+import { buildSegmentActivitySummaryFromSegments } from "./segment-activity-utils";
import { generateSegmentTableColumns } from "./segment-table-columns";
interface SegmentTableUpdatedProps {
- segments: TSegmentWithSurveyNames[];
+ segments: TSegmentWithSurveyRefs[];
+ allSegments: TSegmentWithSurveyRefs[];
contactAttributeKeys: TContactAttributeKey[];
isContactsEnabled: boolean;
isReadOnly: boolean;
@@ -18,16 +20,17 @@ interface SegmentTableUpdatedProps {
export function SegmentTable({
segments,
+ allSegments,
contactAttributeKeys,
isContactsEnabled,
isReadOnly,
-}: SegmentTableUpdatedProps) {
+}: Readonly) {
const { t } = useTranslation();
- const [editingSegment, setEditingSegment] = useState(null);
+ const [editingSegment, setEditingSegment] = useState(null);
const columns = useMemo(() => {
return generateSegmentTableColumns(t);
- }, []);
+ }, [t]);
const table = useReactTable({
data: segments,
@@ -35,7 +38,7 @@ export function SegmentTable({
getCoreRowModel: getCoreRowModel(),
});
- const getHeader = (header: Header) => {
+ const getHeader = (header: Header) => {
if (header.isPlaceholder) {
return null;
}
@@ -136,6 +139,7 @@ export function SegmentTable({
open={!!editingSegment}
setOpen={(open) => !open && setEditingSegment(null)}
currentSegment={editingSegment}
+ activitySummary={buildSegmentActivitySummaryFromSegments(editingSegment, allSegments)}
contactAttributeKeys={contactAttributeKeys}
segments={segments}
isContactsEnabled={isContactsEnabled}
diff --git a/apps/web/modules/ee/contacts/segments/lib/filter/prisma-query.test.ts b/apps/web/modules/ee/contacts/segments/lib/filter/prisma-query.test.ts
index 6c0140f7df..0b0762d729 100644
--- a/apps/web/modules/ee/contacts/segments/lib/filter/prisma-query.test.ts
+++ b/apps/web/modules/ee/contacts/segments/lib/filter/prisma-query.test.ts
@@ -1,6 +1,6 @@
import { Prisma } from "@prisma/client";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
-import { TBaseFilters, TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TBaseFilters, TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { getSegment } from "../segments";
import { segmentFilterToPrismaQuery } from "./prisma-query";
@@ -270,7 +270,7 @@ describe("segmentFilterToPrismaQuery", () => {
];
// Mock the getSegment function to return a segment with filters
- const mockSegment: TSegmentWithSurveyNames = {
+ const mockSegment: TSegmentWithSurveyRefs = {
id: nestedSegmentId,
filters: nestedFilters,
environmentId: mockEnvironmentId,
@@ -336,7 +336,7 @@ describe("segmentFilterToPrismaQuery", () => {
// Mock getSegment to return null for the non-existent segment
vi.mocked(getSegment).mockResolvedValueOnce(mockSegment);
- vi.mocked(getSegment).mockResolvedValueOnce(null as unknown as TSegmentWithSurveyNames);
+ vi.mocked(getSegment).mockResolvedValueOnce(null as unknown as TSegmentWithSurveyRefs);
const result = await segmentFilterToPrismaQuery(mockSegmentId, filters, mockEnvironmentId);
@@ -426,7 +426,7 @@ describe("segmentFilterToPrismaQuery", () => {
];
// Mock the getSegment function to return a segment with filters
- const mockSegment: TSegmentWithSurveyNames = {
+ const mockSegment: TSegmentWithSurveyRefs = {
id: nestedSegmentId,
filters: nestedFilters,
environmentId: mockEnvironmentId,
@@ -490,7 +490,7 @@ describe("segmentFilterToPrismaQuery", () => {
test("handle circular references in segment filters", async () => {
// Mock getSegment to simulate a circular reference
- const circularSegment: TSegmentWithSurveyNames = {
+ const circularSegment: TSegmentWithSurveyRefs = {
id: mockSegmentId, // Same ID creates the circular reference
filters: [
{
@@ -550,7 +550,7 @@ describe("segmentFilterToPrismaQuery", () => {
test("handle missing segments in segment filters", async () => {
const nestedSegmentId = "segment-missing-123";
- vi.mocked(getSegment).mockResolvedValue(null as unknown as TSegmentWithSurveyNames);
+ vi.mocked(getSegment).mockResolvedValue(null as unknown as TSegmentWithSurveyRefs);
const filters: TBaseFilters = [
{
@@ -599,7 +599,7 @@ describe("segmentFilterToPrismaQuery", () => {
];
// Mock the nested segment
- const mockNestedSegment: TSegmentWithSurveyNames = {
+ const mockNestedSegment: TSegmentWithSurveyRefs = {
id: nestedSegmentId,
filters: nestedFilters,
environmentId: mockEnvironmentId,
@@ -890,7 +890,7 @@ describe("segmentFilterToPrismaQuery", () => {
];
// Set up the mocks
- const mockCircularSegment: TSegmentWithSurveyNames = {
+ const mockCircularSegment: TSegmentWithSurveyRefs = {
id: circularSegmentId,
filters: circularFilters,
environmentId: mockEnvironmentId,
@@ -904,7 +904,7 @@ describe("segmentFilterToPrismaQuery", () => {
inactiveSurveys: [],
};
- const mockSecondSegment: TSegmentWithSurveyNames = {
+ const mockSecondSegment: TSegmentWithSurveyRefs = {
id: secondSegmentId,
filters: secondFilters,
environmentId: mockEnvironmentId,
@@ -922,7 +922,7 @@ describe("segmentFilterToPrismaQuery", () => {
vi.mocked(getSegment)
.mockResolvedValueOnce(mockCircularSegment) // First call for circularSegmentId
.mockResolvedValueOnce(mockSecondSegment) // Third call for secondSegmentId
- .mockResolvedValueOnce(null as unknown as TSegmentWithSurveyNames); // Fourth call for non-existent-segment
+ .mockResolvedValueOnce(null as unknown as TSegmentWithSurveyRefs); // Fourth call for non-existent-segment
// Complex filters with mixed error conditions
const filters: TBaseFilters = [
diff --git a/apps/web/modules/ee/contacts/segments/lib/helper.test.ts b/apps/web/modules/ee/contacts/segments/lib/helper.test.ts
index 03c149803b..481b8a4f63 100644
--- a/apps/web/modules/ee/contacts/segments/lib/helper.test.ts
+++ b/apps/web/modules/ee/contacts/segments/lib/helper.test.ts
@@ -1,6 +1,6 @@
import { beforeEach, describe, expect, test, vi } from "vitest";
import { InvalidInputError } from "@formbricks/types/errors";
-import { TBaseFilters, TSegmentWithSurveyNames } from "@formbricks/types/segment";
+import { TBaseFilters, TSegmentWithSurveyRefs } from "@formbricks/types/segment";
import { checkForRecursiveSegmentFilter } from "@/modules/ee/contacts/segments/lib/helper";
import { getSegment } from "@/modules/ee/contacts/segments/lib/segments";
@@ -77,7 +77,7 @@ describe("checkForRecursiveSegmentFilter", () => {
],
};
- vi.mocked(getSegment).mockResolvedValue(referencedSegment as unknown as TSegmentWithSurveyNames);
+ vi.mocked(getSegment).mockResolvedValue(referencedSegment as unknown as TSegmentWithSurveyRefs);
// Act & Assert
// The function should complete without throwing an error
diff --git a/apps/web/modules/ee/contacts/segments/lib/segments.test.ts b/apps/web/modules/ee/contacts/segments/lib/segments.test.ts
index 24f4803fd2..50b5e4f303 100644
--- a/apps/web/modules/ee/contacts/segments/lib/segments.test.ts
+++ b/apps/web/modules/ee/contacts/segments/lib/segments.test.ts
@@ -8,7 +8,7 @@ import {
TEvaluateSegmentUserData,
TSegmentCreateInput,
TSegmentUpdateInput,
- TSegmentWithSurveyNames,
+ TSegmentWithSurveyRefs,
} from "@formbricks/types/segment";
import { getSurvey } from "@/lib/survey/service";
import { validateInputs } from "@/lib/utils/validate";
@@ -79,10 +79,10 @@ const mockSegmentPrisma = {
surveys: [{ id: surveyId, name: "Test Survey", status: "inProgress" }],
};
-const mockSegment: TSegmentWithSurveyNames = {
+const mockSegment: TSegmentWithSurveyRefs = {
...mockSegmentPrisma,
surveys: [surveyId],
- activeSurveys: ["Test Survey"],
+ activeSurveys: [{ id: surveyId, name: "Test Survey" }],
inactiveSurveys: [],
};
@@ -287,7 +287,7 @@ describe("Segment Service Tests", () => {
...mockSegment,
id: clonedSegmentId,
title: "Copy of Test Segment (1)",
- activeSurveys: ["Test Survey"],
+ activeSurveys: [{ id: surveyId, name: "Test Survey" }],
inactiveSurveys: [],
};
@@ -327,7 +327,7 @@ describe("Segment Service Tests", () => {
const clonedSegment2 = {
...clonedSegment,
title: "Copy of Test Segment (2)",
- activeSurveys: ["Test Survey"],
+ activeSurveys: [{ id: surveyId, name: "Test Survey" }],
inactiveSurveys: [],
};
@@ -415,7 +415,7 @@ describe("Segment Service Tests", () => {
title: surveyId,
isPrivate: true,
filters: [],
- activeSurveys: ["Test Survey"],
+ activeSurveys: [{ id: surveyId, name: "Test Survey" }],
inactiveSurveys: [],
};
@@ -487,7 +487,7 @@ describe("Segment Service Tests", () => {
const updatedSegment = {
...mockSegment,
title: "Updated Segment",
- activeSurveys: ["Test Survey"],
+ activeSurveys: [{ id: surveyId, name: "Test Survey" }],
inactiveSurveys: [],
};
const updateData: TSegmentUpdateInput = { title: "Updated Segment" };
@@ -531,7 +531,7 @@ describe("Segment Service Tests", () => {
...updatedSegment,
surveys: [newSurveyId],
activeSurveys: [],
- inactiveSurveys: ["New Survey"],
+ inactiveSurveys: [{ id: newSurveyId, name: "New Survey" }],
};
vi.mocked(prisma.segment.update).mockResolvedValue(updatedSegmentPrismaWithSurvey);
diff --git a/apps/web/modules/ee/contacts/segments/lib/segments.ts b/apps/web/modules/ee/contacts/segments/lib/segments.ts
index d129661285..26607d4aff 100644
--- a/apps/web/modules/ee/contacts/segments/lib/segments.ts
+++ b/apps/web/modules/ee/contacts/segments/lib/segments.ts
@@ -25,7 +25,7 @@ import {
TSegmentPersonFilter,
TSegmentSegmentFilter,
TSegmentUpdateInput,
- TSegmentWithSurveyNames,
+ TSegmentWithSurveyRefs,
ZRelativeDateValue,
ZSegmentCreateInput,
ZSegmentFilters,
@@ -66,14 +66,14 @@ export const selectSegment = {
},
} satisfies Prisma.SegmentSelect;
-export const transformPrismaSegment = (segment: PrismaSegment): TSegmentWithSurveyNames => {
+export const transformPrismaSegment = (segment: PrismaSegment): TSegmentWithSurveyRefs => {
const activeSurveys = segment.surveys
.filter((survey) => survey.status === "inProgress")
- .map((survey) => survey.name);
+ .map((survey) => ({ id: survey.id, name: survey.name }));
const inactiveSurveys = segment.surveys
.filter((survey) => survey.status !== "inProgress")
- .map((survey) => survey.name);
+ .map((survey) => ({ id: survey.id, name: survey.name }));
return {
...segment,
@@ -83,7 +83,7 @@ export const transformPrismaSegment = (segment: PrismaSegment): TSegmentWithSurv
};
};
-export const getSegment = reactCache(async (segmentId: string): Promise => {
+export const getSegment = reactCache(async (segmentId: string): Promise => {
validateInputs([segmentId, ZId]);
try {
const segment = await prisma.segment.findUnique({
@@ -107,7 +107,7 @@ export const getSegment = reactCache(async (segmentId: string): Promise => {
+export const getSegments = reactCache(async (environmentId: string): Promise => {
validateInputs([environmentId, ZId]);
try {
const segments = await prisma.segment.findMany({
diff --git a/apps/web/modules/ee/contacts/segments/page.tsx b/apps/web/modules/ee/contacts/segments/page.tsx
index 2aa6b41cef..6cb9e1be71 100644
--- a/apps/web/modules/ee/contacts/segments/page.tsx
+++ b/apps/web/modules/ee/contacts/segments/page.tsx
@@ -47,6 +47,7 @@ export const SegmentsPage = async ({
upgradePromptTitle={t("environments.segments.unlock_segments_title")}
upgradePromptDescription={t("environments.segments.unlock_segments_description")}>
>;
- segment: TSegmentWithSurveyNames;
onDelete: () => Promise;
}
export const ConfirmDeleteSegmentModal = ({
+ activitySummary,
onDelete,
open,
- segment,
setOpen,
}: ConfirmDeleteSegmentModalProps) => {
const { t } = useTranslation();
@@ -32,9 +32,9 @@ export const ConfirmDeleteSegmentModal = ({
await onDelete();
};
- const segmentHasSurveys = useMemo(() => {
- return segment.activeSurveys.length > 0 || segment.inactiveSurveys.length > 0;
- }, [segment.activeSurveys.length, segment.inactiveSurveys.length]);
+ const allSurveys = useMemo(() => {
+ return [...activitySummary.activeSurveys, ...activitySummary.inactiveSurveys];
+ }, [activitySummary.activeSurveys, activitySummary.inactiveSurveys]);
return (