Spreadsheet-UX op een echte relationele engine

main

Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.

2.3 kB Ruw bestand
import { type ReactNode } from 'react';
import { formatCell, type Row, type TableMeta } from '@wellformed/shared';
import { LINK_OPTION_LIMIT } from '../api/hooks';
import { useI18n } from '../i18n';
import { useCurrency } from '../state/session';
import { Modal } from './Modal';

interface RecordPanelProps {
  table: TableMeta;
  /** Undefined when the row falls outside the link options already loaded. */
  row: Row | undefined;
  onClose(): void;
  onOpenTable(): void;
}

/**
 * The far side of a link, without leaving the row you are reading.
 *
 * Everything shown here is already in the client — `useLinkTargets` loads the
 * target rows so link cells can offer them — so following a relation costs no
 * request.
 */
export function RecordPanel({ table, row, onClose, onOpenTable }: RecordPanelProps): ReactNode {
  const currency = useCurrency();
  const { t, locale } = useI18n();

  return (
    <Modal
      title={row ? describe(row, table) : table.label}
      onClose={onClose}
      footer={
        <>
          <button className="btn" onClick={onClose}>
            {t('common.close')}
          </button>
          <button className="btn primary" onClick={onOpenTable}>
            {t('grid.openInTable', table.label)}
          </button>
        </>
      }
    >
      <div className="mb">
        {!row ? (
          <p className="hint" style={{ margin: 0 }}>
            {t('grid.linkRowNotLoaded', LINK_OPTION_LIMIT, table.label, locale)}
          </p>
        ) : (
          <div className="record">
            {table.columns.map((col) => {
              const text = formatCell(row.values[col.name] ?? null, col, {
                label: row.labels[col.name],
                currency,
                locale,
              });
              return (
                <div className="record-row" key={col.name}>
                  <span className="k">{col.label}</span>
                  <span className="v">{text === '' ? '—' : text}</span>
                </div>
              );
            })}
          </div>
        )}
      </div>
    </Modal>
  );
}

function describe(row: Row, table: TableMeta): string {
  if (!table.display) return row.id;
  const value = row.values[table.display];
  return value === null || value === undefined || value === '' ? row.id : String(value);
}