Topola Genealogy Viewer
repository·master·Indexed 43 days ago
https://github.com/pewu/topola-viewerAn interactive, browser-based tool for visualizing genealogy data from GEDCOM files and ZIP archives (.gdz). It features high-performance charts, such as Hourglass and All Relatives, and supports exporting to PDF, PNG, and SVG. The application ensures privacy by processing files locally in the browser and can be deployed via Docker or static hosting. It includes integrations for WikiTree, a search index powered by lunr, and a Model Context Protocol (MCP) implementation for AI model interactions.
What's inside Topola Viewer
- Topola Genealogy Viewer is an interactive tool for viewing genealogy data using charts (such as Hourglass and All Relatives charts). It allows users to load standard GEDCOM files or ZIP archives containing media, provides a side panel for person details, and supports exporting trees to PDF, PNG, and SVG. The application runs entirely in the browser, ensuring privacy as files do not leave the user's computer.
Overview of Topola Viewer Source Structure
masterThe Topola Viewer source code is organized into several functional areas. Understanding this structure helps in locating specific logic for data loading, UI components, or utility functions:
Core Application Logic
app.tsx: The central component managing application state, routing, data loading orchestration, and the high-level layout.index.tsx: The application entry point responsible for polyfills, internationalization, and rendering the root.chart.tsx: The primary rendering engine for genealogy charts, utilizing D3 and thetopolalibrary. It manages user interactions like zoom, pan, and exporting.donatso-chart.tsx: An alternative chart view implementation using thefamily-chartlibrary.intro.tsx: The landing page displayed when no data is loaded, providing user instructions and privacy information.
Functional Subdirectories
datasource/: Contains adapters for loading data from various sources including GEDCOM files, URLs, WikiTree API, and embedded data.menu/: Handles navigation components, including the top bar, search bar, and data source menus (Upload, URL, WikiTree).sidepanel/: Manages the side panel used for displaying individual person details and chart configuration settings.translations/: Stores JSON-based language translations.util/: Provides shared utility functions for dates, GEDCOM processing, analytics, and responsive design.
AI Integration (WebMCP)
Topola Viewer includes a Model Context Protocol (MCP) implementation to allow AI models to interact with the viewer state and trigger actions (e.g., searching for persons or fetching ancestry details).
Explore the Side Panel directory structure
masterThe side panel features are organized into the following subdirectories:
config/: UI and logic for managing chart display settings.details/: Components for rendering the detailed view of an individual's data.head/: Components for displaying metadata from the GEDCOM file header.side-panel.tsx: The main React component that manages the layout, expansion/collapse states, and the tabbed interface.
Understand the Topola Genealogy Viewer project structure
masterThe Topola Genealogy Viewer project is organized into a central root directory that orchestrates configuration, build setup, and dependency management, while the core logic and assets reside in subdirectories.
Core Directories
src/: The application source code. Key modules include:src/datasource/: Data loading and transformation (files, URLs, WikiTree).src/menu/: Navigation and menu components.src/sidepanel/: Details and configuration side panel.src/translations/: Localization JSON files.src/util/: Utilities for dates, analytics, and data processing.
public/: Static assets served at the root path.tests/: End-to-end tests, includingtests/probers/for live smoke tests against deployed URLs.docs/: Technical and architectural design documents.
Understand the Side Panel Details components
masterThesrc/sidepanel/detailsdirectory contains the React components responsible for rendering detailed information about a selected individual (person) within the Topola Viewer side panel. These components consume data extracted from parsed GEDCOM files. The display is orchestrated by a main component that manages various sub-modules for names, images, events, facts, notes, and sources.Future Prober: WikiTree Authenticated Login Flow
masterA planned prober to test the authenticated WikiTree API path. This would involve logging in with an
authcodeto verify access to private profiles.Implementation Requirements:
- A dedicated test account on
wikitree.com. - The
authcodemust be stored as a GitHub Actions secret.
Note: This feature is currently deferred due to the complexity of secret management, authcode expiry, and test account maintenance.
- A dedicated test account on
Understand the Topola Viewer Docker Architecture
masterThe containerized Topola Viewer is designed to serve a client-side React application and genealogy data using a lightweight, secure architecture. It consists of three main components:
- The User's Web Browser (The App): Runs the single-page React application. All logic, chart rendering, and user interactions are executed locally in the browser.
- The Caddy Web Server (The Helper): A lightweight server inside the Docker container that serves the application files (HTML, CSS, JS) and the genealogy data. Caddy is responsible for dynamically injecting the family tree file path into the main HTML page on-the-fly based on container configuration.
- The Genealogy Data (The Data): The family tree file being served. You can provide:
- Unzipped File (
.ged): A standard plain-text GEDCOM file (best if you don't have local photos). - Zipped Archive (
.gdzor.zip): A compressed archive containing the.gedfile and photo assets. Topola Viewer automatically unzips these to map photos to the tree.
- Unzipped File (
How the Immediate Family Section works
masterThe Immediate Family Section is a dedicated layout block in the side panel designed to improve navigation efficiency. Instead of searching the graphical canvas for relatives, users can use this section to find clickable links for a selected person's parents, spouses, and children.
The feature operates through the interaction of three core components:
- Genealogy Data Store: Acts as the central repository for parsed individuals and family records. It provides the lookup utilities necessary to resolve relationships (e.g., linking children to parents or spouses).
- Immediate Family Component: A UI element in the side panel. It queries the Data Store for the currently selected person, extracts their primary parents, and groups children under their respective spouses or partners.
- Navigation Module: Handles user interaction. When a link (parent, spouse, or child) is clicked, this module updates the application's active web address with the relative's identifier, which re-centers both the side panel and the visual tree on that person.
This design ensures that even as family structures grow or users zoom in, primary relationships remain accessible at a glance.
Prober Test Selectors and Flow
masterProber tests follow a standardized flow using
data-testidattributes to ensure resilience against CSS or framework changes. The shared flow intests/probers/helpers.tsperforms the following steps:- Diagnostics: Registers listeners for console errors, page errors, and failed network requests to stdout.
- Navigation: Navigates to the target URL using
waitUntil: 'domcontentloaded'. - Content Readiness: Waits for
data-testid="content"to be visible (indicating theSHOWING_CHARTstate). - Chart Assertion: Asserts the expected name appears in
data-testid="chart"(the SVG text). - Side Panel Assertion: Asserts the expected name appears in
data-testid="details"(the side panel). - Error Checks: Asserts that
data-testid="error-message"anddata-testid="error-popup"are not visible.
Key Selectors:
data-testid="content": Main container.data-testid="chart": SVG group inside the chart.data-testid="details": Side panel Details tab content.data-testid="error-message": Fatal error message (.ui.error.message).data-testid="error-popup": Dismissable popup error (.ui.errorPopup.message).
Optimize CI/CD E2E testing workflows
masterTo avoid duplicating slow Playwright test execution during manual deployments (e.g., when
deploy-everywhere.ymltriggers bothdeploy-gh-pages.ymlanddeploy-wikitree-apps.ymlin parallel), restructure the GitHub Actions workflows.Recommended Pattern: Execute E2E validation once as a gating pre-deploy job using the
needskeyword, or rely strictly on the main merge-to-master CI pipeline validation to ensure deployments remain fast and lightweight.How Google Drive integration works in Topola Viewer
masterThe Google Drive integration allows users to view genealogy files (like
.gedand.gdz) stored in the cloud without manual downloads. The integration is designed as a read-only service that uses thedrive.filescope to ensure privacy and security, only accessing files explicitly selected by the user via the Google Picker.The integration relies on five core components:
- Google Drive Service: Manages the connection, loads Google libraries, handles the login popup, caches tokens, and opens the Google Picker.
- Google Drive Data Source: A registered data loader that uses the authorization token to download raw file content directly from Google's servers.
- App Router / Shell: Orchestrates the loading process by parsing URL parameters like
fileIdandsource=google-drive. - Access Authorization Modal: A fallback UI that appears when a user lacks permission for a shared file, guiding them through authentication and file selection.
- Google Drive Menu: A UI entry point in the menu bar for connecting Google accounts and browsing files.
Security and Privacy of Google Drive Integration
masterTopola Viewer uses a zero-server architecture for Google Drive integration to ensure genealogical data remains private.
Data Privacy Model
- Direct Communication: All requests to Google Drive APIs are made directly from the user's browser to Google. No data or access tokens are routed through Topola's servers or third-party CORS proxies.
- Local Parsing: Files (GEDCOM or GEDZIP) are parsed entirely within the browser. No family data is transmitted to external servers.
- Short-Lived Tokens: The app uses short-lived access tokens and does not request or store persistent refresh tokens.
- Session Storage Security: Parsed tree data is cached in
sessionStorageusing the key patterngoogle-drive:{fileId}. Signing out or disconnecting Google Drive purges allgoogle-drive:*keys fromsessionStorageto protect privacy on shared computers.
OAuth Scopes and Least Privilege
The integration uses the restrictive
drive.filescope rather than the broaddrive.readonlyscope. This means the application can only access files that the user explicitly opens with the app (e.g., via the Google Picker or the "Open with" menu).