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

Move DNA matches & chromosome browser to separate DNA view #568

Merged
merged 13 commits into from
Jan 26, 2025
17 changes: 16 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,20 @@
"Pending": "Pending",
"Started": "Started",
"Delete user": "Delete user",
"Do you really want to delete user \"%s\"?": "Do you really want to delete user \"%s\"?"
"Do you really want to delete user \"%s\"?": "Do you really want to delete user \"%s\"?",
"First person": "First person",
"Second person": "Second person",
"Raw match data": "Raw match data",
"Add new DNA match": "Add new DNA match",
"Paste the raw data in the field above to see the preview.": "Paste the raw data in the field above to see the preview.",
"Number of SNPs": "Number of SNPs",
"Side": "Side",
"Chromosome": "Chromosome",
"Start Position": "Start Position",
"End Position": "End Position",
"DNA Match": "DNA Match",
"DNA match with %s deleted.": "DNA match with %s deleted.",
"Paste text or drop a file here": "Paste text or drop a file here",
"No DNA matches found.": "No DNA matches found.",
"No DNA matches detected in the data provided.": "No DNA matches detected in the data provided."
}
18 changes: 17 additions & 1 deletion src/GrampsJs.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class GrampsJs extends LitElement {
_dbInfo: {type: Object},
_page: {type: String},
_pageId: {type: String},
_pageId2: {type: String},
_showShortcuts: {type: Boolean},
_shortcutPressed: {type: String},
_firstRunToken: {type: String},
Expand All @@ -95,6 +96,8 @@ export class GrampsJs extends LitElement {
this._dbInfo = {}
this._page = 'home'
this._pageId = ''
this._pageId2 = ''

this._showShortcuts = false
this._shortcutPressed = ''
this._firstRunToken = ''
Expand Down Expand Up @@ -523,6 +526,9 @@ export class GrampsJs extends LitElement {
<div>
<grampsjs-main-menu
.strings="${this._strings}"
.page="${this._page}"
.pageId="${this._pageId}"
.pageId2="${this._pageId2}"
?canViewPrivate="${this.canViewPrivate}"
?canUseChat="${this.canUseChat}"
></grampsjs-main-menu>
Expand All @@ -544,6 +550,7 @@ export class GrampsJs extends LitElement {
.settings="${this.settings}"
.page="${this._page}"
.pageId="${this._pageId}"
.pageId2="${this._pageId2}"
.canAdd="${this.canAdd}"
.canEdit="${this.canEdit}"
.canViewPrivate="${this.canViewPrivate}"
Expand Down Expand Up @@ -773,14 +780,18 @@ export class GrampsJs extends LitElement {
const pathId = path.slice(1)
const page = pathId.split('/')[0]
const pageId = pathId.split('/')[1]
const pageId2 = pathId.split('/')[2]
this._page = page
this._pageId = pageId || ''
this._pageId2 = pageId2 || ''
} else if (path.split('/')[0] === BASE_DIR.split('/')[0]) {
const pathId = path.slice(1)
const page = pathId.split('/')[1]
const pageId = pathId.split('/')[2]
const pageId2 = pathId.split('/')[3]
this._page = page
this._pageId = pageId || ''
this._pageId2 = pageId2 || ''
}

if (!this.wide) {
Expand Down Expand Up @@ -809,7 +820,12 @@ export class GrampsJs extends LitElement {
const {path} = e.detail
const page = path.split('/')[0]
const pageId = path.split('/')[1]
if (page !== this._page || pageId !== this._pageId) {
const pageId2 = path.split('/')[2]
if (
page !== this._page ||
pageId !== this._pageId ||
pageId2 !== this._pageId2
) {
const href = `${BASE_DIR}/${path}`
this._loadPage(href)
window.history.pushState({}, '', href)
Expand Down
10 changes: 10 additions & 0 deletions src/SharedStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const sharedStyles = css`
--md-sys-color-surface-container-highest: #fff;
--md-primary-tab-label-text-weight: 425;
--md-primary-tab-label-text-size: 16px;
--md-divider-thickness: 0px;
}

mwc-tab-bar {
Expand Down Expand Up @@ -350,6 +351,15 @@ export const sharedStyles = css`
color: rgb(125, 0, 0, 0.8);
}

md-outlined-text-field.drag-hover {
--md-outlined-text-field-outline-color: var(--mdc-theme-secondary);
--md-outlined-text-field-hover-outline-color: var(--mdc-theme-secondary);
--md-outlined-text-field-hover-outline-width: var(--mdc-theme-secondary);
--md-outlined-text-field-outline-width: var(--mdc-theme-secondary);
--md-outlined-text-field-input-text-color: rgba(0, 0, 0, 0.5);
--md-outlined-text-field-hover-input-text-color: rgba(0, 0, 0, 0.4);
}

@media (max-width: 768px) {
:host {
font-size: 16px;
Expand Down
61 changes: 49 additions & 12 deletions src/components/GrampsjsConnectedComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Base class for Components that fetch data when first loaded
import {LitElement} from 'lit'
import {GrampsjsTranslateMixin} from '../mixins/GrampsjsTranslateMixin.js'
import {sharedStyles} from '../SharedStyles.js'
import {apiGet} from '../api.js'
import {apiGet, apiPost} from '../api.js'
import {fireEvent} from '../util.js'

export class GrampsjsConnectedComponent extends GrampsjsTranslateMixin(
LitElement
Expand All @@ -23,6 +24,9 @@ export class GrampsjsConnectedComponent extends GrampsjsTranslateMixin(
_errorMessage: {type: String},
_data: {type: Object},
_oldUrl: {type: String},
method: {type: String},
postData: {type: Object},
_oldPostData: {type: Object},
}
}

Expand All @@ -37,6 +41,9 @@ export class GrampsjsConnectedComponent extends GrampsjsTranslateMixin(
this._oldUrl = ''
this._boundUpdateData = this._updateData.bind(this)
this._boundsHandleOnline = this._handleOnline.bind(this)
this.method = 'GET'
this.postData = {}
this._oldPostData = {}
}

render() {
Expand Down Expand Up @@ -68,31 +75,61 @@ export class GrampsjsConnectedComponent extends GrampsjsTranslateMixin(

update(changed) {
super.update(changed)
if (this.getUrl() !== this._oldUrl) {
if (this.method !== 'POST' && this.getUrl() !== this._oldUrl) {
this._updateData()
}
if (this.method === 'POST' && this.postData !== this._oldPostData) {
this._updateData()
}
}

_updateData(clearData = true) {
async _updateData(clearData = true) {
const url = this.getUrl()
this._oldUrl = url
this._oldPostData = this.postData
if (url === '') {
return
}
if (clearData) {
this._clearData()
}
this.loading = true
apiGet(url).then(data => {
this.loading = false
if ('data' in data) {
this._data = {data: data.data}
this.error = false
} else if ('error' in data) {
this.error = true
this._errorMessage = data.error
if (this.method === 'POST') {
if (Object.keys(this.postData).length > 0) {
await this._updatePostData(url)
}
})
} else {
await this._updateGetData(url)
}
this.loading = false
}

async _updateGetData(url) {
const data = await apiGet(url)
if ('data' in data) {
this._data = {data: data.data}
this.error = false
this._fireUpdateEvent()
} else if ('error' in data) {
this.error = true
this._errorMessage = data.error
}
}

async _updatePostData(url) {
const data = await apiPost(url, this.postData, true, false)
if ('data' in data) {
this._data = {data: data.data}
this.error = false
this._fireUpdateEvent()
} else if ('error' in data) {
this.error = true
this._errorMessage = data.error
}
}

_fireUpdateEvent() {
fireEvent(this, 'connected-component:updated', {data: this._data})
}

_clearData() {
Expand Down
41 changes: 41 additions & 0 deletions src/components/GrampsjsConnectedDnaMatchTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {html} from 'lit'

import '@material/mwc-circular-progress'

import './GrampsjsDnaMatchTable.js'
import {GrampsjsConnectedComponent} from './GrampsjsConnectedComponent.js'

class GrampsjsConnectedDnaMatchTable extends GrampsjsConnectedComponent {
constructor() {
super()
this.method = 'POST'
}

renderContent() {
return html`
<grampsjs-dna-match-table
.strings="${this.strings}"
.segments="${this._data.data}"
></grampsjs-dna-match-table>
`
}

// eslint-disable-next-line class-methods-use-this
renderLoading() {
return html`<mwc-circular-progress
indeterminate
density="-7"
open
></mwc-circular-progress>`
}

// eslint-disable-next-line class-methods-use-this
getUrl() {
return `/api/parsers/dna-match`
}
}

window.customElements.define(
'grampsjs-connected-dna-match-table',
GrampsjsConnectedDnaMatchTable
)
85 changes: 85 additions & 0 deletions src/components/GrampsjsDnaMatch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {html, LitElement, css} from 'lit'
import {mdiArrowLeft} from '@mdi/js'

import {GrampsjsTranslateMixin} from '../mixins/GrampsjsTranslateMixin.js'
import {sharedStyles} from '../SharedStyles.js'
import './GrampsjsDnaMatchTable.js'
import './GrampsjsFormEditMatch.js'
import {personDisplayName, fireEvent} from '../util.js'
import {renderIconSvg} from '../icons.js'

export class GrampsjsDnaMatch extends GrampsjsTranslateMixin(LitElement) {
static get styles() {
return [
sharedStyles,
css`
.container {
margin-top: 40px;
}
`,
]
}

static get properties() {
return {
data: {type: Object},
person: {type: Object},
personMatch: {type: Object},
edit: {type: Boolean},
}
}

constructor() {
super()
this.data = {}
this.person = {}
this.personMatch = {}
this.edit = false
}

render() {
if (Object.keys(this.data).length === 0) {
return ''
}
return html`
<h4>
${this._('DNA Match')}:
<a href="/person/${this.person.gramps_id}"
>${personDisplayName(this.person)}</a
>
&amp;
<a href="/person/${this.personMatch.gramps_id}"
>${personDisplayName(this.personMatch)}</a
>
</h4>

${this.edit
? html`
<grampsjs-form-edit-match
.strings="${this.strings}"
@object:save="${this._handleSaveMatch}"
.data="${this.data}"
></grampsjs-form-edit-match>
`
: html`
<grampsjs-dna-match-table
.strings="${this.strings}"
.segments="${this.data.segments}"
></grampsjs-dna-match-table>
`}

<div class="container">
<md-icon-button @click="${this.handleBackToAllMatches}">
<md-icon>${renderIconSvg(mdiArrowLeft, '#666')}</md-icon>
</md-icon-button>
</div>
`
}

handleBackToAllMatches() {
const path = `dna-matches/${this.person.gramps_id}`
fireEvent(this, 'nav', {path})
}
}

window.customElements.define('grampsjs-dna-match', GrampsjsDnaMatch)
Loading
Loading