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

Passive active choice #98

Merged
merged 28 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
37d3560
Moved todos to #97
sverhoeven Apr 23, 2024
c719e34
Merge remote-tracking branch 'origin/main' into passive-active-choice
sverhoeven Apr 23, 2024
bd251fa
Add storybook.js so components are easier to develop in isolation
sverhoeven Apr 23, 2024
4dafa24
Big refactor of molecule sub form and its children
sverhoeven Apr 23, 2024
62e8f32
When mouse leaves ngl viewer make sure any highlighted residues are u…
sverhoeven Apr 24, 2024
e3fff8b
Active selection takes precedence over already selected passive
sverhoeven Apr 24, 2024
a5308c2
Add toggle shadcn component
sverhoeven Apr 24, 2024
9f85728
Save computed neigbours in own list
sverhoeven Apr 24, 2024
db2dc5e
get shift select to work again
sverhoeven Apr 25, 2024
453c988
Picking 3D will unselect other
sverhoeven Apr 25, 2024
ddfdfa2
Renamed RestraintsBase to RestraintsFlavour
sverhoeven Apr 25, 2024
22b2597
Update docs
sverhoeven Apr 25, 2024
f0995a4
Show neighbours as passive disabled residues
sverhoeven Apr 25, 2024
f97b44b
Regen restraints client dts
sverhoeven May 6, 2024
bce0058
add default radius
sverhoeven May 6, 2024
68d3ef1
Use colors in 3D that are similar to colors of residue sequence
sverhoeven May 7, 2024
d5151e9
User settable surface cutoff and neighbour radius
sverhoeven May 7, 2024
26860a3
FOrmat
sverhoeven May 8, 2024
e055e52
Add toggle to show either surface or buried residues
sverhoeven May 8, 2024
9697269
Added toggle to render selection as spacefill or surface
sverhoeven May 8, 2024
13e7dc5
Show protein as surface
sverhoeven May 8, 2024
4a757bd
Moved onPick + onHover to NGLStage
sverhoeven May 8, 2024
90decd6
Make MoleculeSubForm smaller, by moving reusable components to own files
sverhoeven May 8, 2024
73570ed
Keep selection when switching representation
sverhoeven May 10, 2024
21e7b09
Show spinner while talking to restraints web service
sverhoeven May 10, 2024
ce05060
Allow another pdb file to be chosen or a different chain to be selected
sverhoeven May 10, 2024
9263076
Keeping both surface residues vars as they are both used optimally in…
sverhoeven May 10, 2024
39bce36
Format
sverhoeven May 10, 2024
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
2 changes: 1 addition & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = {
},

// Base config
extends: ["eslint:recommended"],
extends: ["eslint:recommended", "plugin:storybook/recommended"],

overrides: [
// React
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ Caddyfile
/playwright-report/
/blob-report/
/playwright

*storybook.log
25 changes: 25 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { StorybookConfig } from "@storybook/react-vite";

const config: StorybookConfig = {
stories: [
"../stories/**/*.mdx",
"../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)",
],
addons: [
"@storybook/addon-onboarding",
"@storybook/addon-links",
"@storybook/addon-essentials",
"@chromatic-com/storybook",
"@storybook/addon-interactions",
"@storybook/addon-themes",
],
framework: {
name: "@storybook/react-vite",
options: {},
},
docs: {
autodocs: "tag",
},
staticDirs: [{ from: "../stories/assets", to: "/assets" }],
};
export default config;
28 changes: 28 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Preview } from "@storybook/react";
import { withThemeFromJSXProvider } from "@storybook/addon-themes";
import { ThemeProvider } from "remix-themes";
import "../app/tailwind.css";

const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;

export const decorators = [
withThemeFromJSXProvider({
themes: {
light: "light" as any,
dark: "dark" as any,
},
defaultTheme: "light",
Provider: ThemeProvider,
}),
];
29 changes: 29 additions & 0 deletions app/components/ui/popover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import * as React from "react";
import * as PopoverPrimitive from "@radix-ui/react-popover";

import { cn } from "~/lib/utils";

const Popover = PopoverPrimitive.Root;

const PopoverTrigger = PopoverPrimitive.Trigger;

const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className,
)}
{...props}
/>
</PopoverPrimitive.Portal>
));
PopoverContent.displayName = PopoverPrimitive.Content.displayName;

export { Popover, PopoverTrigger, PopoverContent };
54 changes: 54 additions & 0 deletions app/components/ui/spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/* From https://shadcnui-expansions.typeart.cc/docs/spinner */
import React from "react";

import { cn } from "~/lib/utils";
import { VariantProps, cva } from "class-variance-authority";
import { Loader2 } from "lucide-react";

const spinnerVariants = cva("flex-col items-center justify-center", {
variants: {
show: {
true: "flex",
false: "hidden",
},
},
defaultVariants: {
show: true,
},
});

const loaderVariants = cva("animate-spin text-primary", {
variants: {
size: {
small: "size-6",
medium: "size-8",
large: "size-12",
},
},
defaultVariants: {
size: "small",
},
});

interface SpinnerContentProps
extends VariantProps<typeof spinnerVariants>,
VariantProps<typeof loaderVariants> {
className?: string;
children?: React.ReactNode;
title?: string;
}

export function Spinner({
size,
show,
children,
className,
title = "Loading...",
}: SpinnerContentProps) {
return (
<span className={spinnerVariants({ show })} title={title}>
<Loader2 className={cn(loaderVariants({ size }), className)} />
{children}
</span>
);
}
59 changes: 59 additions & 0 deletions app/components/ui/toggle-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import * as React from "react";
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
import { VariantProps } from "class-variance-authority";

import { cn } from "~/lib/utils";
import { toggleVariants } from "~/components/ui/toggle";

const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
});

const ToggleGroup = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, children, ...props }, ref) => (
<ToggleGroupPrimitive.Root
ref={ref}
className={cn("flex items-center justify-center gap-1", className)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
));

ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;

const ToggleGroupItem = React.forwardRef<
React.ElementRef<typeof ToggleGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>
>(({ className, children, variant, size, ...props }, ref) => {
const context = React.useContext(ToggleGroupContext);

return (
<ToggleGroupPrimitive.Item
ref={ref}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className,
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
);
});

ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;

export { ToggleGroup, ToggleGroupItem };
43 changes: 43 additions & 0 deletions app/components/ui/toggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from "react";
import * as TogglePrimitive from "@radix-ui/react-toggle";
import { cva, type VariantProps } from "class-variance-authority";

import { cn } from "~/lib/utils";

const toggleVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-10 px-3",
sm: "h-9 px-2.5",
lg: "h-11 px-5",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);

const Toggle = React.forwardRef<
React.ElementRef<typeof TogglePrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>
>(({ className, variant, size, ...props }, ref) => (
<TogglePrimitive.Root
ref={ref}
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
));

Toggle.displayName = TogglePrimitive.Root.displayName;

export { Toggle, toggleVariants };
27 changes: 24 additions & 3 deletions app/haddock3-restraints-client/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export interface paths {
};
get?: never;
put?: never;
/** Calculate Actpass To Ambig */
/**
* Calculate Actpass To Ambig
* @description Get the passive residues.
*/
post: operations["calculate_actpass_to_ambig_actpass_to_ambig_post"];
delete?: never;
options?: never;
Expand All @@ -48,7 +51,10 @@ export interface paths {
};
get?: never;
put?: never;
/** Restrain Bodies */
/**
* Restrain Bodies
* @description Create distance restraints to lock several chains together.
*/
post: operations["restrain_bodies_restrain_bodies_post"];
delete?: never;
options?: never;
Expand All @@ -65,7 +71,10 @@ export interface paths {
};
get?: never;
put?: never;
/** Calculate Accessibility */
/**
* Calculate Accessibility
* @description Calculate the accessibility of the side chains and apply a cutoff.
*/
post: operations["calculate_accessibility_calc_accessibility_post"];
delete?: never;
options?: never;
Expand Down Expand Up @@ -108,6 +117,12 @@ export interface paths {
* ```shell
* cat pdb | pdb_tidy -strict | pdb_selchain -<from_chain> | pdb_chain -<to_chain> | pdb_fixinsert | pdb_selaltloc | pdb_tidy -strict
* ```
*
* or with `delhetatm` and `keepcoord` set to true:
*
* ```shell
* cat pdb | pdb_tidy -strict | pdb_selchain -<from_chain> | pdb_chain -<to_chain> | pdb_delhetatm | pdb_fixinsert | pdb_keepcoord | pdb_selaltloc | pdb_tidy -strict
* ```
*/
post: operations["preprocess_pdb_preprocess_pdb_post"];
delete?: never;
Expand Down Expand Up @@ -227,6 +242,12 @@ export interface components {
* @default []
*/
surface: number[];
/**
* Radius
* @description The radius from active.
* @default 6.5
*/
radius: number;
};
/** RestrainBodiesRequest */
RestrainBodiesRequest: {
Expand Down
24 changes: 5 additions & 19 deletions app/routes/scenarios.antibody-antigen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
ActPassSelection,
MoleculeSubForm,
} from "~/scenarios/MoleculeSubForm.client";
import { AntigenSubForm, Flavour } from "~/scenarios/Antigen.client";
import { PDBFileInput } from "~/scenarios/PDBFileInput.client";
import {
generateAmbiguousRestraintsFile,
Expand Down Expand Up @@ -158,43 +157,32 @@ export default function AntibodyAntigenScenario() {
const [antibodyActPass, seAntibodyActPass] = useState<ActPassSelection>({
active: [],
passive: [],
neighbours: [],
chain: "",
bodyRestraints: "",
});
const [antigenActPass, setAntigen2ActPass] = useState<ActPassSelection>({
active: [],
passive: [],
neighbours: [],
chain: "",
bodyRestraints: "",
});
const [antigenFlavour, setAntigenFlavour] = useState<Flavour>("actpass");

async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
const form = event.currentTarget;
const formData = new FormData(form);

let antigenSelection = antigenActPass;
if (antigenFlavour === "pass") {
// in the ResidueSubForm the user selected residues are stored as active
// and the computed surface neighbouring residues are stored as passive
// here we store all those residues as passive
antigenSelection = {
active: [],
passive: [...antigenActPass.active, ...antigenActPass.passive],
chain: antigenActPass.chain,
bodyRestraints: antigenActPass.bodyRestraints,
};
}
const ambig_fname = await generateAmbiguousRestraintsFile(
antibodyActPass,
antigenSelection,
antigenActPass,
);
formData.set("ambig_fname", ambig_fname);

const unambig_fname = generateUnAmbiguousRestraintsFile(
antibodyActPass.bodyRestraints,
antigenSelection.bodyRestraints,
antigenActPass.bodyRestraints,
);
if (unambig_fname) {
formData.set("unambig_fname", unambig_fname);
Expand Down Expand Up @@ -237,7 +225,7 @@ export default function AntibodyAntigenScenario() {
accessibilityCutoff={0.15}
/>
<div>
<AntigenSubForm
<MoleculeSubForm
name="antigen"
legend="Antigen"
description="In tutorial named pdbs/4I1B_clean.pdb"
Expand All @@ -246,8 +234,6 @@ export default function AntibodyAntigenScenario() {
targetChain="B"
preprocessPipeline="delhetatmkeepcoord"
accessibilityCutoff={0.15}
antigenFlavour={antigenFlavour}
onFlavourChange={setAntigenFlavour}
/>
</div>
</div>
Expand Down
Loading
Loading