Skip to content

Commit

Permalink
Add column selection button
Browse files Browse the repository at this point in the history
Related Issues: #23

A new button has been added above the molecule table which allows users
to select the value collections which are displayed in the table. If
the value collection is toggled off, it is also not possible for the
user to sort by this collection. The idea is that this will make the
drop down list smaller for the sorting list, so that it is easier for
users to find the collection they want to sort by.

The implementation through the introduction of two new actions,
`HideCollection` and `ShowCollection`, which add and remove a given
collection from the `ignoredCollections` list. The `ignoredCollections`
list is then used to filter which collections in `valueCollections` are
displayed in the table, as well as the sorting drop-down menu.
The `ignoredCollections` state is passed around between the different
pages. This is because I expect that users would be quite annoyed
at having to continuously re-select which columns they wish to view
upon changing the page.

The `ignoredCollections` are also no longer being sent to requests.
The `ignoredCollections` sent to requests are now pretty much empty.
Conceptually the `ignoredCollections` used by the page states and by
the requests are quite different. The page's `ignoredCollections`
are those which are not currently being viewed by the table. However,
for these we still want to perform data requests. The reason being
that if the user decides to turn the column back on, there is no need
to send a new request to see the values. In addition, if these
collections were passed to the request, when the request returns the
new value collections, the `ignoredCollections` would not be present.
This would mean that you would not be able to show the empty checkbox,
because that depends on the collection being present in value
collections. This could be avoided by going through all the values
in `ignoredCollections` too, and making an empty checkbox for those,
but I think that leads to a more complex implementation. Essentially,
I think the `ignoredCollections` in the page state vs the requests
serve different purposes, and it's a bad idea to couple them.

There is a performance trade-off to not coupling the request and
page `ignoredCollections`. If they were coupled, then the page
requests would likely be quicker, because there would be fewer data
queries. However, toggling of the columns would be more expensive, as
it would involve requests. Because I think users expect toggling of
columns to be snappy, while page loads to be slower, I think not
coupling them will annoy them the least.

Alos, by default, the various position matrix collections were being
added into `ignoredCollections`, this is no longer the case. I'm
just going to expect the users toggle the collection off explicitly
if they don't want to see it. I think doing it behind the scenes is
a little bit confusing. I could see adding it back, but I don't really
want to think about it right now. Really I think the collection would
need to be added into the `ignoredCollections` for the requests,
rather than for the page state. This would prevent the collection
showing up as a `valueCollection`, once the request returns the new
list of `valueCollections`. I guess I'm not too bothered by this,
because I expect there will be multiple position matrix collections
which the user will need to toggle off. For example, if the user
has 5 position matrix collections for building blocks. They can
put at most 1 as a building block position matrix collection into
the Mongo Configurator. So I could automatically hide this one, but
the user would have to manually hide the others. So having the extra
one there is not a big deal and maybe even slightly more consistent.

I also changed lots of types from `Array String` to `HashSet String`
for better performance and to be more explicit that there are
unsorted collections of unique values
  • Loading branch information
lukasturcani committed Jun 6, 2021
1 parent bf44af9 commit 7d7ff99
Show file tree
Hide file tree
Showing 53 changed files with 2,030 additions and 551 deletions.
1 change: 1 addition & 0 deletions spago.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ You can edit this file as you like.
, "promises"
, "psci-support"
, "tuples"
, "unordered-collections"
, "validated-molecule"
]
, packages = ./packages.dhall
Expand Down
7 changes: 7 additions & 0 deletions src/@types/Page.BuildingBlockBrowser.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ declare module 'Page.BuildingBlockBrowser'
import {
Props as SaveButtonProps,
} from 'Page.SaveButton';
import {
Props as ColumnButtonProps,
} from 'Page.ColumnButton';

export type Model = unknown;
export type Action = { type: string };
Expand All @@ -30,6 +33,7 @@ declare module 'Page.BuildingBlockBrowser'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Building Block Browser All Viewers";
};
type: undefined;
Expand All @@ -45,6 +49,7 @@ declare module 'Page.BuildingBlockBrowser'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Building Block Browser 2D Viewer";
};
type: undefined;
Expand All @@ -60,6 +65,7 @@ declare module 'Page.BuildingBlockBrowser'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Building Block Browser 3D Viewer";
};
type: undefined;
Expand All @@ -75,6 +81,7 @@ declare module 'Page.BuildingBlockBrowser'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Building Block Browser No Viewers";
};
type: undefined;
Expand Down
23 changes: 23 additions & 0 deletions src/@types/Page.ColumnButton.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
declare module 'Page.ColumnButton'
{
export interface CollectionCheckboxProps
{
isChecked: boolean;
label: string;
}

export interface Props<a>
{
collections: CollectionCheckboxProps[];

hideCollection:
(dispatch: (action: a) => void) =>
(collection: string) =>
void;

showCollection:
(dispatch: (action: a) => void) =>
(collection: string) =>
void;
}
}
7 changes: 7 additions & 0 deletions src/@types/Page.MoleculeBrowser.Props.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ declare module 'Page.MoleculeBrowser.Props'
import {
Props as SaveButtonProps,
} from 'Page.SaveButton';
import {
Props as ColumnButtonProps,
} from 'Page.ColumnButton';

export interface AllViewers<a>
{
Expand All @@ -41,6 +44,7 @@ declare module 'Page.MoleculeBrowser.Props'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Molecule Browser All Viewers";
};
type: undefined;
Expand All @@ -58,6 +62,7 @@ declare module 'Page.MoleculeBrowser.Props'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Molecule Browser 2D Viewer";
};
type: undefined;
Expand All @@ -75,6 +80,7 @@ declare module 'Page.MoleculeBrowser.Props'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Molecule Browser 3D Viewer";
}
type: undefined;
Expand All @@ -90,6 +96,7 @@ declare module 'Page.MoleculeBrowser.Props'
twoDViewerSwitch: ViewerSwitchProps<a>;
threeDViewerSwitch: ViewerSwitchProps<a>;
saveButton: SaveButtonProps;
columnButton: ColumnButtonProps<a>;
type: "Molecule Browser No Viewers";
};
type: undefined;
Expand Down
39 changes: 16 additions & 23 deletions src/Config.purs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Config
, searchKind
) where

import Data.HashSet (HashSet)
import Molecule (Molecule, MoleculeKeyValue)
import PageKind (PageKind)
import SelectingCollection (SelectingCollection)
Expand All @@ -28,7 +29,7 @@ type MongoConfigurator =
, positionMatrixCollection :: String
, buildingBlockPositionMatrixCollection :: String
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, searchKind :: SearchKind
, twoDViewer :: Boolean
, threeDViewer :: Boolean
Expand All @@ -44,10 +45,9 @@ type UnsortedAll =
, buildingBlockPositionMatrixCollection :: String
, pageIndex :: Int
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, pageKind :: PageKind
, valueCollections :: Array String
, columns :: Array String
, valueCollections :: HashSet String
, molecules :: SelectingCollection Molecule
, twoDViewer :: Boolean
, threeDViewer :: Boolean
Expand All @@ -63,10 +63,9 @@ type UnsortedBuildingBlocks =
, buildingBlockPositionMatrixCollection :: String
, pageIndex :: Int
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, pageKind :: PageKind
, valueCollections :: Array String
, columns :: Array String
, valueCollections :: HashSet String
, molecules :: SelectingCollection Molecule
, twoDViewer :: Boolean
, threeDViewer :: Boolean
Expand All @@ -82,10 +81,9 @@ type UnsortedConstructedMolecules =
, buildingBlockPositionMatrixCollection :: String
, pageIndex :: Int
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, pageKind :: PageKind
, valueCollections :: Array String
, columns :: Array String
, valueCollections :: HashSet String
, molecules :: SelectingCollection Molecule
, twoDViewer :: Boolean
, threeDViewer :: Boolean
Expand All @@ -101,10 +99,9 @@ type SortedAll =
, buildingBlockPositionMatrixCollection :: String
, pageIndex :: Int
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, pageKind :: PageKind
, valueCollections :: Array String
, columns :: Array String
, valueCollections :: HashSet String
, molecules :: SelectingCollection Molecule
, sortedCollection :: String
, sortType :: SortType
Expand All @@ -122,10 +119,9 @@ type SortedBuildingBlocks =
, buildingBlockPositionMatrixCollection :: String
, pageIndex :: Int
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, pageKind :: PageKind
, valueCollections :: Array String
, columns :: Array String
, valueCollections :: HashSet String
, molecules :: SelectingCollection Molecule
, sortedCollection :: String
, sortType :: SortType
Expand All @@ -143,10 +139,9 @@ type SortedConstructedMolecules =
, buildingBlockPositionMatrixCollection :: String
, pageIndex :: Int
, numEntriesPerPage :: Int
, ignoredCollections :: Array String
, ignoredCollections :: HashSet String
, pageKind :: PageKind
, valueCollections :: Array String
, columns :: Array String
, valueCollections :: HashSet String
, molecules :: SelectingCollection Molecule
, sortedCollection :: String
, sortType :: SortType
Expand All @@ -170,9 +165,8 @@ type BuildingBlockBrowser =
, constructedMoleculeCollection :: String
, positionMatrixCollection :: String
, buildingBlockPositionMatrixCollection :: String
, ignoredCollections :: Array String
, valueCollections :: Array String
, columns :: Array String
, ignoredCollections :: HashSet String
, valueCollections :: HashSet String
, buildingBlocks :: SelectingCollection Molecule
, history :: Array MoleculeKeyValue
, molecule :: MoleculeKeyValue
Expand Down Expand Up @@ -201,4 +195,3 @@ searchKind browser = case browser of
SortedBuildingBlocks _ -> SearchKind.UnsortedBuildingBlocks
SortedConstructedMolecules _ ->
SearchKind.UnsortedConstructedMolecules

88 changes: 88 additions & 0 deletions src/Page/Assets/ColumnButton/ColumnButton.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
module Page.ColumnButton
( Props
, CollectionCheckboxProps
, props
) where

import Prelude
import Data.HashSet (HashSet)
import Data.HashSet as HashSet
import Data.Array as Array
import Data.String as String
import DispatchAction (DispatchAction)
import Effect.Unsafe (unsafePerformEffect)
import Effect.Uncurried (runEffectFn1)

type CollectionCheckboxProps =
{ isChecked :: Boolean
, label :: String
}


type Props a =
{ collections :: Array CollectionCheckboxProps
, hideCollection :: DispatchAction a -> String -> Unit
, showCollection :: DispatchAction a -> String -> Unit
}

type ActionCreators a r =
{ hideCollection :: String -> a
, showCollection :: String -> a
| r
}

props
:: forall a r
. ActionCreators a r
-> HashSet String
-> HashSet String
-> Props a

props actionCreators ignoredCollections collections =
{ collections: checkboxProps
, hideCollection: hideCollection actionCreators
, showCollection: showCollection actionCreators
}

where

sortedCollections =
Array.sortWith String.toLower $
Array.fromFoldable collections

checkboxProps :: Array CollectionCheckboxProps
checkboxProps = do
collection <- sortedCollections
pure
{ isChecked:
not $ collection `HashSet.member` ignoredCollections
, label: collection
}

hideCollection
:: forall a r
. ActionCreators a r
-> DispatchAction a
-> String
-> Unit

hideCollection actionCreators dispatch collection =
unsafePerformEffect
(runEffectFn1
dispatch
(actionCreators.hideCollection collection)
)

showCollection
:: forall a r
. ActionCreators a r
-> DispatchAction a
-> String
-> Unit

showCollection actionCreators dispatch collection =
unsafePerformEffect
(runEffectFn1
dispatch
(actionCreators.showCollection collection)
)
61 changes: 61 additions & 0 deletions src/Page/Assets/ColumnButton/components/base/column-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as React from 'react';
import {
Props as ColumnButtonProps
} from 'Page.ColumnButton';
import {
CoreProps as ColumnSettingsProps,
} from './column-settings';


type Empty = Record<string, unknown>;

export interface DispatchProps<a>
{
dispatch: (action: a) => void;
}

export type CoreProps<a> = ColumnButtonProps<a> & DispatchProps<a>;

interface Props<a> extends ColumnButtonProps<a>, DispatchProps<a>
{
container: React.FunctionComponent<Empty>;
button: React.FunctionComponent<ButtonProps>;
columnSettings: React.FunctionComponent<ColumnSettingsProps<a>>;
}

export interface SnackbarProps
{
open: boolean;
onClose: (event?: React.SyntheticEvent, reason?: string) => void;
message: string;
}


export interface ButtonProps
{
onClick: () => void;
}


export function ColumnButton<a>(
props: Props<a>,
)
{
const [open, setOpen] = React.useState(false);

return (
<props.container>
<props.button
onClick={ () => setOpen(true) }
/>
<props.columnSettings
dispatch={props.dispatch}
open={open}
setOpen={setOpen}
collections={props.collections}
hideCollection={props.hideCollection}
showCollection={props.showCollection}
/>
</props.container>
);
}
Loading

0 comments on commit 7d7ff99

Please sign in to comment.