refactor: improve code formatting and readability in page.tsx

This commit is contained in:
Abhimanyu Saharan
2026-02-13 21:30:29 +05:30
parent 277bfcb33a
commit aea69f5118
3 changed files with 96 additions and 44 deletions

View File

@@ -580,17 +580,15 @@ const formatCustomFieldDetailValue = (
const trimmed = value.trim();
if (!trimmed) return "—";
try {
// Validate URL before rendering as a link.
// eslint-disable-next-line no-new
new URL(trimmed);
const parsedUrl = new URL(trimmed);
return (
<a
href={trimmed}
href={parsedUrl.toString()}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-blue-700 underline decoration-blue-300 underline-offset-2 hover:text-blue-800"
>
<span className="break-all">{trimmed}</span>
<span className="break-all">{parsedUrl.toString()}</span>
<ArrowUpRight className="h-3.5 w-3.5 flex-shrink-0" />
</a>
);
@@ -601,8 +599,7 @@ const formatCustomFieldDetailValue = (
if (fieldType === "json") {
try {
const normalized =
typeof value === "string" ? JSON.parse(value) : value;
const normalized = typeof value === "string" ? JSON.parse(value) : value;
return (
<pre className="whitespace-pre-wrap break-words rounded border border-slate-200 bg-white px-2 py-1 font-mono text-xs leading-relaxed text-slate-800">
{JSON.stringify(normalized, null, 2)}
@@ -615,7 +612,11 @@ const formatCustomFieldDetailValue = (
if (fieldType === "text_long") {
const text = customFieldInputText(value);
return text ? <span className="whitespace-pre-wrap break-words">{text}</span> : "—";
return text ? (
<span className="whitespace-pre-wrap break-words">{text}</span>
) : (
"—"
);
}
return customFieldInputText(value) || "—";
@@ -634,7 +635,8 @@ const isCustomFieldVisible = (
value: unknown,
): boolean => {
if (definition.ui_visibility === "hidden") return false;
if (definition.ui_visibility === "if_set") return isCustomFieldValueSet(value);
if (definition.ui_visibility === "if_set")
return isCustomFieldValueSet(value);
return true;
};
@@ -644,7 +646,10 @@ const parseCustomFieldInputValue = (
): unknown | null => {
const trimmed = text.trim();
if (!trimmed) return null;
if (definition.field_type === "text" || definition.field_type === "text_long") {
if (
definition.field_type === "text" ||
definition.field_type === "text_long"
) {
return trimmed;
}
if (definition.field_type === "integer") {
@@ -739,7 +744,10 @@ const customFieldPatchPayload = (
): TaskCustomFieldValues =>
definitions.reduce((acc, definition) => {
const key = definition.field_key;
const currentValue = Object.prototype.hasOwnProperty.call(currentValues, key)
const currentValue = Object.prototype.hasOwnProperty.call(
currentValues,
key,
)
? currentValues[key]
: null;
const nextValue = Object.prototype.hasOwnProperty.call(nextValues, key)
@@ -2855,7 +2863,10 @@ export default function BoardDetailPage() {
if (dueDateChanged) {
updatePayload.due_at = localDateInputToUtcIso(editDueDate);
}
if (customFieldValuesChanged && Object.keys(editCustomFieldPatch).length > 0) {
if (
customFieldValuesChanged &&
Object.keys(editCustomFieldPatch).length > 0
) {
updatePayload.custom_field_values = editCustomFieldPatch;
}
@@ -4343,7 +4354,8 @@ export default function BoardDetailPage() {
) : (
<div className="space-y-3">
{boardCustomFieldDefinitions.map((definition) => {
const fieldValue = editCustomFieldValues[definition.field_key];
const fieldValue =
editCustomFieldValues[definition.field_key];
if (!isCustomFieldVisible(definition, fieldValue)) {
return null;
}
@@ -4371,7 +4383,9 @@ export default function BoardDetailPage() {
value === "unset" ? null : value === "true",
}))
}
disabled={!selectedTask || isSavingTask || !canWrite}
disabled={
!selectedTask || isSavingTask || !canWrite
}
>
<SelectTrigger>
<SelectValue placeholder="Optional" />
@@ -4389,10 +4403,11 @@ export default function BoardDetailPage() {
onChange={(event) =>
setEditCustomFieldValues((prev) => ({
...prev,
[definition.field_key]: parseCustomFieldInputValue(
definition,
event.target.value,
),
[definition.field_key]:
parseCustomFieldInputValue(
definition,
event.target.value,
),
}))
}
placeholder={
@@ -4402,7 +4417,9 @@ export default function BoardDetailPage() {
: "Optional"
}
rows={definition.field_type === "text_long" ? 3 : 4}
disabled={!selectedTask || isSavingTask || !canWrite}
disabled={
!selectedTask || isSavingTask || !canWrite
}
/>
) : (
<Input
@@ -4418,15 +4435,20 @@ export default function BoardDetailPage() {
? "url"
: "text"
}
step={definition.field_type === "decimal" ? "any" : undefined}
step={
definition.field_type === "decimal"
? "any"
: undefined
}
value={customFieldInputText(fieldValue)}
onChange={(event) =>
setEditCustomFieldValues((prev) => ({
...prev,
[definition.field_key]: parseCustomFieldInputValue(
definition,
event.target.value,
),
[definition.field_key]:
parseCustomFieldInputValue(
definition,
event.target.value,
),
}))
}
placeholder={
@@ -4435,7 +4457,9 @@ export default function BoardDetailPage() {
? `Default: ${customFieldInputText(definition.default_value)}`
: "Optional"
}
disabled={!selectedTask || isSavingTask || !canWrite}
disabled={
!selectedTask || isSavingTask || !canWrite
}
/>
)}
{definition.description ? (
@@ -4833,10 +4857,11 @@ export default function BoardDetailPage() {
onChange={(event) =>
setCreateCustomFieldValues((prev) => ({
...prev,
[definition.field_key]: parseCustomFieldInputValue(
definition,
event.target.value,
),
[definition.field_key]:
parseCustomFieldInputValue(
definition,
event.target.value,
),
}))
}
placeholder={
@@ -4862,15 +4887,20 @@ export default function BoardDetailPage() {
? "url"
: "text"
}
step={definition.field_type === "decimal" ? "any" : undefined}
step={
definition.field_type === "decimal"
? "any"
: undefined
}
value={customFieldInputText(fieldValue)}
onChange={(event) =>
setCreateCustomFieldValues((prev) => ({
...prev,
[definition.field_key]: parseCustomFieldInputValue(
definition,
event.target.value,
),
[definition.field_key]:
parseCustomFieldInputValue(
definition,
event.target.value,
),
}))
}
placeholder={

View File

@@ -67,7 +67,13 @@ type EditCustomFieldFormProps = {
onSubmit: (updates: TaskCustomFieldDefinitionUpdate) => Promise<void>;
};
const STRING_FIELD_TYPES = new Set(["text", "text_long", "date", "date_time", "url"]);
const STRING_FIELD_TYPES = new Set([
"text",
"text_long",
"date",
"date_time",
"url",
]);
const parseDefaultValue = (
fieldType: FormState["fieldType"],
@@ -92,11 +98,14 @@ const parseDefaultValue = (
}
if (fieldType === "boolean") {
if (trimmed.toLowerCase() === "true") return { value: true, error: null };
if (trimmed.toLowerCase() === "false")
return { value: false, error: null };
if (trimmed.toLowerCase() === "false") return { value: false, error: null };
return { value: null, error: "Default value must be true or false." };
}
if (fieldType === "date" || fieldType === "date_time" || fieldType === "url") {
if (
fieldType === "date" ||
fieldType === "date_time" ||
fieldType === "url"
) {
return { value: trimmed, error: null };
}
if (fieldType === "json") {
@@ -198,7 +207,9 @@ function EditCustomFieldForm({
trimmedValidationRegex &&
!STRING_FIELD_TYPES.has(formState.fieldType)
) {
setSaveError("Validation regex is only supported for string field types.");
setSaveError(
"Validation regex is only supported for string field types.",
);
return;
}
const parsedDefaultValue = parseDefaultValue(
@@ -455,7 +466,9 @@ function EditCustomFieldForm({
Loading boards
</div>
) : boardsError ? (
<div className="px-4 py-6 text-sm text-rose-700">{boardsError}</div>
<div className="px-4 py-6 text-sm text-rose-700">
{boardsError}
</div>
) : filteredBoards.length === 0 ? (
<div className="px-4 py-6 text-sm text-slate-500">
No boards found.

View File

@@ -63,7 +63,13 @@ const defaultFormState: FormState = {
defaultValue: "",
};
const STRING_FIELD_TYPES = new Set(["text", "text_long", "date", "date_time", "url"]);
const STRING_FIELD_TYPES = new Set([
"text",
"text_long",
"date",
"date_time",
"url",
]);
const parseDefaultValue = (
fieldType: FormState["fieldType"],
@@ -88,11 +94,14 @@ const parseDefaultValue = (
}
if (fieldType === "boolean") {
if (trimmed.toLowerCase() === "true") return { value: true, error: null };
if (trimmed.toLowerCase() === "false")
return { value: false, error: null };
if (trimmed.toLowerCase() === "false") return { value: false, error: null };
return { value: null, error: "Default value must be true or false." };
}
if (fieldType === "date" || fieldType === "date_time" || fieldType === "url") {
if (
fieldType === "date" ||
fieldType === "date_time" ||
fieldType === "url"
) {
return { value: trimmed, error: null };
}
if (fieldType === "json") {