Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,31 @@
<mat-icon svgIcon="delete_forever"></mat-icon>
</button>
</div>
<div class = "sites" *ngFor = "let site of link.sites;index as index">
<mat-form-field class="site">
<mat-label>{{index === 0? 'To': 'From'}}</mat-label>
<mat-select [formControlName] = "'site'+index" (selectionChange)="updateSuggestions($event.value, index) " class ="site-select" >
<div class="sites" *ngFor="let site of link.sites; index as index">
<mat-form-field class="site">
<mat-label>{{ index === 0 ? "To" : "From" }}</mat-label>
<mat-select
[formControlName]="'site' + index"
[compareWith]="compareSites"
(selectionChange)="updateSuggestions($event.value, index)"
class="site-select"
>
<mat-option *ngFor="let cys of cysteine" [value]="cys">
{{cys.subunitIndex}}_{{cys.residueIndex}}
{{ cys.subunitIndex }}_{{ cys.residueIndex }}
</mat-option>
<mat-option [value] = "site" >
{{site.subunitIndex}}_{{site.residueIndex}}
<mat-option [value]="site">
{{ site.subunitIndex }}_{{ site.residueIndex }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-form-field>
</div>

<button mat-icon-button matTooltip="Select from sequence view" (click)="openDialog()">
<button
mat-icon-button
matTooltip="Select from sequence view"
(click)="openDialog()"
>
<mat-icon svgIcon="edit"></mat-icon>
</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
import {AfterViewInit, Component, EventEmitter, Input, OnDestroy, OnInit, Output} from '@angular/core';
import {Link, Site} from '@gsrs-core/substance';
import { SubstanceFormDisulfideLinksService } from './substance-form-disulfide-links.service';
import {UtilsService} from '@gsrs-core/utils';
import {ControlledVocabularyService} from '@gsrs-core/controlled-vocabulary';
import {MatDialog} from '@angular/material/dialog';
import {OverlayContainer} from '@angular/cdk/overlay';
import {Subscription} from 'rxjs';
import {SubstanceFormService} from '@gsrs-core/substance-form/substance-form.service';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {SubunitSelectorDialogComponent} from '@gsrs-core/substance-form/subunit-selector-dialog/subunit-selector-dialog.component';
import {
AfterViewInit,
Component,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
} from "@angular/core";
import { Link, Site } from "@gsrs-core/substance";
import { SubstanceFormDisulfideLinksService } from "./substance-form-disulfide-links.service";
import { UtilsService } from "@gsrs-core/utils";
import { ControlledVocabularyService } from "@gsrs-core/controlled-vocabulary";
import { MatDialog } from "@angular/material/dialog";
import { OverlayContainer } from "@angular/cdk/overlay";
import { Subscription } from "rxjs";
import { SubstanceFormService } from "@gsrs-core/substance-form/substance-form.service";
import { FormControl, FormGroup, Validators } from "@angular/forms";
import { SubunitSelectorDialogComponent } from "@gsrs-core/substance-form/subunit-selector-dialog/subunit-selector-dialog.component";

@Component({
selector: 'app-disulfide-links-form',
templateUrl: './disulfide-links-form.component.html',
styleUrls: ['./disulfide-links-form.component.scss'],
standalone: false
selector: "app-disulfide-links-form",
templateUrl: "./disulfide-links-form.component.html",
styleUrls: ["./disulfide-links-form.component.scss"],
standalone: false,
})
export class DisulfideLinksFormComponent implements OnInit, AfterViewInit, OnDestroy {

export class DisulfideLinksFormComponent
implements OnInit, AfterViewInit, OnDestroy
{
private privateLink: Link;
public cysteine: Array<Site> = [];
@Output() linkDeleted = new EventEmitter<Link>();
deleteTimer: any;
testForm = new FormGroup({
site0: new FormControl('', [
Validators.required
]),
site1: new FormControl('', [
Validators.required
]),
site0: new FormControl<Site | null>(null, [Validators.required]),
site1: new FormControl<Site | null>(null, [Validators.required]),
});
private subscriptions: Array<Subscription> = [];
private overlayContainer: HTMLElement;
Expand All @@ -39,29 +44,32 @@ export class DisulfideLinksFormComponent implements OnInit, AfterViewInit, OnDes
private utilsService: UtilsService,
private overlayContainerService: OverlayContainer,
private substanceFormService: SubstanceFormService,
private substanceFormDisulfideLinksService: SubstanceFormDisulfideLinksService
) { }
private substanceFormDisulfideLinksService: SubstanceFormDisulfideLinksService,
) {}

ngOnInit() {
if (this.privateLink.sites) {
this.testForm.controls['site0'].setValue(this.privateLink.sites[0].toString());
this.testForm.controls['site1'].setValue(this.privateLink.sites[1].toString());
this.testForm.controls["site0"].setValue(this.privateLink.sites[0]);
this.testForm.controls["site1"].setValue(this.privateLink.sites[1]);
} else {
this.privateLink.sites = [{}, {}];
}
this.overlayContainer = this.overlayContainerService.getContainerElement();
}
ngAfterViewInit() {
setTimeout(() => {
const cysteineSubscription = this.substanceFormDisulfideLinksService.substanceCysteineSites.subscribe(cysteine => {
this.cysteine = cysteine;
});
this.subscriptions.push(cysteineSubscription);
});
ngAfterViewInit() {
setTimeout(() => {
const cysteineSubscription =
this.substanceFormDisulfideLinksService.substanceCysteineSites.subscribe(
(cysteine) => {
this.cysteine = cysteine;
},
);
this.subscriptions.push(cysteineSubscription);
});
}

ngOnDestroy() {
this.subscriptions.forEach(subscription => {
this.subscriptions.forEach((subscription) => {
subscription.unsubscribe();
});
}
Expand All @@ -76,14 +84,14 @@ export class DisulfideLinksFormComponent implements OnInit, AfterViewInit, OnDes
}

deleteLink(): void {
if (confirm('Are you sure you want to delete links?')) {
this.privateLink.$$deletedCode = this.utilsService.newUUID();
// if (!this.privateLink) {
if (confirm("Are you sure you want to delete links?")) {
this.privateLink.$$deletedCode = this.utilsService.newUUID();
// if (!this.privateLink) {
this.deleteTimer = setTimeout(() => {
this.linkDeleted.emit(this.link);
}, 1000);
// }
this.substanceFormDisulfideLinksService.emitDisulfideLinkUpdate();
// }
this.substanceFormDisulfideLinksService.emitDisulfideLinkUpdate();
}
}

Expand All @@ -98,8 +106,11 @@ export class DisulfideLinksFormComponent implements OnInit, AfterViewInit, OnDes
}

updateSuggestions(value: Site, pos: number): void {
this.cysteine = this.cysteine.filter(function(r) {
return (r.residueIndex !== value.residueIndex) || (r.subunitIndex !== value.subunitIndex);
this.cysteine = this.cysteine.filter(function (r) {
return (
r.residueIndex !== value.residueIndex ||
r.subunitIndex !== value.subunitIndex
);
});
if (this.privateLink.sites[pos] !== value) {
if (this.privateLink.sites[pos].residueIndex) {
Expand All @@ -109,7 +120,7 @@ export class DisulfideLinksFormComponent implements OnInit, AfterViewInit, OnDes
this.substanceFormDisulfideLinksService.updateCysteine(this.cysteine);
} else {
}
this.testForm.controls['site' + pos].setValue(value);
this.testForm.controls["site" + pos].setValue(value);
}

openDialog(): void {
Expand All @@ -118,33 +129,42 @@ export class DisulfideLinksFormComponent implements OnInit, AfterViewInit, OnDes
sentSites = [];
}
const dialogRef = this.dialog.open(SubunitSelectorDialogComponent, {
data: {'card': 'disulfide', 'link': sentSites},
width: '1040px',
panelClass: 'subunit-dialog'
data: { card: "disulfide", link: sentSites },
width: "1040px",
panelClass: "subunit-dialog",
});
this.overlayContainer.style.zIndex = '1002';
this.overlayContainer.style.zIndex = "1002";

const dialogSubscription = dialogRef.afterClosed().subscribe(newLinks => {
const dialogSubscription = dialogRef.afterClosed().subscribe((newLinks) => {
this.overlayContainer.style.zIndex = null;
if (newLinks) {
if (newLinks[0] && newLinks[0].subunitIndex) {
this.privateLink.sites[0] = newLinks[0];
this.testForm.controls['site0'].setValue(this.privateLink.sites[0].toString());
this.testForm.controls["site0"].setValue(this.privateLink.sites[0]);
} else {
this.privateLink.sites[0] = {};
this.testForm.controls['site0'].reset();
this.testForm.controls["site0"].reset();
}
if (newLinks[1] && newLinks[1].subunitIndex) {
this.privateLink.sites[1] = newLinks[1];
this.testForm.controls['site1'].setValue(this.privateLink.sites[1].toString());
this.testForm.controls["site1"].setValue(this.privateLink.sites[1]);
} else {
this.privateLink.sites[1] = {};
this.testForm.controls['site1'].reset();
this.testForm.controls["site1"].reset();
}
}
this.substanceFormDisulfideLinksService.emitDisulfideLinkUpdate();
});
this.subscriptions.push(dialogSubscription);
}

compareSites = (a: Site | null, b: Site | null): boolean => {
if (!a || !b) {
return a === b;
}

return (
a.subunitIndex === b.subunitIndex && a.residueIndex === b.residueIndex
);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,28 @@ export class SubstanceFormDisulfideLinksCardComponent extends SubstanceCardBaseF
}

ngAfterViewInit() {
const disulfideLinksSubscription = this.substanceFormDisulfideLinksService.substanceDisulfideLinks.subscribe(disulfideLinks => {
this.disulfideLinks = disulfideLinks;
this.countCysteine();
});
// setTimeout defers subscriptions until after the service's unload/init setTimeout callbacks
// have fired. This prevents subscribing to a propertyEmitter that is about to be completed
// and replaced by unloadSubstance(), which would leave the component with a dead subscription.
setTimeout(() => {
const disulfideLinksSubscription = this.substanceFormDisulfideLinksService.substanceDisulfideLinks.subscribe(disulfideLinks => {
this.disulfideLinks = disulfideLinks;
this.countCysteine();
});
this.subscriptions.push(disulfideLinksSubscription);

this.subscriptions.push(disulfideLinksSubscription);
const subunitsSubscription = this.substanceFormService.substanceSubunits.subscribe(subunits => {
this.subunits = subunits;
this.countCysteine();
});
this.subscriptions.push(subunitsSubscription);
const cysteineSubscription = this.substanceFormDisulfideLinksService.substanceCysteineSites.subscribe(cysteine => {
this.cysteine = cysteine;
this.countCysteine();
const subunitsSubscription = this.substanceFormService.substanceSubunits.subscribe(subunits => {
this.subunits = subunits;
this.countCysteine();
});
this.subscriptions.push(subunitsSubscription);

const cysteineSubscription = this.substanceFormDisulfideLinksService.substanceCysteineSites.subscribe(cysteine => {
this.cysteine = cysteine;
this.countCysteine();
});
this.subscriptions.push(cysteineSubscription);
});
this.subscriptions.push(cysteineSubscription);
}

ngOnDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
}

.mat-tab-style {
:host ::ng-deep .mat-mdc-tab .mdc-tab__text-label,
.mat-tab-labels, .mat-tab-label, .mat-tab-link {
color: var(--regular-blue-color);
color: var(--regular-blue-color);
}
}

:host ::ng-deep .mat-mdc-tab-list .mat-mdc-tab,
:host ::ng-deep .mat-tab-list .mat-tab-label {
flex-grow: 0 !important;
flex-shrink: 0 !important;
}

.bordergray {
Expand Down
6 changes: 4 additions & 2 deletions src/styles/_material-overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1332,10 +1332,12 @@ button.export-button {
0px 3px 14px 2px rgba(0, 0, 0, 0.12);
}

// Override MDC ripple behavior if it interferes with existing styles
// Override MDC ripple behavior if it interferes with existing styles.
// NOTE: .mat-ripple is intentionally excluded — MatRipple directive adds that class
// to its HOST element (e.g. the pagination <button> itself), so pointer-events: none
// on it would make interactive elements unclickable (e.g. mat-tab-header pagination arrows).
.mat-mdc-button-ripple,
.mat-mdc-icon-button-ripple,
.mat-ripple,
.mat-mdc-button-persistent-ripple {
position: absolute;
pointer-events: none;
Expand Down
Loading