Implement group support in Settings UI

pull/133/head
Kelvin Schoofs 6 years ago
parent 8bcbb2179c
commit 1965f51b08

@ -0,0 +1,11 @@
import { FieldDropdownWithInput } from 'src/FieldTypes/dropdownwithinput';
import { connect } from 'src/redux';
import { getGroups } from 'src/types/fileSystemConfig';
export interface StateProps {
values: string[];
}
export default connect(FieldDropdownWithInput)<StateProps>(
state => ({ values: getGroups(state.data.configs).sort() }),
);

@ -5,6 +5,7 @@ import { FieldNumber } from 'src/FieldTypes/number';
import { FieldPath } from 'src/FieldTypes/path';
import { FieldString } from 'src/FieldTypes/string';
import { FileSystemConfig, invalidConfigName } from 'src/types/fileSystemConfig';
import FieldConfigGroup from './configGroupField';
import { PROXY_FIELD } from './proxyFields';
export type FieldChanged<K = string, V = any> = (field: K, newValue: V) => void;
@ -38,6 +39,12 @@ export function label(config: FileSystemConfig, onChange: FSCChanged<'label'>):
return <FieldString key="label" label="Label" value={config.label} onChange={callback} optional={true} description={description} />
}
export function group(config: FileSystemConfig, onChange: FSCChanged<'group'>): React.ReactElement {
const callback = (newValue: string) => onChange('group', newValue);
const description = 'Group for this config, to group configs together in some UI places. Allows subgroups, in the format "Group1.SubGroup1.Subgroup2"';
return <FieldConfigGroup key="group" label="Group" value={config.group} {...{ description }} onChange={callback} optional={true} />
}
export function putty(config: FileSystemConfig, onChange: FSCChanged<'putty'>): React.ReactElement {
const callback = (newValue: string) => onChange('putty', newValue === '<Auto-detect>' ? true : newValue);
const description = 'A name of a PuTTY session, or `true` to find the PuTTY session from the host address';
@ -104,6 +111,6 @@ export function passphrase(config: FileSystemConfig, onChange: FSCChanged<'passp
export type FieldFactory = (config: FileSystemConfig, onChange: FSCChanged, onChangeMultiple: FSCChangedMultiple) => React.ReactElement | null;
export const FIELDS: FieldFactory[] = [
name, merge, label, putty, host, port,
name, merge, label, group, putty, host, port,
root, agent, username, password, privateKeyPath, passphrase,
PROXY_FIELD];

@ -2,16 +2,19 @@ import * as React from 'react';
import ConfigList from 'src/ConfigList';
import { receivedData } from 'src/data/actions';
import { connect, pickProperties } from 'src/redux';
import { ConfigLocation, FileSystemConfig, formatConfigLocation, groupByLocation } from 'src/types/fileSystemConfig';
import { openNewConfig } from 'src/view/actions';
import { ConfigLocation, FileSystemConfig, formatConfigLocation, groupByGroup, groupByLocation } from 'src/types/fileSystemConfig';
import { IStartScreenState } from 'src/view';
import { openNewConfig, openStartScreen } from 'src/view/actions';
import { API } from 'src/vscode';
import './index.css';
interface StateProps {
configs: FileSystemConfig[];
groupBy: string;
}
interface DispatchProps {
refresh(): void;
changeGroupBy(current: string): void;
add(): void;
}
class Homescreen extends React.Component<StateProps & DispatchProps> {
@ -19,27 +22,35 @@ class Homescreen extends React.Component<StateProps & DispatchProps> {
this.props.refresh();
}
public render() {
const grouped = groupByLocation(this.props.configs);
grouped.sort();
const grouped = (this.props.groupBy === 'group' ? groupByGroup : groupByLocation)(this.props.configs);
grouped.sort((a, b) => a[0] > b[0] ? 1 : -1);
const nextGroupBy = this.props.groupBy === 'group' ? 'location' : 'group';
return <div className="Homescreen">
<h2>Configurations</h2>
<button onClick={this.props.refresh}>Refresh</button>
<button onClick={this.props.add}>Add</button>
<button onClick={this.changeGroupBy}>Sort by {nextGroupBy}</button>
{grouped.map(([loc, configs]) => this.createGroup(loc, configs))}
</div>;
}
public createGroup(location: ConfigLocation, configs: FileSystemConfig[]) {
return <div key={location}>
<h3>{formatConfigLocation(location)}</h3>
public createGroup(group: string | ConfigLocation, configs: FileSystemConfig[]) {
const title = this.props.groupBy === 'group' ? group : formatConfigLocation(group as ConfigLocation);
return <div key={group}>
<h3>{title}</h3>
<ConfigList configs={configs} />
</div>;
}
public changeGroupBy = () => this.props.changeGroupBy(this.props.groupBy);
}
export default connect(Homescreen)<StateProps, DispatchProps>(
state => pickProperties(state.data, 'configs'),
state => ({
...pickProperties(state.data, 'configs'),
...pickProperties(state.view as IStartScreenState, 'groupBy'),
}),
dispatch => ({
add: () => dispatch(openNewConfig()),
changeGroupBy: (current: string) => dispatch(openStartScreen(current === 'group' ? 'location' : 'group')),
refresh: () => (dispatch(receivedData([], [])), API.postMessage({ type: 'requestData' })),
}),
);

@ -37,9 +37,10 @@ interface IAction {
export interface IActionOpenStartscreen extends IAction {
type: ActionType.OPEN_STARTSCREEN;
groupBy?: string;
}
export function openStartScreen(): IActionOpenStartscreen {
return { type: ActionType.OPEN_STARTSCREEN };
export function openStartScreen(groupBy?: string): IActionOpenStartscreen {
return { type: ActionType.OPEN_STARTSCREEN, groupBy };
}
/* NewConfig */

@ -1,11 +1,13 @@
import { Action, ActionType } from './actions';
import { DEFAULT_STATE, IConfigEditorState, INewConfigState, IState } from './state';
import { DEFAULT_STATE, IConfigEditorState, INewConfigState, IStartScreenState, IState } from './state';
export function reducer(state = DEFAULT_STATE, action: Action): IState {
switch (action.type) {
// Startscreen
case ActionType.OPEN_STARTSCREEN:
return { ...state, view: 'startscreen' };
case ActionType.OPEN_STARTSCREEN: {
const groupBy = action.groupBy || (state as IStartScreenState).groupBy || 'group';
return { ...state, view: 'startscreen', groupBy };
}
// New Config
case ActionType.OPEN_NEWCONFIG: {
const { name } = action;

@ -4,7 +4,9 @@ interface IViewState<V extends string> {
view: V;
}
export type IStartScreenState = IViewState<'startscreen'>;
export interface IStartScreenState extends IViewState<'startscreen'> {
groupBy: string;
}
export interface INewConfigState extends IViewState<'newconfig'> {
location?: ConfigLocation;
@ -25,5 +27,6 @@ export interface IConfigLocatorState extends IViewState<'configlocator'> {
export type IState = IStartScreenState | INewConfigState | IConfigEditorState | IConfigLocatorState;
export const DEFAULT_STATE: IState = {
groupBy: 'group',
view: 'startscreen',
}

Loading…
Cancel
Save