FEAT: Refactor berth API functions to use dedicated utility methods for fetching and updating berths, and add connection test for NocoDB

This commit is contained in:
2025-06-17 16:07:15 +02:00
parent 0e85cb40bc
commit adf226a38a
5 changed files with 235 additions and 154 deletions

View File

@@ -1,3 +1,5 @@
import type { Interest, Berth } from "@/utils/types";
export interface PageInfo {
pageSize: number;
totalRows: number;
@@ -11,8 +13,14 @@ export interface InterestsResponse {
PageInfo: PageInfo;
}
export interface BerthsResponse {
list: Berth[];
PageInfo: PageInfo;
}
export enum Table {
Interest = "mbs9hjauug4eseo",
Berth = "mczgos9hr3oa9qc",
}
/**
@@ -414,3 +422,146 @@ export const getInterestByFieldAsync = async (fieldName: string, value: any): Pr
return null;
}
};
// Berth functions
export const getBerths = async () => {
console.log('[nocodb.getBerths] Fetching berths from NocoDB...');
const result = await $fetch<BerthsResponse>(createTableUrl(Table.Berth), {
headers: {
"xc-token": getNocoDbConfiguration().token,
},
params: {
limit: 1000,
// Include interested parties (expand the linked field)
fields: '*,Interested Parties.Id,Interested Parties.Full Name,Interested Parties.Sales Process Level,Interested Parties.EOI Status,Interested Parties.Contract Status'
},
});
console.log('[nocodb.getBerths] Successfully fetched berths, count:', result.list?.length || 0);
// Sort berths by letter zone and then by number using Mooring Number
if (result.list && Array.isArray(result.list)) {
result.list.sort((a, b) => {
const berthA = a['Mooring Number'] || '';
const berthB = b['Mooring Number'] || '';
// Extract letter and number parts
const matchA = berthA.match(/^([A-Za-z]+)(\d+)$/);
const matchB = berthB.match(/^([A-Za-z]+)(\d+)$/);
if (matchA && matchB) {
const [, letterA, numberA] = matchA;
const [, letterB, numberB] = matchB;
// First sort by letter zone
const letterCompare = letterA.localeCompare(letterB);
if (letterCompare !== 0) {
return letterCompare;
}
// Then sort by number within the same letter zone
return parseInt(numberA) - parseInt(numberB);
}
// Fallback to string comparison if pattern doesn't match
return berthA.localeCompare(berthB);
});
console.log('[nocodb.getBerths] Berths sorted by zone and number');
}
return result;
};
export const getBerthById = async (id: string) => {
console.log('[nocodb.getBerthById] Fetching berth ID:', id);
const result = await $fetch<Berth>(`${createTableUrl(Table.Berth)}/${id}`, {
headers: {
"xc-token": getNocoDbConfiguration().token,
},
params: {
// Include interested parties (expand the linked field)
fields: '*,Interested Parties.Id,Interested Parties.Full Name,Interested Parties.Sales Process Level,Interested Parties.EOI Status,Interested Parties.Contract Status'
}
});
console.log('[nocodb.getBerthById] Successfully fetched berth:', result.Id);
return result;
};
export const updateBerth = async (id: string, data: Partial<Berth>): Promise<Berth> => {
console.log('[nocodb.updateBerth] Updating berth:', id);
console.log('[nocodb.updateBerth] Data fields:', Object.keys(data));
// Create a clean data object that matches the Berth schema
const cleanData: Record<string, any> = {};
// Only include fields that are part of the Berth schema
const allowedFields = [
"Mooring Number",
"Area",
"Status",
"Nominal Boat Size",
"Water Depth",
"Length",
"Width",
"Depth",
"Side Pontoon",
"Power Capacity",
"Voltage",
"Mooring Type",
"Access",
"Cleat Type",
"Cleat Capacity",
"Bollard Type",
"Bollard Capacity",
"Price",
"Bow Facing"
];
// Filter the data to only include allowed fields
for (const field of allowedFields) {
if (field in data) {
const value = (data as any)[field];
// Handle clearing fields - NocoDB requires null for clearing, not undefined
if (value === undefined) {
cleanData[field] = null;
console.log(`[nocodb.updateBerth] Converting undefined to null for field: ${field}`);
} else {
cleanData[field] = value;
}
}
}
console.log('[nocodb.updateBerth] Clean data fields:', Object.keys(cleanData));
// PATCH requires ID in the body (not in URL)
// Ensure ID is an integer
cleanData.Id = parseInt(id);
const url = createTableUrl(Table.Berth);
console.log('[nocodb.updateBerth] URL:', url);
try {
console.log('[nocodb.updateBerth] Sending PATCH request');
const result = await $fetch<Berth>(url, {
method: "PATCH",
headers: {
"xc-token": getNocoDbConfiguration().token,
"Content-Type": "application/json"
},
body: cleanData
});
console.log('[nocodb.updateBerth] Update successful for ID:', id);
return result;
} catch (error: any) {
console.error('[nocodb.updateBerth] Update failed:', error);
console.error('[nocodb.updateBerth] Error details:', error instanceof Error ? error.message : 'Unknown error');
throw error;
}
};