import { kintonePrettyFields } from './fields.js'; import { getGuestSpaceId, createFieldWithLabels, createFieldLabels, getColumnWidths } from './dom.js'; import { KintoneRestAPIClient } from '@kintone/rest-api-client'; import { COLORS } from './constants.js'; /** * Fetches form data from Kintone API * @param {number} appId - The application ID * @param {string} language - User language setting * @returns {Promise} Form fields and layout data */ const fetchFormData = async (appId, language) => { const client = new KintoneRestAPIClient({ guestSpaceId: getGuestSpaceId(), }); const isPreview = false; try { const [formFieldsResult, layoutResult] = await Promise.all([ client.app.getFormFields({ app: appId, lang: language, preview: isPreview, }), client.app.getFormLayout({ app: appId, preview: isPreview, }), ]); return { formFields: formFieldsResult.properties, layout: layoutResult.layout, }; } catch (error) { console.error('Failed to fetch form data:', error); throw new Error('Could not retrieve form configuration'); } }; /** * Adds label to a subtable field element * @param {Object} field - Field configuration * @param {HTMLElement} fieldElement - The field DOM element */ const addSubtableLabel = (field, fieldElement) => { // Add field code label above the table fieldElement.before( createFieldWithLabels({ code: field.code, type: field.type, }) ); // Add column labels below the table const fieldNames = Object.keys(field.fields); const columnWidths = getColumnWidths(fieldElement, field.type); fieldElement.after( createFieldLabels(fieldNames, columnWidths, field.type) ); }; /** * Adds label to a reference table field element * @param {Object} field - Field configuration * @param {HTMLElement} fieldElement - The field DOM element */ const addReferenceTableLabel = (field, fieldElement) => { // Add field code label above the reference table fieldElement.before( createFieldWithLabels({ code: field.code, type: field.type, }) ); // Add display field labels if available if (field.referenceTable?.displayFields) { const displayFields = field.referenceTable.displayFields; const columnWidths = getColumnWidths(fieldElement, field.type); fieldElement.appendChild( createFieldLabels(displayFields, columnWidths, field.type) ); } }; /** * Adds label to a group field element * @param {Object} field - Field configuration * @param {HTMLElement} fieldElement - The field DOM element */ const addGroupLabel = (field, fieldElement) => { fieldElement.parentElement?.before( createFieldWithLabels({ code: field.code, type: field.type, }) ); }; /** * Adds label to a standard field element * @param {Object} field - Field configuration * @param {HTMLElement} fieldElement - The field DOM element */ const addStandardFieldLabel = (field, fieldElement) => { fieldElement.before( createFieldWithLabels({ code: field.code, type: field.type, }) ); }; /** * Processes and adds labels to all field elements on the page * @param {Array} fieldsWithLabels - Processed field objects with label info */ const processFieldLabels = (fieldsWithLabels) => { for (const field of fieldsWithLabels) { const fieldElement = kintone.app.record.getFieldElement(field.code); if (!fieldElement) continue; // Handle different field types with appropriate label placement if (kintonePrettyFields.isSubtable(field)) { addSubtableLabel(field, fieldElement); } else if (kintonePrettyFields.isReferenceTable(field)) { addReferenceTableLabel(field, fieldElement); } else if (kintonePrettyFields.isGroup(field)) { addGroupLabel(field, fieldElement); } else { addStandardFieldLabel(field, fieldElement); } } }; /** * Processes and adds labels to spacer elements on the page * @param {Array} spacerElements - Spacer element configurations */ const processSpacerLabels = (spacerElements) => { for (const spacer of spacerElements) { const spacerElement = kintone.app.record.getSpaceElement(spacer.elementId); if (!spacerElement) continue; // Add label and blue border to spacer elements spacerElement.appendChild( createFieldWithLabels({ code: spacer.elementId, }) ); spacerElement.style.border = COLORS.SPACER_BORDER; } }; /** * Main function to enhance Kintone forms with labels and visual helpers * @returns {Promise} */ export const runKintoneHelper = async () => { try { // Early return if not in a valid app context const appId = kintone.app.getId(); if (!appId) { console.log('Not in a valid Kintone app context'); return; } // Fetch necessary form configuration const language = kintone.getLoginUser().language; const { formFields, layout } = await fetchFormData(appId, language); // Process fields and generate label data const { fields: fieldsWithLabels, spacers: spacerElements } = kintonePrettyFields.generateFields(formFields, layout); // Apply labels to field elements processFieldLabels(fieldsWithLabels); // Apply visual indicators to spacer elements processSpacerLabels(spacerElements); console.log('Kintone helper labels applied successfully'); } catch (error) { console.error('Failed to run Kintone helper:', error); // Could implement user-friendly error notification here } }; // Execute helper function immediately when the script is injected runKintoneHelper();