denshoproject / sites-of-shame-app

1 stars 0 forks source link

ui: Add individual bios to "Family Journeys" ui #220

Closed GeoffFroh closed 2 years ago

GeoffFroh commented 2 years ago

Current behavior: The app does not display an individual bio for each person in a Family Journey except as a popup triggered by clicking a journey line in the map UI when that individual's family layer is activated. This allows for a short description of the particular journey event, but not an overarching bio for that individual.

Desired behavior: Each individual listed in the "Family Journeys" component of the legend ui would have an info button similar to those in the "Facilities" list. Pressing that button would trigger an info popup with bio information that could include text and links to DDR/Encyclopedia content.

The journey line popup in the map UI would display the individual name, the family name, the place name they came from and the place name they went to. (see issue#221)

Technical overview: Family Journeys data is loaded on the client-side on app startup from the family-journeys.csv file (/public/data/family-journeys.csv). The data contained in each row is a single step in an individual journey. At runtime, the FamilyLayer component (/src/components/layers/FamilyLayer.js) loads the csv into an object that is consumed by theFamilyIndividual.js` component when the legend/layer-selector UI is loaded.

The infobox button content is loaded from a separate csv (/public/data/infoboxes.csv) based on a matching id attribute.

Not all people have bios in infoboxes.csv, which means that the infobox button will appear, but there won't be associated data in infoboxes.csv. The lightest-weight approach from the runtime perspective is to have a boolean value in the family-journeys.csv dataset that indicates whether there's an individual bio or not. The downside is additional, redundant data in family-journeys.csv and the need to update it when a bio is added/removed.

(It would also be possible to infer that attribute at runtime by examining the infoboxes.csv file in the FamilyLayer.js code, but this would be expensive.)

Possible solution:

  1. Add rows for each individual bio with an id value that matches the person_id in the family-journeys.csv file.
  2. Add has_bio column to infoboxes.csv. If the person has an individual bio, the value is 1; no bio, the value is 0
  3. Get person_id from family_journeys.csv; add to individuals object between line 31 and 32 of FamilyIndividuals.js
    return individualIds
      .map((individual) => {
        const name = byIndividual.get(individual)[0].person_name;
        const color =
          colorScheme.filter(({ personId }) => personId === individual)[0]
            ?.color ?? null;
        const personId = byIndividual.get(individual)[0].person_id;
        const hasBio = byIndividual.get(individual)[0].has_bio;
        return { name, color, personId, hasBio };
      })
  1. Add infobox button to UI between line 51 and 56 in FamilyIndividual.js:
      <ol className="individual-list">
        {individuals.map(({ name, color, personId, hasBio }) => (
          <li key={name}>
            <FamilyLegendRectangle color={color} />
            {name}
            {hasBio ? (
              <InfoboxButton id={personId} clickedId={personId} />
            ) : null}
          </li>
        ))}
      </ol>
GeoffFroh commented 2 years ago

Implemented in 08f637277e5f599c2914d83deb78cc6bd1e8bb4e

(Requires data schema change in densho-sites-of-shame-data; see: https://github.com/denshoproject/densho-sites-of-shame-data/issues/1)