Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topola Viewer integration (#347) #414

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/GrampsJs.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import './views/GrampsjsViewRecent.js'
import './views/GrampsjsViewBookmarks.js'
import './views/GrampsjsViewMap.js'
import './views/GrampsjsViewTree.js'
import './views/GrampsjsViewTopola.js'
import './views/GrampsjsViewNewPerson.js'
import './views/GrampsjsViewNewFamily.js'
import './views/GrampsjsViewNewEvent.js'
Expand Down Expand Up @@ -554,6 +555,10 @@ export class GrampsJs extends LitElement {
<span>${this._('Family Tree')}</span>
<mwc-icon slot="graphic">${renderIcon(mdiFamilyTree)}</mwc-icon>
</grampsjs-list-item>
<grampsjs-list-item href="${BASE_DIR}/topola" graphic="icon">
<span>${this._('Interactive Tree')}</span>
<mwc-icon slot="graphic">${renderIcon(mdiFamilyTree)}</mwc-icon>
</grampsjs-list-item>
<li divider padded role="separator"></li>
<grampsjs-list-item href="${BASE_DIR}/recent" graphic="icon">
<span>${this._('History')}</span>
Expand Down Expand Up @@ -675,6 +680,13 @@ export class GrampsJs extends LitElement {
.strings="${this._strings}"
.settings="${this.settings}"
></grampsjs-view-tree>
<grampsjs-view-topola
class="page"
?active=${this._page === 'topola'}
grampsId="${this.settings.homePerson}"
.strings="${this._strings}"
.settings="${this.settings}"
></grampsjs-view-topola>
<grampsjs-view-person
class="page"
?active=${this._page === 'person'}
Expand Down
112 changes: 112 additions & 0 deletions src/views/GrampsjsViewTopola.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {css, html} from 'lit'

import {GrampsjsView} from './GrampsjsView.js'
import {getExporterDownloadUrl} from '../api.js'

/**
* Gramps Web View displaying the Topola Viewer.
*
* Topola Viewer is loaded from the official deployment at
* https://pewu.github.io/topola-viewer and displayed in an iframe.
*
* Data is loaded from the Gramps Web API as a full GEDCOM file and is passed
* to Topola Viewer using JS messaging between iframes. The GEDCOM file is
* generated and passed only once. Navigating away from the Topola tab and back
* does not cause the GEDCOM file to be regenerated. This means that edits will
* not be visible in Topola Viewer without reloading the page.
* No data is sent to any Topola Viewer server (it's a statically serverd app
* without a backend), all communication with Topola Viewer happens inside the
* browser.
*
* The home person is passed to Topola Viewer in the iframe URL.
*/
export class GrampsjsViewTopola extends GrampsjsView {
static get styles() {
return [
super.styles,
css`
:host {
margin: 0;
margin-top: -4px;
}
`,
]
}

static get properties() {
return {
grampsId: {type: String},
}
}

constructor() {
super()
/** Gramps Web home person */
this.grampsId = ''
/** Set to true when the iframe reports to be ready. */
this.ready = false
/** The GEDCOM file loaded from the Gramps Web API. */
this.gedcom = null
}

renderContent() {
const indiParam = this.grampsId ? `&indi=${this.grampsId}` : ''
return html`<iframe

Check failure on line 54 in src/views/GrampsjsViewTopola.js

View workflow job for this annotation

GitHub Actions / test

<iframe> elements must have a unique title property
id="topolaFrame"
style="width: calc(100vw - 234px); height: calc(100vh - 72px);"
src="https://pewu.github.io/topola-viewer/#/view?utm_source=grampsweb&embedded=true${indiParam}"

Check failure on line 57 in src/views/GrampsjsViewTopola.js

View workflow job for this annotation

GitHub Actions / test

Attribute values may not contain unencoded HTML entities, e.g. use `&gt;` instead of `>`
></iframe>`
}

/** Initializes communication with the iframe. */
async firstUpdated() {
window.addEventListener('message', this._onMessage.bind(this))

const url = '/api/exporters/ged/file'
const downloadUrl = getExporterDownloadUrl(url)
const response = await fetch(downloadUrl)
const gedcom = await response.text()
this.gedcom = gedcom
this._maybeSendData()
}

/** Handles incoming messages. */
_onMessage(message) {
if (message.data.message === 'ready') {
this.ready = true
this._maybeSendData()
}
}

/**
* Sends data to the iframe when both the iframe is ready and the data is
* present.
*/
_maybeSendData() {
if (!this.ready || !this.gedcom) {
return
}
const frame = this.shadowRoot.getElementById('topolaFrame')
frame.contentWindow.postMessage(
{message: 'gedcom', gedcom: this.gedcom},
'*'
)
}

/** Registers listening for home person changes. */
connectedCallback() {
super.connectedCallback()
window.addEventListener(
'pedigree:person-selected',
this._selectPerson.bind(this)
)
}

/** Sets the home person based on a received event. */
async _selectPerson(event) {
const {grampsId} = event.detail
this.grampsId = grampsId
}
}

window.customElements.define('grampsjs-view-topola', GrampsjsViewTopola)
Loading