page: number;
onSearch: (value: string) => void;
onRowClick: (item: T) => void;
+ onRowDoubleClick: (item: T) => void;
onColumnToggle: (column: DataColumn<T>) => void;
- onContextAction: (action: ContextMenuAction, item: T) => void;
+ onContextMenu: (event: React.MouseEvent<HTMLElement>, item: T) => void;
onSortToggle: (column: DataColumn<T>) => void;
onFiltersChange: (filters: DataTableFilterItem[], column: DataColumn<T>) => void;
onChangePage: (page: number) => void;
columns={[...this.props.columns, this.contextMenuColumn]}
items={this.props.items}
onRowClick={(_, item: T) => this.props.onRowClick(item)}
- onRowContextMenu={this.openContextMenu}
+ onContextMenu={this.props.onContextMenu}
+ onRowDoubleClick={(_, item: T) => this.props.onRowDoubleClick(item)}
onFiltersChange={this.props.onFiltersChange}
onSortToggle={this.props.onSortToggle} />
<Toolbar>
items: T[];
columns: DataColumns<T>;
onRowClick: (event: React.MouseEvent<HTMLTableRowElement>, item: T) => void;
- onRowContextMenu: (event: React.MouseEvent<HTMLTableRowElement>, item: T) => void;
+ onContextMenu: (event: React.MouseEvent<HTMLElement>, item: T) => void;
+ onRowDoubleClick: (event: React.MouseEvent<HTMLTableRowElement>, item: T) => void;
onSortToggle: (column: DataColumn<T>) => void;
onFiltersChange: (filters: DataTableFilterItem[], column: DataColumn<T>) => void;
}
}
renderBodyRow = (item: T, index: number) => {
- const { onRowClick, onContextMenu } = this.props;
- const { onRowClick, onRowDoubleClick, onRowContextMenu } = this.props;
++ const { onRowClick, onRowDoubleClick, onContextMenu } = this.props;
return <TableRow
hover
key={item.key}
onClick={event => onRowClick && onRowClick(event, item)}
- onContextMenu={this.handleRowContextMenu(item)}>
- onDoubleClick={event => onRowDoubleClick && onRowDoubleClick(event, item) }
- onContextMenu={event => onRowContextMenu && onRowContextMenu(event, item)}>
++ onContextMenu={this.handleRowContextMenu(item)}
++ onDoubleClick={event => onRowDoubleClick && onRowDoubleClick(event, item) }>
{this.mapVisibleColumns((column, index) => (
<TableCell key={column.key || index}>
{column.render(item)}
interface Props {
id: string;
- contextActions: ContextMenuActionGroup[];
onRowClick: (item: any) => void;
- onContextAction: (action: ContextMenuAction, item: any) => void;
+ onContextMenu: (event: React.MouseEvent<HTMLElement>, item: any) => void;
+ onRowDoubleClick: (item: any) => void;
}
-const mapStateToProps = (state: RootState, { id, contextActions }: Props) =>
+const mapStateToProps = (state: RootState, { id }: Props) =>
getDataExplorer(state.dataExplorer, id);
- const mapDispatchToProps = (dispatch: Dispatch, { id, onRowClick, onContextMenu }: Props) => ({
-const mapDispatchToProps = (dispatch: Dispatch, { id, contextActions, onRowClick, onRowDoubleClick, onContextAction }: Props) => ({
++const mapDispatchToProps = (dispatch: Dispatch, { id, onRowClick, onRowDoubleClick, onContextMenu }: Props) => ({
onSearch: (searchValue: string) => {
dispatch(actions.SET_SEARCH_VALUE({ id, searchValue }));
},
dispatch(actions.SET_ROWS_PER_PAGE({ id, rowsPerPage }));
},
- contextActions,
-
onRowClick,
- onContextMenu
+ onRowDoubleClick,
-
- onContextAction
++
++ onContextMenu,
});
export default connect(mapStateToProps, mapDispatchToProps)(DataExplorer);
type ProjectPanelProps = {
currentItemId: string,
onItemClick: (item: ProjectPanelItem) => void,
- onItemRouteChange: (itemId: string) => void,
+ onContextMenu: (event: React.MouseEvent<HTMLElement>, item: ProjectPanelItem) => void;
+ onDialogOpen: (ownerUuid: string) => void;
+ onItemDoubleClick: (item: ProjectPanelItem) => void,
+ onItemRouteChange: (itemId: string) => void
}
& DispatchProp
& WithStyles<CssRules>
</div>
<DataExplorer
id={PROJECT_PANEL_ID}
- contextActions={contextMenuActions}
onRowClick={this.props.onItemClick}
- onContextMenu={this.props.onContextMenu} />;
+ onRowDoubleClick={this.props.onItemDoubleClick}
- onContextAction={this.executeAction} />;
++ onContextMenu={this.props.onContextMenu} />
</div>;
}
import ProjectPanel from "../project-panel/project-panel";
import DetailsPanel from '../../views-components/details-panel/details-panel';
import { ArvadosTheme } from '../../common/custom-theme';
+import ContextMenu, { ContextMenuAction } from '../../components/context-menu/context-menu';
+import { mockAnchorFromMouseEvent } from '../../components/popover/helpers';
+import CreateProjectDialog from "../../views-components/create-project-dialog/create-project-dialog";
+import { authService } from '../../services/services';
+
+ import detailsPanelActions, { loadDetails } from "../../store/details-panel/details-panel-action";
+ import { ResourceKind } from '../../models/kinds';
const drawerWidth = 240;
const appBarHeight = 100;
helpMenu: NavMenuItem[],
anonymousMenu: NavMenuItem[]
};
- isDetailsPanelOpened: boolean;
}
+
class Workbench extends React.Component<WorkbenchProps, WorkbenchState> {
state = {
+ contextMenu: {
+ anchorEl: undefined,
+ itemUuid: undefined
+ },
+ isCreationDialogOpen: false,
anchorEl: null,
searchText: "",
breadcrumbs: [],
},
onMenuItemClick: (menuItem: NavMenuItem) => menuItem.action(),
onDetailsPanelToggle: () => {
- this.setState(prev => ({ isDetailsPanelOpened: !prev.isDetailsPanelOpened }));
+ this.props.dispatch(detailsPanelActions.TOGGLE_DETAILS_PANEL());
+ },
+ onContextMenu: (event: React.MouseEvent<HTMLElement>, breadcrumb: NavBreadcrumb) => {
+ this.openContextMenu(event, breadcrumb.itemId);
}
};
<ProjectTree
projects={this.props.projects}
toggleOpen={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.OPEN))}
- toggleActive={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
- onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid)} />
++ onContextMenu={(event, item) => this.openContextMenu(event, item.data.uuid)}
+ toggleActive={itemId => {
+ this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE));
+ this.props.dispatch<any>(loadDetails(itemId, ResourceKind.Project));
- }}
- />
++ }}/>
</SidePanel>
</Drawer>}
<main className={classes.contentWrapper}>
<Route path="/projects/:id" render={this.renderProjectPanel} />
</Switch>
</div>
- <DetailsPanel
- isOpened={this.state.isDetailsPanelOpened}
- onCloseDrawer={this.mainAppBarActions.onDetailsPanelToggle} />
+ <DetailsPanel />
</main>
+ <ContextMenu
+ anchorEl={this.state.contextMenu.anchorEl}
+ actions={contextMenuActions}
+ onActionClick={this.openCreateDialog}
+ onClose={this.closeContextMenu} />
+ <CreateProjectDialog />
</div>
);
}
renderProjectPanel = (props: RouteComponentProps<{ id: string }>) => <ProjectPanel
onItemRouteChange={itemId => this.props.dispatch<any>(setProjectItem(itemId, ItemMode.ACTIVE))}
- onItemClick={item => this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE))}
+ onContextMenu={(event, item) => this.openContextMenu(event, item.uuid)}
+ onDialogOpen={this.handleCreationDialogOpen}
+ onItemClick={item => {
+ this.props.dispatch<any>(loadDetails(item.uuid, item.kind as ResourceKind));
+ }}
+ onItemDoubleClick={item => {
+ this.props.dispatch<any>(setProjectItem(item.uuid, ItemMode.ACTIVE));
+ this.props.dispatch<any>(loadDetails(item.uuid, ResourceKind.Project));
+ }}
{...props} />
+}
+const contextMenuActions = [[{
+ icon: "fas fa-plus fa-fw",
+ name: "New project",
+ openCreateDialog: true
+}, {
+ icon: "fas fa-users fa-fw",
+ name: "Share"
+}, {
+ icon: "fas fa-sign-out-alt fa-fw",
+ name: "Move to"
+}, {
+ icon: "fas fa-star fa-fw",
+ name: "Add to favourite"
+}, {
+ icon: "fas fa-edit fa-fw",
+ name: "Rename"
+}, {
+ icon: "fas fa-copy fa-fw",
+ name: "Make a copy"
+}, {
+ icon: "fas fa-download fa-fw",
+ name: "Download"
+}], [{
+ icon: "fas fa-trash-alt fa-fw",
+ name: "Remove"
}
+]];
export default connect<WorkbenchDataProps>(
(state: RootState) => ({