Skip to content
Snippets Groups Projects
AdminRenderer.js 16.40 KiB
// src/renderers/AdminRenderer.js

export function renderAdminData(adminData, language) {
  const container = document.getElementById('adminData');
  container.innerHTML = '';

  // Title
  const title = document.createElement('h2');
  title.textContent = `Administrative Data (${language})`;
  container.appendChild(title);

  // ----- CORE DATA SECTION -----
  if (adminData['dcc:coreData']) {
    const coreData = adminData['dcc:coreData'];
    const coreContainer = document.createElement('div');
    coreContainer.style.marginBottom = '20px';
    coreContainer.style.border = '1px solid #ccc';
    coreContainer.style.padding = '8px';

    // Unique Identifier
    const uuidDiv = document.createElement('div');
    uuidDiv.innerHTML = `<strong>Unique Identifier:</strong> ${coreData['dcc:uniqueIdentifier'] || 'N/A'}`;
    uuidDiv.style.marginBottom = '10px';
    coreContainer.appendChild(uuidDiv);

    // Identifications table
    if (coreData['dcc:identifications'] && coreData['dcc:identifications']['dcc:identification']) {
      let identifications = coreData['dcc:identifications']['dcc:identification'];
      if (!Array.isArray(identifications)) {
        identifications = [identifications];
      }
      const idTable = document.createElement('table');
      idTable.style.width = '100%';
      idTable.style.borderCollapse = 'collapse';
      identifications.forEach(id => {
        const tr = document.createElement('tr');
        tr.style.borderBottom = '1px solid #ccc';

        // Identification Name (language-aware)
        let idName = '';
        if (id['dcc:name'] && id['dcc:name']['dcc:content']) {
          const content = id['dcc:name']['dcc:content'];
          idName = Array.isArray(content)
              ? (content.find(item => item.$ && item.$.lang === language) || content[0])._ || ''
              : content._ || '';
        }
        const tdName = document.createElement('td');
        tdName.style.padding = '4px';
        tdName.innerHTML = `<strong>${idName}</strong>`;
        tr.appendChild(tdName);

        // Issuer and Value
        const tdIssuerValue = document.createElement('td');
        tdIssuerValue.style.padding = '4px';
        tdIssuerValue.innerHTML = `<em>${id['dcc:issuer'] || ''}</em>: ${id['dcc:value'] || ''}`;
        tr.appendChild(tdIssuerValue);

        idTable.appendChild(tr);
      });
      coreContainer.appendChild(idTable);
    }
    container.appendChild(coreContainer);
  }

  // ----- ADDRESSES SECTION -----
  const addressesContainer = document.createElement('div');
  addressesContainer.style.display = 'flex';
  addressesContainer.style.justifyContent = 'space-between';
  addressesContainer.style.marginBottom = '20px';
  // Mapping for Calibration Laboratory and Customer static labels.
  const labLabelMapping = {
    de: 'Kalibrierlabor',
    en: 'Calibration Laboratory',
    fr: "Laboratoire d'étalonnage",
    es: 'Laboratorio de calibración'
  };
  const custLabelMapping = {
    de: 'Kunde',
    en: 'Customer',
    fr: 'Client',
    es: 'Cliente'
  };

  // Calibration Laboratory (left side)
  if (adminData['dcc:calibrationLaboratory'] && adminData['dcc:calibrationLaboratory']['dcc:contact']) {
    const calLab = adminData['dcc:calibrationLaboratory']['dcc:contact'];
    const labDiv = document.createElement('div');
    labDiv.style.width = '45%';
    labDiv.style.border = '1px solid #ccc';
    labDiv.style.padding = '8px';
    // Render logo from descriptionData if available:
    if (calLab['dcc:descriptionData']) {
      const descData = calLab['dcc:descriptionData'];
      let logoImg = '';
      if (descData['dcc:dataBase64'] && descData['dcc:mimeType']) {
        logoImg = `<img src="data:${descData['dcc:mimeType']};base64,${descData['dcc:dataBase64']}" style="max-width:150px; max-height:150px; display:block; margin-bottom:8px;" />`;
      }
      labDiv.innerHTML += logoImg;
    }
    // Use static label based on language
    const labLabelMapping = {
      de: 'Kalibrierlabor',
      en: 'Calibration Laboratory',
      fr: "Laboratoire d'étalonnage",
      es: 'Laboratorio de calibración'
    };
    labDiv.innerHTML += `<strong>${labLabelMapping[language] || 'Calibration Laboratory'}:</strong><br>`;
    labDiv.innerHTML += renderAddress(calLab);
    addressesContainer.appendChild(labDiv);
  }

  // Customer (left side)
  if (adminData['dcc:customer']) {
    const customer = adminData['dcc:customer'];
    const custDiv = document.createElement('div');
    custDiv.style.width = '45%';
    custDiv.style.border = '1px solid #ccc';
    custDiv.style.padding = '8px';
    custDiv.innerHTML = `<strong>${custLabelMapping[language] || 'Customer'}:</strong><br>`;
    custDiv.innerHTML += renderAddress(customer);
    addressesContainer.appendChild(custDiv);
  }
  container.appendChild(addressesContainer);

// ----- ITEMS SECTION (Updated for inline image with mouseover enlargement) -----
  if (adminData['dcc:items'] && adminData['dcc:items']['dcc:item']) {
    let items = adminData['dcc:items']['dcc:item'];
    if (!Array.isArray(items)) items = [items];
    const itemsContainer = document.createElement('div');
    itemsContainer.style.marginBottom = '20px';
    itemsContainer.innerHTML = `<h3>Items</h3>`;
    items.forEach(item => {
      // Create a flex container for the item details and image.
      const itemDiv = document.createElement('div');
      itemDiv.style.border = '1px solid #ccc';
      itemDiv.style.padding = '8px';
      itemDiv.style.marginBottom = '10px';
      itemDiv.style.display = 'flex';
      itemDiv.style.justifyContent = 'space-between';
      itemDiv.style.alignItems = 'center';

      // Left side: textual details
      const detailsDiv = document.createElement('div');
      detailsDiv.style.flex = '1';
      detailsDiv.style.marginRight = '10px';

      // Item Name (language-aware)
      let itemName = '';
      if (item['dcc:name'] && item['dcc:name']['dcc:content']) {
        const content = item['dcc:name']['dcc:content'];
        itemName = Array.isArray(content)
            ? (content.find(c => c.$ && c.$.lang === language) || content[0])._ || ''
            : content._ || '';
      }
      detailsDiv.innerHTML += `<strong>Item:</strong> ${itemName}<br>`;

      // Manufacturer details
      if (item['dcc:manufacturer']) {
        const manu = item['dcc:manufacturer'];
        let manuName = '';
        if (manu['dcc:name'] && manu['dcc:name']['dcc:content']) {
          const content = manu['dcc:name']['dcc:content'];
          manuName = Array.isArray(content)
              ? (content.find(c => c.$ && c.$.lang === language) || content[0])._ || ''
              : content._ || '';
        }
        detailsDiv.innerHTML += `<strong>Manufacturer:</strong> ${manuName}<br>`;
        if (manu['dcc:location']) {
          detailsDiv.innerHTML += `<strong>Location:</strong> ${renderAddress(manu['dcc:location'])}<br>`;
        }
      }

      // Model
      if (item['dcc:model']) {
        detailsDiv.innerHTML += `<strong>Model:</strong> ${item['dcc:model']}<br>`;
      }

      // Item Identifications
      if (item['dcc:identifications'] && item['dcc:identifications']['dcc:identification']) {
        let identifications = item['dcc:identifications']['dcc:identification'];
        if (!Array.isArray(identifications)) identifications = [identifications];
        detailsDiv.innerHTML += `<strong>Identifications:</strong><br>`;
        identifications.forEach(id => {
          let idName = '';
          if (id['dcc:name'] && id['dcc:name']['dcc:content']) {
            const content = id['dcc:name']['dcc:content'];
            idName = Array.isArray(content)
                ? (content.find(item => item.$ && item.$.lang === language) || content[0])._ || ''
                : content._ || '';
          }
          detailsDiv.innerHTML += `<em>${id['dcc:issuer'] || ''}</em> - ${idName}: ${id['dcc:value'] || ''}<br>`;
        });
      }

      itemDiv.appendChild(detailsDiv);

      // Right side: always display image (if available) as an inline thumbnail
      if (item['dcc:description'] && item['dcc:description']['dcc:file']) {
        let file = item['dcc:description']['dcc:file'];
        if (!Array.isArray(file)) file = [file];
        const firstFile = file[0];
        if (firstFile['dcc:dataBase64'] && firstFile['dcc:mimeType']) {
          const img = document.createElement('img');
          img.src = `data:${firstFile['dcc:mimeType']};base64,${firstFile['dcc:dataBase64']}`;
          img.style.maxWidth = '150px';
          img.style.maxHeight = '150px';
          img.style.transition = 'transform 0.3s';
          img.style.cursor = 'pointer';
          // Enlarge on mouse over
          img.addEventListener('mouseover', () => {
            img.style.transform = 'scale(1.5)';
          });
          img.addEventListener('mouseout', () => {
            img.style.transform = 'scale(1)';
          });
          itemDiv.appendChild(img);
        }
      }

      itemsContainer.appendChild(itemDiv);
    });
    container.appendChild(itemsContainer);
  }
  // ----- STATEMENTS SECTION -----
  if (adminData['dcc:statements'] && adminData['dcc:statements']['dcc:statement']) {
    let statements = adminData['dcc:statements']['dcc:statement'];
    if (!Array.isArray(statements)) {
      statements = [statements];
    }
    const statementsContainer = document.createElement('div');
    statementsContainer.style.marginBottom = '20px';
    statementsContainer.innerHTML = `<h3>Statements</h3>`;
    statements.forEach(stmt => {
      const details = document.createElement('details');
      details.style.border = '1px solid #ccc';
      details.style.padding = '8px';
      details.style.marginBottom = '10px';

      // Summary: use dcc:name if available; if not, fallback to declaration's name
      let stmtName = '';
      if (stmt['dcc:name'] && stmt['dcc:name']['dcc:content']) {
        const content = stmt['dcc:name']['dcc:content'];
        stmtName = Array.isArray(content)
            ? (content.find(item => item.$ && item.$.lang === language) || content[0])._ || ''
            : content._ || '';
      } else if (stmt['dcc:declaration'] && stmt['dcc:declaration']['dcc:name'] && stmt['dcc:declaration']['dcc:name']['dcc:content']) {
        const content = stmt['dcc:declaration']['dcc:name']['dcc:content'];
        stmtName = Array.isArray(content)
            ? (content.find(item => item.$ && item.$.lang === language) || content[0])._ || ''
            : content._ || '';
      }
      // If thumbnail available, render it
      let thumbHtml = '';
      if (stmt['dcc:declaration'] && stmt['dcc:declaration']['dcc:file']) {
        let file = stmt['dcc:declaration']['dcc:file'];
        if (!Array.isArray(file)) file = [file];
        const firstFile = file[0];
        if (firstFile['dcc:dataBase64'] && firstFile['dcc:mimeType']) {
          thumbHtml = `<img src="data:${firstFile['dcc:mimeType']};base64,${firstFile['dcc:dataBase64']}" style="max-height:30px; vertical-align:middle; margin-right:8px;" />`;
        }
      }
      const summary = document.createElement('summary');
      summary.innerHTML = thumbHtml + stmtName;
      details.appendChild(summary);

      // Expanded content
      const contentDiv = document.createElement('div');
      contentDiv.style.marginTop = '8px';
      contentDiv.style.fontFamily = 'sans-serif';

      // Decision rule statements: render quantities in a table with merged value/unit
      if (stmt.$ && stmt.$.refType && stmt.$.refType.includes('basic_decisionRule')) {
        const table = document.createElement('table');
        table.style.width = '100%';
        table.style.borderCollapse = 'collapse';
        // Header: Quantity, Value, Description
        const headerRow = document.createElement('tr');
        ['Quantity', 'Value', 'Description'].forEach(text => {
          const th = document.createElement('th');
          th.style.border = '1px solid #ccc';
          th.style.padding = '4px';
          th.textContent = text;
          headerRow.appendChild(th);
        });
        table.appendChild(headerRow);
        if (stmt['dcc:data'] && stmt['dcc:data']['dcc:quantity']) {
          let quantities = stmt['dcc:data']['dcc:quantity'];
          if (!Array.isArray(quantities)) quantities = [quantities];
          quantities.forEach(q => {
            const row = document.createElement('tr');
            // Quantity Name
            let qtyName = '';
            if (q['dcc:name'] && q['dcc:name']['dcc:content']) {
              const content = q['dcc:name']['dcc:content'];
              qtyName = Array.isArray(content)
                  ? (content.find(item => item.$ && item.$.lang === language) || content[0])._ || ''
                  : content._ || '';
            }
            // Value and Unit merged
            let value = (q['si:real'] && q['si:real']['si:value']) ||
                (q['si:realListXMLList'] && q['si:realListXMLList']['si:valueXMLList']) || '';
            let unit = '';
            if (q['si:real'] && q['si:real']['si:unit']) {
              unit = q['si:real']['si:unit'].trim();
            } else if (q['si:realListXMLList'] && q['si:realListXMLList']['si:unitXMLList']) {
              unit = q['si:realListXMLList']['si:unitXMLList'].trim();
            }
            const valueWithUnit = unit ? `${value} ${unit}` : value;
            // Description
            let description = '';
            if (q['dcc:description'] && q['dcc:description']['dcc:content']) {
              const desc = q['dcc:description']['dcc:content'];
              description = Array.isArray(desc)
                  ? (desc.find(item => item.$ && item.$.lang === language) || desc[0])._ || ''
                  : desc._ || '';
            }
            [qtyName, valueWithUnit, description].forEach(cellText => {
              const td = document.createElement('td');
              td.style.border = '1px solid #ccc';
              td.style.padding = '4px';
              td.textContent = cellText;
              row.appendChild(td);
            });
            table.appendChild(row);
          });
        }
        contentDiv.appendChild(table);
      } else {
        // For other statements, show declaration content (language-specific)
        let declText = '';
        if (stmt['dcc:declaration'] && stmt['dcc:declaration']['dcc:content']) {
          const decl = stmt['dcc:declaration']['dcc:content'];
          declText = Array.isArray(decl)
              ? (decl.find(c => c.$ && c.$.lang === language) || decl[0])._ || ''
              : decl._ || '';
        }
        contentDiv.innerHTML = declText;
      }
      details.appendChild(contentDiv);
      statementsContainer.appendChild(details);
    });
    container.appendChild(statementsContainer);
  }

  // ----- SOFTWARE SECTION -----
  if (adminData['dcc:dccSoftware'] && adminData['dcc:dccSoftware']['dcc:software']) {
    let softwares = adminData['dcc:dccSoftware']['dcc:software'];
    if (!Array.isArray(softwares)) softwares = [softwares];
    const softwareDiv = document.createElement('div');
    softwareDiv.style.border = '1px solid #ccc';
    softwareDiv.style.padding = '8px';
    softwareDiv.style.marginBottom = '20px';
    softwareDiv.innerHTML = '<strong>Used Software:</strong><br>';
    softwares.forEach(sw => {
      let swName = '';
      if (sw['dcc:name'] && sw['dcc:name']['dcc:content']) {
        const content = sw['dcc:name']['dcc:content'];
        swName = Array.isArray(content)
            ? (content.find(c => c.$ && c.$.lang === language) || content[0])._ || ''
            : content._ || '';
      }
      softwareDiv.innerHTML += `${swName} (Release: ${sw['dcc:release'] || ''}, Type: ${sw['dcc:type'] || ''})<br>`;
    });
    container.appendChild(softwareDiv);
  }
}

// Helper function to render a full address from a location/contact object
function renderAddress(addressObj) {
  let addressStr = '';
  // If the object has a 'dcc:location', use that; otherwise use the object directly.
  const loc = addressObj['dcc:location'] || addressObj;
  if (loc) {
    if (loc['dcc:street']) {
      addressStr += loc['dcc:street'] + ' ';
    }
    if (loc['dcc:streetNo']) {
      addressStr += loc['dcc:streetNo'] + '<br>';
    }
    if (loc['dcc:postCode']) {
      addressStr += loc['dcc:postCode'] + ' ';
    }
    if (loc['dcc:city']) {
      addressStr += loc['dcc:city'] + '<br>';
    }
    if (loc['dcc:countryCode']) {
      addressStr += loc['dcc:countryCode'] + '<br>';
    }
  }
  // Also add email/phone if present
  if (addressObj['dcc:eMail']) {
    addressStr += addressObj['dcc:eMail'] + '<br>';
  }
  if (addressObj['dcc:phone']) {
    addressStr += addressObj['dcc:phone'] + '<br>';
  }
  return addressStr;
}