mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-20 11:22:55 -05:00
fix: input clear on operand change
This commit is contained in:
@@ -25,7 +25,7 @@ export function AdvancedLogicEditor({
|
||||
isLast,
|
||||
}: AdvancedLogicEditorProps) {
|
||||
return (
|
||||
<div className={cn("no-scrollbar flex w-full grow flex-col gap-4 overflow-x-auto text-sm")}>
|
||||
<div className={cn("flex w-full grow flex-col gap-4 overflow-x-auto text-sm")}>
|
||||
<AdvancedLogicEditorConditions
|
||||
conditions={logicItem.conditions}
|
||||
updateQuestion={updateQuestion}
|
||||
|
||||
@@ -45,7 +45,7 @@ export function AdvancedLogicEditorActions({
|
||||
const actions = logicItem.actions;
|
||||
|
||||
const handleActionsChange = (
|
||||
operation: "delete" | "addBelow" | "duplicate" | "update",
|
||||
operation: "remove" | "addBelow" | "duplicate" | "update",
|
||||
actionIdx: number,
|
||||
action?: TAction
|
||||
) => {
|
||||
@@ -53,7 +53,7 @@ export function AdvancedLogicEditorActions({
|
||||
const logicItem = logicCopy[logicIdx];
|
||||
const actionsClone = logicItem.actions;
|
||||
|
||||
if (operation === "delete") {
|
||||
if (operation === "remove") {
|
||||
actionsClone.splice(actionIdx, 1);
|
||||
} else if (operation === "addBelow") {
|
||||
actionsClone.splice(actionIdx + 1, 0, { id: createId(), objective: "jumpToQuestion", target: "" });
|
||||
@@ -110,7 +110,7 @@ export function AdvancedLogicEditorActions({
|
||||
target: val,
|
||||
});
|
||||
}}
|
||||
comboboxClasses="w-40"
|
||||
comboboxClasses="grow"
|
||||
/>
|
||||
)}
|
||||
{action.objective === "calculate" && (
|
||||
@@ -129,10 +129,11 @@ export function AdvancedLogicEditorActions({
|
||||
},
|
||||
});
|
||||
}}
|
||||
comboboxClasses="w-40"
|
||||
comboboxClasses="grow"
|
||||
emptyDropdownText="Add a variable to calculate"
|
||||
/>
|
||||
<InputCombobox
|
||||
key="attribute"
|
||||
key="operator"
|
||||
showSearch={false}
|
||||
options={getActionOpeartorOptions(
|
||||
localSurvey.variables.find((v) => v.id === action.variableId)?.type
|
||||
@@ -145,7 +146,7 @@ export function AdvancedLogicEditorActions({
|
||||
operator: val,
|
||||
});
|
||||
}}
|
||||
comboboxClasses="w-20"
|
||||
comboboxClasses="grow"
|
||||
/>
|
||||
<InputCombobox
|
||||
key="value"
|
||||
@@ -176,6 +177,7 @@ export function AdvancedLogicEditorActions({
|
||||
});
|
||||
}
|
||||
}}
|
||||
comboboxClasses="grow shrink-0"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@@ -199,7 +201,7 @@ export function AdvancedLogicEditorActions({
|
||||
className="flex items-center gap-2"
|
||||
disabled={actions.length === 1}
|
||||
onClick={() => {
|
||||
handleActionsChange("delete", idx);
|
||||
handleActionsChange("remove", idx);
|
||||
}}>
|
||||
<TrashIcon className="h-4 w-4" />
|
||||
Remove
|
||||
|
||||
@@ -127,10 +127,12 @@ export function AdvancedLogicEditorConditions({
|
||||
};
|
||||
|
||||
const handleOperatorChange = (condition: TSingleCondition, value: TSurveyLogicCondition) => {
|
||||
handleUpdateCondition(condition.id, {
|
||||
operator: value,
|
||||
rightOperand: undefined,
|
||||
});
|
||||
if (value !== condition.operator) {
|
||||
handleUpdateCondition(condition.id, {
|
||||
operator: value,
|
||||
rightOperand: undefined,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleRightOperandChange = (
|
||||
@@ -279,7 +281,7 @@ export function AdvancedLogicEditorConditions({
|
||||
showSearch={false}
|
||||
groupedOptions={options}
|
||||
allowMultiSelect={["equalsOneOf", "includesAllOf", "includesOneOf"].includes(condition.operator)}
|
||||
comboboxClasses="grow min-w-[100px] max-w-[300px]"
|
||||
comboboxClasses="grow min-w-[180px] max-w-[300px]"
|
||||
value={condition.rightOperand?.value}
|
||||
clearable={true}
|
||||
onChangeValue={(val, option) => {
|
||||
|
||||
@@ -74,7 +74,7 @@ export function ConditionalLogic({
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteLogic = (logicItemIdx: number) => {
|
||||
const handleRemoveLogic = (logicItemIdx: number) => {
|
||||
const logicCopy = structuredClone(question.logic || []);
|
||||
logicCopy.splice(logicItemIdx, 1);
|
||||
updateQuestion(questionIdx, {
|
||||
@@ -159,10 +159,10 @@ export function ConditionalLogic({
|
||||
<DropdownMenuItem
|
||||
className="flex items-center gap-2"
|
||||
onClick={() => {
|
||||
handleDeleteLogic(logicItemIdx);
|
||||
handleRemoveLogic(logicItemIdx);
|
||||
}}>
|
||||
<TrashIcon className="h-4 w-4" />
|
||||
Delete
|
||||
Remove
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -757,8 +757,8 @@ export const getActionTargetOptions = (
|
||||
return {
|
||||
label:
|
||||
ending.type === "endScreen"
|
||||
? `🙏 ${getLocalizedValue(ending.headline, "default")}`
|
||||
: `🙏 ${ending.label || "Redirect Thank you card"}`,
|
||||
? getLocalizedValue(ending.headline, "default")
|
||||
: ending.label || "Redirect Thank you card",
|
||||
value: ending.id,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -40,33 +40,33 @@ const operatorsWithoutRightOperand = [
|
||||
export const ZDyanmicLogicField = z.enum(["question", "variable", "hiddenField"]);
|
||||
export const ZActionObjective = z.enum(["calculate", "requireAnswer", "jumpToQuestion"]);
|
||||
export const ZActionTextVariableCalculateOperator = z.enum(["assign", "concat"], {
|
||||
message: "Invalid operator for a text variable",
|
||||
message: "Conditional Logic: Invalid operator for a text variable",
|
||||
});
|
||||
export const ZActionNumberVariableCalculateOperator = z.enum(
|
||||
["add", "subtract", "multiply", "divide", "assign"],
|
||||
{ message: "Invalid operator for a number variable" }
|
||||
{ message: "Conditional Logic: Invalid operator for a number variable" }
|
||||
);
|
||||
|
||||
const ZDynamicQuestion = z.object({
|
||||
type: z.literal("question"),
|
||||
value: z.string().min(1, "Question id cannot be empty"),
|
||||
value: z.string().min(1, "Conditional Logic: Question id cannot be empty"),
|
||||
});
|
||||
|
||||
const ZDynamicVariable = z.object({
|
||||
type: z.literal("variable"),
|
||||
value: z
|
||||
.string()
|
||||
.cuid2({ message: "Variable id must be a valid cuid" })
|
||||
.min(1, "Variable id cannot be empty"),
|
||||
.cuid2({ message: "Conditional Logic: Variable id must be a valid cuid" })
|
||||
.min(1, "Conditional Logic: Variable id cannot be empty"),
|
||||
});
|
||||
|
||||
const ZDynamicHiddenField = z.object({
|
||||
type: z.literal("hiddenField"),
|
||||
value: z.string().min(1, "Hidden field id cannot be empty"),
|
||||
value: z.string().min(1, "Conditional Logic: Hidden field id cannot be empty"),
|
||||
});
|
||||
|
||||
const ZDynamicLogicFieldValue = z.union([ZDynamicQuestion, ZDynamicVariable, ZDynamicHiddenField], {
|
||||
message: "Invalid dynamic field value",
|
||||
message: "Conditional Logic: Invalid dynamic field value",
|
||||
});
|
||||
|
||||
export type TSurveyLogicCondition = z.infer<typeof ZSurveyLogicCondition>;
|
||||
@@ -106,14 +106,14 @@ export const ZSingleCondition = z
|
||||
if (val.rightOperand === undefined) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `rightOperand is required for operator "${val.operator}"`,
|
||||
message: `Conditional Logic: rightOperand is required for operator "${val.operator}"`,
|
||||
path: ["rightOperand"],
|
||||
});
|
||||
}
|
||||
} else if (val.rightOperand !== undefined) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `rightOperand should not be present for operator "${val.operator}"`,
|
||||
message: `Conditional Logic: rightOperand should not be present for operator "${val.operator}"`,
|
||||
path: ["rightOperand"],
|
||||
});
|
||||
}
|
||||
@@ -157,12 +157,8 @@ export const ZActionCalculateText = ZActionCalculateBase.extend({
|
||||
z.object({
|
||||
type: z.literal("static"),
|
||||
value: z
|
||||
.string({ message: "Value must be a string for text variable" })
|
||||
.min(1, "Please enter a value in logic field"),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("static"),
|
||||
value: z.number({ message: "Value must be a number for number variable" }),
|
||||
.string({ message: "Conditional Logic: Value must be a string for text variable" })
|
||||
.min(1, "Conditional Logic: Please enter a value in logic field"),
|
||||
}),
|
||||
ZDynamicLogicFieldValue,
|
||||
]),
|
||||
@@ -173,13 +169,7 @@ export const ZActionCalculateNumber = ZActionCalculateBase.extend({
|
||||
value: z.union([
|
||||
z.object({
|
||||
type: z.literal("static"),
|
||||
value: z
|
||||
.string({ message: "Value must be a string for text variable" })
|
||||
.min(1, "Please enter a value in logic field"),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("static"),
|
||||
value: z.number({ message: "Value must be a number for number variable" }),
|
||||
value: z.number({ message: "Conditional Logic: Value must be a number for number variable" }),
|
||||
}),
|
||||
ZDynamicLogicFieldValue,
|
||||
]),
|
||||
@@ -187,7 +177,7 @@ export const ZActionCalculateNumber = ZActionCalculateBase.extend({
|
||||
if (val.operator === "divide" && val.value.type === "static" && val.value.value === 0) {
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "Cannot divide by zero",
|
||||
message: "Conditional Logic: Cannot divide by zero",
|
||||
path: ["value", "value"],
|
||||
});
|
||||
}
|
||||
@@ -199,13 +189,13 @@ export type TActionCalculate = z.infer<typeof ZActionCalculate>;
|
||||
|
||||
const ZActionRequireAnswer = ZActionBase.extend({
|
||||
objective: z.literal("requireAnswer"),
|
||||
target: z.string().min(1, "Target question id cannot be empty"),
|
||||
target: z.string().min(1, "Conditional Logic: Target question id cannot be empty"),
|
||||
});
|
||||
export type TActionRequireAnswer = z.infer<typeof ZActionRequireAnswer>;
|
||||
|
||||
const ZActionJumpToQuestion = ZActionBase.extend({
|
||||
objective: z.literal("jumpToQuestion"),
|
||||
target: z.string().min(1, "Target question id cannot be empty"),
|
||||
target: z.string().min(1, "Conditional Logic: Target question id cannot be empty"),
|
||||
});
|
||||
|
||||
export type TActionJumpToQuestion = z.infer<typeof ZActionJumpToQuestion>;
|
||||
|
||||
@@ -836,7 +836,7 @@ export const ZSurvey = z
|
||||
const questionIndex = questions.findIndex((q) => q.id === questionId);
|
||||
ctx.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Cyclic logic detected 🔃 Please check the logic of question ${String(questionIndex + 1)}.`,
|
||||
message: `Conditional Logic: Cyclic logic detected 🔃 Please check the logic of question ${String(questionIndex + 1)}.`,
|
||||
path: ["questions", questionIndex, "logic"],
|
||||
});
|
||||
});
|
||||
@@ -1093,11 +1093,20 @@ const validateConditions = (
|
||||
// Validate left operand
|
||||
if (leftOperand.type === "question") {
|
||||
const questionId = leftOperand.value;
|
||||
const question = survey.questions.find((q) => q.id === questionId);
|
||||
const questionIdx = survey.questions.findIndex((q) => q.id === questionId);
|
||||
const question = questionIdx !== -1 ? survey.questions[questionIdx] : undefined;
|
||||
|
||||
if (!question) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
return;
|
||||
} else if (questionIndex < questionIdx) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Conditional Logic: Question ${String(questionIndex + 1)} cannot refer to a question ${String(questionIdx + 1)} that appears later in the survey`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
return;
|
||||
@@ -1108,7 +1117,7 @@ const validateConditions = (
|
||||
if (isInvalidOperator) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid operator "${operator}" for question type "${question.type}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid operator "${operator}" for question type "${question.type}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1128,7 +1137,7 @@ const validateConditions = (
|
||||
if (rightOperand !== undefined) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should not be defined for operator "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should not be defined for operator "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1144,7 +1153,7 @@ const validateConditions = (
|
||||
if (!ques) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1159,7 +1168,7 @@ const validateConditions = (
|
||||
if (!validQuestionTypes.includes(question.type)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1171,7 +1180,7 @@ const validateConditions = (
|
||||
if (!variable) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1182,7 +1191,7 @@ const validateConditions = (
|
||||
if (!field) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1190,7 +1199,7 @@ const validateConditions = (
|
||||
if (!rightOperand.value) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Static value is required in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Static value is required in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1199,14 +1208,14 @@ const validateConditions = (
|
||||
if (rightOperand?.type !== "static") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be a static value for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be a static value for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (condition.operator === "equals" || condition.operator === "doesNotEqual") {
|
||||
if (typeof rightOperand.value !== "string") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be a string for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be a string for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1214,7 +1223,7 @@ const validateConditions = (
|
||||
if (!Array.isArray(rightOperand.value)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be an array for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be an array for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1222,7 +1231,7 @@ const validateConditions = (
|
||||
if (typeof value !== "string") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be an array of strings for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be an array of strings for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1233,7 +1242,7 @@ const validateConditions = (
|
||||
if (rightOperand.value.some((value) => !choices.includes(value))) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Choices selected in right operand does not exist in the choices of the question in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Choices selected in right operand does not exist in the choices of the question in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1246,14 +1255,14 @@ const validateConditions = (
|
||||
if (rightOperand?.type !== "static") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be amongst the choice values for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be amongst the choice values for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (condition.operator === "equals" || condition.operator === "doesNotEqual") {
|
||||
if (typeof rightOperand.value !== "string") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be a string for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be a string for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1261,7 +1270,7 @@ const validateConditions = (
|
||||
if (!choice) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Choice with label "${rightOperand.value}" does not exist in question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Choice with label "${rightOperand.value}" does not exist in question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1270,7 +1279,7 @@ const validateConditions = (
|
||||
if (!Array.isArray(rightOperand.value)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be an array for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be an array for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1278,7 +1287,7 @@ const validateConditions = (
|
||||
if (typeof value !== "string") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be an array of strings for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be an array of strings for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1289,7 +1298,7 @@ const validateConditions = (
|
||||
if (rightOperand.value.some((value) => !choices.includes(value))) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Choices selected in right operand does not exist in the choices of the question in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Choices selected in right operand does not exist in the choices of the question in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1306,13 +1315,13 @@ const validateConditions = (
|
||||
if (!variable) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (variable.type !== "number") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable type should be number in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable type should be number in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1320,28 +1329,28 @@ const validateConditions = (
|
||||
if (typeof rightOperand.value !== "number") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be a number for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be a number for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (question.type === TSurveyQuestionTypeEnum.NPS) {
|
||||
if (rightOperand.value < 0 || rightOperand.value > 10) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `NPS score should be between 0 and 10 for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: NPS score should be between 0 and 10 for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
} else if (rightOperand.value < 1 || rightOperand.value > question.range) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Rating score should be between 1 and ${String(question.range)} for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Rating value should be between 1 and ${String(question.range)} for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
} else {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Right operand should be a variable or a static value for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Right operand should be a variable or a static value for "${operator}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1353,7 +1362,7 @@ const validateConditions = (
|
||||
if (!ques) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1361,7 +1370,7 @@ const validateConditions = (
|
||||
if (!validQuestionTypes.includes(question.type)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1373,13 +1382,13 @@ const validateConditions = (
|
||||
if (!variable) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (variable.type !== "text") {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable type should be text in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable type should be text in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1390,17 +1399,23 @@ const validateConditions = (
|
||||
if (!doesFieldExists) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
} else if (rightOperand?.type === "static") {
|
||||
const date = rightOperand.value as string;
|
||||
|
||||
if (isNaN(new Date(date).getTime())) {
|
||||
if (!date) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid date format for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Please select a date value in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (isNaN(new Date(date).getTime())) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Conditional Logic: Invalid date format for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1412,7 +1427,7 @@ const validateConditions = (
|
||||
if (!variable) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1421,7 +1436,7 @@ const validateConditions = (
|
||||
if (isInvalidOperator) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid operator "${operator}" for variable ${variable.name} of type "${variable.type}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid operator "${operator}" for variable ${variable.name} of type "${variable.type}" in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1434,7 +1449,7 @@ const validateConditions = (
|
||||
if (!question) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (variable.type === "number") {
|
||||
@@ -1442,7 +1457,7 @@ const validateConditions = (
|
||||
if (!validQuestionTypes.includes(question.type)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1458,7 +1473,7 @@ const validateConditions = (
|
||||
if (!validQuestionTypes.includes(question.type)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1470,13 +1485,13 @@ const validateConditions = (
|
||||
if (!foundVariable) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else if (variable.type !== foundVariable.type) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable type mismatch in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable type mismatch in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1487,7 +1502,7 @@ const validateConditions = (
|
||||
if (!field) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1500,7 +1515,7 @@ const validateConditions = (
|
||||
if (!hiddenField) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Hidden field ID ${hiddenFieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Hidden field ID ${hiddenFieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1510,7 +1525,7 @@ const validateConditions = (
|
||||
if (isInvalidOperator) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid operator "${operator}" for hidden field in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid operator "${operator}" for hidden field in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1523,7 +1538,7 @@ const validateConditions = (
|
||||
if (!question) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Question ID ${questionId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
} else {
|
||||
@@ -1539,7 +1554,7 @@ const validateConditions = (
|
||||
if (!validQuestionTypes.includes(question.type)) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Invalid question type "${question.type}" for right operand in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1551,7 +1566,7 @@ const validateConditions = (
|
||||
if (!variable) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1562,7 +1577,7 @@ const validateConditions = (
|
||||
if (!field) {
|
||||
issues.push({
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Hidden field ID ${fieldId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex, "conditions"],
|
||||
});
|
||||
}
|
||||
@@ -1600,7 +1615,7 @@ const validateActions = (
|
||||
if (!variable) {
|
||||
return {
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: `Variable ID ${action.variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
message: `Conditional Logic: Variable ID ${action.variableId} does not exist in logic no: ${String(logicIndex + 1)} of question ${String(questionIndex + 1)}`,
|
||||
path: ["questions", questionIndex, "logic", logicIndex],
|
||||
};
|
||||
}
|
||||
@@ -1614,6 +1629,7 @@ const validateActions = (
|
||||
path: ["questions", questionIndex, "logic", logicIndex],
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const numberVariableParseData = ZActionCalculateNumber.safeParse(action);
|
||||
|
||||
@@ -40,6 +40,7 @@ export interface InputComboboxProps {
|
||||
allowMultiSelect?: boolean;
|
||||
showCheckIcon?: boolean;
|
||||
comboboxClasses?: string;
|
||||
emptyDropdownText?: string;
|
||||
}
|
||||
|
||||
export const InputCombobox = ({
|
||||
@@ -55,6 +56,7 @@ export const InputCombobox = ({
|
||||
allowMultiSelect = false,
|
||||
showCheckIcon = false,
|
||||
comboboxClasses,
|
||||
emptyDropdownText = "No option found.",
|
||||
}: InputComboboxProps) => {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [localValue, setLocalValue] = React.useState<
|
||||
@@ -68,7 +70,7 @@ export const InputCombobox = ({
|
||||
const validOptions = options?.length ? options : groupedOptions?.flatMap((group) => group.options);
|
||||
|
||||
if (value === null || value === undefined) {
|
||||
setLocalValue(null);
|
||||
setLocalValue("");
|
||||
setInputType(null);
|
||||
} else {
|
||||
if (Array.isArray(value)) {
|
||||
@@ -161,9 +163,9 @@ export const InputCombobox = ({
|
||||
));
|
||||
} else if (localValue && typeof localValue === "object") {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex items-center gap-2 truncate">
|
||||
{localValue.icon && <localValue.icon className="h-5 w-5 shrink-0 text-slate-400" />}
|
||||
<span>{localValue.label}</span>
|
||||
<span className="truncate">{localValue.label}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -178,14 +180,14 @@ export const InputCombobox = ({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex max-w-[450px] overflow-hidden rounded-md border border-slate-300",
|
||||
"flex max-w-[440px] overflow-hidden rounded-md border border-slate-300",
|
||||
comboboxClasses
|
||||
)}>
|
||||
{withInput && inputType !== "dropdown" && (
|
||||
<Input
|
||||
className="min-w-0 rounded-none border-0 border-r border-slate-300 bg-white focus:border-slate-300"
|
||||
{...inputProps}
|
||||
value={value as string | number}
|
||||
value={localValue as string | number}
|
||||
onChange={onInputChange}
|
||||
/>
|
||||
)}
|
||||
@@ -203,9 +205,9 @@ export const InputCombobox = ({
|
||||
<div className="ellipsis flex w-full gap-2 truncate px-2">{getDisplayValue}</div>
|
||||
)}
|
||||
{clearable && inputType === "dropdown" ? (
|
||||
<XIcon className="h-5 w-5 shrink-0 text-slate-300" onClick={handleClear} />
|
||||
<XIcon className="h-5 w-5 shrink-0 text-slate-300 hover:text-slate-400" onClick={handleClear} />
|
||||
) : (
|
||||
<ChevronDownIcon className="h-5 w-5 shrink-0 text-slate-300" />
|
||||
<ChevronDownIcon className="h-5 w-5 shrink-0 text-slate-300 hover:text-slate-400" />
|
||||
)}
|
||||
</div>
|
||||
</PopoverTrigger>
|
||||
@@ -213,7 +215,7 @@ export const InputCombobox = ({
|
||||
className={cn(
|
||||
"w-auto max-w-[400px] overflow-y-auto truncate border border-slate-400 bg-slate-50 p-0 shadow-none",
|
||||
{
|
||||
"pt-2": showSearch,
|
||||
"px-2 pt-2": showSearch,
|
||||
}
|
||||
)}>
|
||||
<Command>
|
||||
@@ -223,8 +225,8 @@ export const InputCombobox = ({
|
||||
className="h-8 border-slate-400 bg-white placeholder-slate-300"
|
||||
/>
|
||||
)}
|
||||
<CommandList>
|
||||
<CommandEmpty>No option found.</CommandEmpty>
|
||||
<CommandList className="mx-1 my-2">
|
||||
<CommandEmpty className="mx-2 my-0">{emptyDropdownText}</CommandEmpty>
|
||||
{options && options.length > 0 ? (
|
||||
<CommandGroup>
|
||||
{options.map((option) => (
|
||||
@@ -232,7 +234,7 @@ export const InputCombobox = ({
|
||||
key={option.value}
|
||||
onSelect={() => handleSelect(option)}
|
||||
title={option.label}
|
||||
className="cursor-pointer">
|
||||
className="cursor-pointer truncate hover:text-slate-500">
|
||||
{showCheckIcon &&
|
||||
((allowMultiSelect &&
|
||||
Array.isArray(localValue) &&
|
||||
@@ -241,7 +243,7 @@ export const InputCombobox = ({
|
||||
typeof localValue === "object" &&
|
||||
!Array.isArray(localValue) &&
|
||||
localValue?.value === option.value)) && (
|
||||
<CheckIcon className="mr-2 h-4 w-4 text-slate-300" />
|
||||
<CheckIcon className="mr-2 h-4 w-4 text-slate-300 hover:text-slate-400" />
|
||||
)}
|
||||
{option.icon && <option.icon className="mr-2 h-5 w-5 shrink-0 text-slate-400" />}
|
||||
<span className="truncate">{option.label}</span>
|
||||
@@ -258,7 +260,7 @@ export const InputCombobox = ({
|
||||
<CommandItem
|
||||
key={option.value}
|
||||
onSelect={() => handleSelect(option)}
|
||||
className="cursor-pointer truncate">
|
||||
className="cursor-pointer truncate hover:text-slate-500">
|
||||
{showCheckIcon &&
|
||||
((allowMultiSelect &&
|
||||
Array.isArray(localValue) &&
|
||||
@@ -267,7 +269,7 @@ export const InputCombobox = ({
|
||||
typeof localValue === "object" &&
|
||||
!Array.isArray(localValue) &&
|
||||
localValue?.value === option.value)) && (
|
||||
<CheckIcon className="mr-2 h-4 w-4 shrink-0 text-slate-300" />
|
||||
<CheckIcon className="mr-2 h-4 w-4 shrink-0 text-slate-300 hover:text-slate-400" />
|
||||
)}
|
||||
{option.icon && <option.icon className="mr-2 h-5 w-5 shrink-0 text-slate-400" />}
|
||||
<span className="truncate">{option.label}</span>
|
||||
|
||||
Reference in New Issue
Block a user