From 7dd808a772a976b7996a8d2b9bc8426582bf337b Mon Sep 17 00:00:00 2001
From: Alexander Rose <alexander.rose@weirdbyte.de>
Date: Sat, 12 Mar 2022 10:52:43 -0800
Subject: [PATCH] add custom import controls

---
 CHANGELOG.md                     |  3 ++-
 src/extensions/zenodo/index.ts   |  4 ++--
 src/mol-plugin-ui/left-panel.tsx | 18 +++++++++++++++++-
 src/mol-plugin/context.ts        |  3 ++-
 4 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5bd388049..8b6c16297 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,8 @@ Note that since we don't clearly distinguish between a public and private interf
 ## [Unreleased]
 
 - Fix handling of mmcif with empty ``label_*`` fields
-- Add LoadTrajectory action
+- Add ``LoadTrajectory`` action
+- Add ``CustomImportControls`` to left panel
 - Add Zenodo import extension (load structures, trajectories, volumes, and zip files)
 - Fix loading of some compressed files within sessions
 
diff --git a/src/extensions/zenodo/index.ts b/src/extensions/zenodo/index.ts
index d09b84276..2b2a03f01 100644
--- a/src/extensions/zenodo/index.ts
+++ b/src/extensions/zenodo/index.ts
@@ -15,7 +15,7 @@ export const ZenodoImport = PluginBehavior.create<{ }>({
     },
     ctor: class extends PluginBehavior.Handler<{ }> {
         register(): void {
-            this.ctx.customStructureControls.set('zenodo-import', ZenodoImportUI as any);
+            this.ctx.customImportControls.set('zenodo-import', ZenodoImportUI as any);
         }
 
         update() {
@@ -23,7 +23,7 @@ export const ZenodoImport = PluginBehavior.create<{ }>({
         }
 
         unregister() {
-            this.ctx.customStructureControls.delete('zenodo-import');
+            this.ctx.customImportControls.delete('zenodo-import');
         }
     },
     params: () => ({ })
diff --git a/src/mol-plugin-ui/left-panel.tsx b/src/mol-plugin-ui/left-panel.tsx
index c492c1317..32477e580 100644
--- a/src/mol-plugin-ui/left-panel.tsx
+++ b/src/mol-plugin-ui/left-panel.tsx
@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import * as React from 'react';
@@ -19,6 +20,20 @@ import { StateTree } from './state/tree';
 import { HelpContent } from './viewport/help';
 import { HomeOutlinedSvg, AccountTreeOutlinedSvg, TuneSvg, HelpOutlineSvg, SaveOutlinedSvg, DeleteOutlinedSvg } from './controls/icons';
 
+export class CustomImportControls extends PluginUIComponent<{ initiallyCollapsed?: boolean }> {
+    componentDidMount() {
+        this.subscribe(this.plugin.state.behaviors.events.changed, () => this.forceUpdate());
+    }
+
+    render() {
+        const controls: JSX.Element[] = [];
+        this.plugin.customImportControls.forEach((Controls, key) => {
+            controls.push(<Controls initiallyCollapsed={this.props.initiallyCollapsed} key={key} />);
+        });
+        return controls.length > 0 ? <>{controls}</> : null;
+    }
+}
+
 export class LeftPanelControls extends PluginUIComponent<{}, { tab: LeftPanelTabName }> {
     state = { tab: this.plugin.behaviors.layout.leftPanelTabName.value };
 
@@ -54,6 +69,7 @@ export class LeftPanelControls extends PluginUIComponent<{}, { tab: LeftPanelTab
         'root': <>
             <SectionHeader icon={HomeOutlinedSvg} title='Home' />
             <StateObjectActions state={this.plugin.state.data} nodeRef={StateTransform.RootRef} hideHeader={true} initiallyCollapsed={true} alwaysExpandFirst={true} />
+            <CustomImportControls />
             {this.plugin.spec.components?.remoteState !== 'none' && <RemoteStateSnapshots listOnly /> }
         </>,
         'data': <>
diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts
index e953c67d6..a39812bf7 100644
--- a/src/mol-plugin/context.ts
+++ b/src/mol-plugin/context.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
@@ -176,6 +176,7 @@ export class PluginContext {
     readonly customStructureProperties = new CustomProperty.Registry<Structure>();
 
     readonly customStructureControls = new Map<string, { new(): any /* constructible react components with <action.customControl /> */ }>();
+    readonly customImportControls = new Map<string, { new(): any /* constructible react components with <action.customControl /> */ }>();
     readonly genericRepresentationControls = new Map<string, (selection: StructureHierarchyManager['selection']) => [StructureHierarchyRef[], string]>();
 
     /**
-- 
GitLab