pdbe-molstar
Version:
Molstar implementation for PDBe
176 lines (175 loc) • 12.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AnnotationsComponentControls = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const behavior_1 = require("molstar/lib/extensions/pdbe/structure-quality-report/behavior");
const color_1 = require("molstar/lib/extensions/pdbe/structure-quality-report/color");
const prop_1 = require("molstar/lib/extensions/pdbe/structure-quality-report/prop");
const hierarchy_1 = require("molstar/lib/mol-plugin-state/manager/structure/hierarchy");
const base_1 = require("molstar/lib/mol-plugin-ui/base");
const common_1 = require("molstar/lib/mol-plugin-ui/controls/common");
const icons_1 = require("molstar/lib/mol-plugin-ui/controls/icons");
const mol_state_1 = require("molstar/lib/mol-state");
const param_definition_1 = require("molstar/lib/mol-util/param-definition");
const behavior_2 = require("../domain-annotations/behavior");
const color_2 = require("../domain-annotations/color");
const prop_2 = require("../domain-annotations/prop");
const plugin_custom_state_1 = require("../plugin-custom-state");
const annotation_row_controls_1 = require("./annotation-row-controls");
const icons_2 = require("./icons");
const symmetry_annotation_controls_1 = require("./symmetry-annotation-controls");
class AnnotationsComponentControls extends base_1.PurePluginUIComponent {
constructor() {
super(...arguments);
this.state = {
isCollapsed: false,
validationApplied: false,
validationParams: undefined,
domainsApplied: false,
domainsParams: undefined,
showSymmetryAnnotation: false,
};
this.initOptionParams = () => {
var _a;
const initParams = (0, plugin_custom_state_1.PluginCustomState)(this.plugin).initParams;
const validationAnnotationCtrl = !!(initParams === null || initParams === void 0 ? void 0 : initParams.validationAnnotation);
const domainAnnotationCtrl = !!(initParams === null || initParams === void 0 ? void 0 : initParams.domainAnnotation);
const symmetryAnnotationCtrl = !!(initParams === null || initParams === void 0 ? void 0 : initParams.symmetryAnnotation) && (0, symmetry_annotation_controls_1.isAssemblySymmetryAnnotationApplicable)(this.plugin);
this.setState({ showSymmetryAnnotation: symmetryAnnotationCtrl });
const structure = (_a = this.getStructure()) === null || _a === void 0 ? void 0 : _a.data;
if (!structure)
return;
const themeDataCtx = { structure };
if (validationAnnotationCtrl) {
const validationActionsParams = color_1.StructureQualityReportColorThemeProvider.getParams(themeDataCtx);
this.setState(old => {
var _a, _b;
return ({
validationParams: {
params: validationActionsParams,
values: (_b = (_a = old.validationParams) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : param_definition_1.ParamDefinition.getDefaultValues(validationActionsParams),
},
});
}); // TODO maybe try way to skip render on non-changed params?
}
if (domainAnnotationCtrl) {
const domainActionsParams = color_2.DomainAnnotationsColorThemeProvider.getParams(themeDataCtx);
let updateProps; // this is to force props to change once custom property has been loaded and params have changed
this.setState(old => {
var _a, _b;
if (old.domainsParams && old.domainsParams.params.source.defaultValue.name !== domainActionsParams.source.defaultValue.name) {
updateProps = param_definition_1.ParamDefinition.getDefaultValues(domainActionsParams);
}
return {
domainsParams: {
params: domainActionsParams,
values: (_b = (_a = old.domainsParams) === null || _a === void 0 ? void 0 : _a.values) !== null && _b !== void 0 ? _b : param_definition_1.ParamDefinition.getDefaultValues(domainActionsParams),
},
};
}, () => { if (updateProps)
this.updateDomainParams(updateProps); });
}
};
this.getStructure = () => {
var _a;
const groupRef = mol_state_1.StateSelection.findTagInSubtree(this.plugin.state.data.tree, mol_state_1.StateTransform.RootRef, 'structure-component-static-polymer');
return groupRef ? (_a = this.plugin.state.data.select(groupRef)[0]) === null || _a === void 0 ? void 0 : _a.obj : undefined;
};
this.toggleCollapsed = () => {
this.setState({ isCollapsed: !this.state.isCollapsed });
};
this.applyAnnotation = (type, visibleState, params) => {
// Defaults
let themeName = 'chain-id';
let themePropsToAdd = behavior_1.PDBeStructureQualityReport;
let themePropsToRemove = this.state.domainsParams ? behavior_2.PDBeDomainAnnotations : undefined;
// Set Theme Params
if (type === 'validation') {
if (visibleState)
themeName = color_1.StructureQualityReportColorThemeProvider.name;
this.setState({ validationApplied: visibleState });
this.setState({ domainsApplied: false });
}
else if (type === 'domains') {
themePropsToAdd = behavior_2.PDBeDomainAnnotations;
themePropsToRemove = this.state.validationParams ? behavior_1.PDBeStructureQualityReport : undefined;
if (visibleState)
themeName = color_2.DomainAnnotationsColorThemeProvider.name;
this.setState({ domainsApplied: visibleState });
this.setState({ validationApplied: false });
}
// Update Tooltip
if (visibleState && themeName !== 'chain-id') {
const addTooltipUpdate = this.plugin.state.behaviors.build().to(themePropsToAdd.id).update(themePropsToAdd, (old) => { old.showTooltip = true; });
this.plugin.runTask(this.plugin.state.behaviors.updateTree(addTooltipUpdate));
if (themePropsToRemove) {
const removeTooltipUpdate = this.plugin.state.behaviors.build().to(themePropsToRemove.id).update(themePropsToRemove, (old) => { old.showTooltip = false; });
this.plugin.runTask(this.plugin.state.behaviors.updateTree(removeTooltipUpdate));
}
}
let polymerGroup;
const componentGroups = this.plugin.managers.structure.hierarchy.currentComponentGroups;
componentGroups.forEach(compGrp => {
if (compGrp[0].key === 'structure-component-static-polymer')
polymerGroup = compGrp;
});
if (polymerGroup) {
this.plugin.managers.structure.component.updateRepresentationsTheme(polymerGroup, { color: themeName, colorParams: params });
}
};
this.toggleAnnotation = (type) => {
var _a, _b;
if (type === 'validation')
this.applyAnnotation('validation', !this.state.validationApplied, (_a = this.state.validationParams) === null || _a === void 0 ? void 0 : _a.values);
if (type === 'domains')
this.applyAnnotation('domains', !this.state.domainsApplied, (_b = this.state.domainsParams) === null || _b === void 0 ? void 0 : _b.values);
};
this.updateValidationParams = (values) => {
if (!this.state.validationParams)
return;
const updatedParams = Object.assign({}, this.state.validationParams);
updatedParams.values = values;
this.setState({ validationParams: updatedParams });
if (this.state.validationApplied)
this.applyAnnotation('validation', this.state.validationApplied, values);
};
this.updateDomainParams = (values) => {
if (!this.state.domainsParams)
return;
if (values) {
const updatedParams = Object.assign(Object.assign({}, this.state.domainsParams), { values });
this.setState({ domainsParams: updatedParams });
}
else {
values = this.state.domainsParams.values;
}
if (this.state.domainsApplied)
this.applyAnnotation('domains', this.state.domainsApplied, values);
};
}
componentDidMount() {
const initParams = (0, plugin_custom_state_1.PluginCustomState)(this.plugin).initParams;
if (!(initParams === null || initParams === void 0 ? void 0 : initParams.validationAnnotation) && !(initParams === null || initParams === void 0 ? void 0 : initParams.domainAnnotation) && !(initParams === null || initParams === void 0 ? void 0 : initParams.symmetryAnnotation))
return;
this.subscribe(this.plugin.managers.structure.hierarchy.behaviors.selection, () => {
this.initOptionParams();
this.setState({ description: hierarchy_1.StructureHierarchyManager.getSelectedStructuresDescription(this.plugin) });
});
}
render() {
var _a, _b;
if (!this.state.validationParams && !this.state.domainsParams && !this.state.showSymmetryAnnotation)
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {});
const brand = { accent: 'green', svg: icons_2.TextsmsOutlinedSvg };
const wrapClass = this.state.isCollapsed
? 'msp-transform-wrapper msp-transform-wrapper-collapsed'
: 'msp-transform-wrapper';
const validationDataReady = (_a = this.getStructure()) === null || _a === void 0 ? void 0 : _a.data.model.customProperties.has(prop_1.StructureQualityReportProvider.descriptor);
const domainDataReady = (_b = this.getStructure()) === null || _b === void 0 ? void 0 : _b.data.model.customProperties.has(prop_2.DomainAnnotationsProvider.descriptor);
return (0, jsx_runtime_1.jsxs)("div", { className: wrapClass, children: [(0, jsx_runtime_1.jsx)("div", { className: 'msp-transform-header', children: (0, jsx_runtime_1.jsxs)(common_1.Button, { icon: brand ? undefined : this.state.isCollapsed ? icons_1.ArrowRightSvg : icons_1.ArrowDropDownSvg, noOverflow: true, onClick: this.toggleCollapsed, className: brand ? `msp-transform-header-brand msp-transform-header-brand-${brand.accent}` : undefined, title: `Click to ${this.state.isCollapsed ? 'expand' : 'collapse'}`, children: [(0, jsx_runtime_1.jsx)(icons_1.Icon, { svg: brand === null || brand === void 0 ? void 0 : brand.svg, inline: true }), "Annotations", (0, jsx_runtime_1.jsx)("small", { style: { margin: '0 6px' }, children: this.state.isCollapsed ? '' : this.state.description })] }) }), !this.state.isCollapsed && (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [this.state.validationParams &&
(0, jsx_runtime_1.jsx)(annotation_row_controls_1.AnnotationRowControls, { title: 'Validation', params: this.state.validationParams.params, values: this.state.validationParams.values, onChangeValues: this.updateValidationParams, applied: this.state.validationApplied, onChangeApplied: () => this.toggleAnnotation('validation'), errorMessage: validationDataReady ? undefined : 'First activate annotation to show options' }), this.state.domainsParams &&
(0, jsx_runtime_1.jsx)(annotation_row_controls_1.AnnotationRowControls, { title: 'Domain Annotations', shortTitle: 'Domains', params: this.state.domainsParams.params, values: this.state.domainsParams.values, onChangeValues: this.updateDomainParams, applied: this.state.domainsApplied, onChangeApplied: () => this.toggleAnnotation('domains'), errorMessage: domainDataReady ? undefined : 'First activate annotation to show options' }), this.state.showSymmetryAnnotation &&
(0, jsx_runtime_1.jsx)(symmetry_annotation_controls_1.SymmetryAnnotationControls, {})] })] });
}
}
exports.AnnotationsComponentControls = AnnotationsComponentControls;