Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
71 changes: 22 additions & 49 deletions frontend/packages/labs/ailab/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import {faSpinner} from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import type React from 'react';
import {connect} from 'react-redux';
import type {Dispatch} from 'redux';

import {styles} from './constants';
import {
isSaveComplete,
shouldDisplaySaveStatus,
} from './helpers/navigationValidation';
import {shallowEqual, useAppDispatch, useAppSelector} from './hooks';
import I18n from './i18n';
import type {RootState} from './redux';
import {
getPanelButtons,
setCurrentPanel,
getTrainedModelDataToSave,
} from './redux';
import type {PrevNextButtons, ModelDataToSave, SaveResponseData} from './types';
import {getPanelButtons, setCurrentPanel} from './redux';
import type {PrevNextButtons, SaveResponseData} from './types';
import ColumnInspector from './UIComponents/ColumnInspector';
import DataCard from './UIComponents/DataCard';
import DataDisplay from './UIComponents/DataDisplay';
Expand All @@ -33,8 +27,7 @@ interface PanelButtonsProps {
currentPanel: string;
setCurrentPanel: (panel: string) => void;
onContinue: () => void;
startSaveTrainedModel: (dataToSave: ModelDataToSave) => void;
dataToSave: ModelDataToSave;
startSaveTrainedModel: () => void;
saveStatus: string;
saveResponseData: SaveResponseData | undefined;
isSaveComplete: (saveStatus: string) => boolean;
Expand All @@ -47,7 +40,6 @@ const PanelButtons = ({
setCurrentPanel,
onContinue,
startSaveTrainedModel,
dataToSave,
saveStatus,
saveResponseData,
isSaveComplete: isSaveCompleteProp,
Expand All @@ -64,7 +56,7 @@ const PanelButtons = ({
if (['continue', 'finish'].includes(panelButtons.next.panel)) {
onContinue();
} else if (currentPanel === 'saveModel') {
startSaveTrainedModel(dataToSave);
startSaveTrainedModel();
} else {
setCurrentPanel(panelButtons.next.panel);
}
Expand Down Expand Up @@ -198,28 +190,24 @@ const ContainerFullWidth = ({children}: ContainerFullWidthProps) => {
};

interface AppProps {
panelButtons: PrevNextButtons;
currentPanel: string;
setCurrentPanel: (panel: string) => void;
onContinue: () => void;
resultsPhase: number | undefined;
startSaveTrainedModel: (dataToSave: ModelDataToSave) => void;
dataToSave: ModelDataToSave;
saveStatus: string;
saveResponseData: SaveResponseData | undefined;
startSaveTrainedModel: () => void;
}

const App = ({
panelButtons,
currentPanel,
setCurrentPanel,
onContinue,
resultsPhase,
startSaveTrainedModel,
dataToSave,
saveStatus,
saveResponseData,
}: AppProps) => {
// getPanelButtons builds a fresh {prev, next} each call (and reads I18n for
// button text), so compare its two sub-objects to avoid rerendering on a new
// reference with unchanged contents.
const panelButtonsEqual = (a: PrevNextButtons, b: PrevNextButtons) =>
shallowEqual(a.prev, b.prev) && shallowEqual(a.next, b.next);

const App = ({onContinue, startSaveTrainedModel}: AppProps) => {
const dispatch = useAppDispatch();
const panelButtons = useAppSelector(getPanelButtons, panelButtonsEqual);
const currentPanel = useAppSelector(state => state.currentPanel);
const resultsPhase = useAppSelector(state => state.resultsPhase);
const saveStatus = useAppSelector(state => state.saveStatus);
const saveResponseData = useAppSelector(state => state.saveResponseData);

return (
<div style={styles.app}>
{currentPanel === 'selectDataset' && (
Expand Down Expand Up @@ -293,10 +281,9 @@ const App = ({
<PanelButtons
panelButtons={panelButtons}
currentPanel={currentPanel}
setCurrentPanel={setCurrentPanel}
setCurrentPanel={panel => dispatch(setCurrentPanel(panel))}
onContinue={onContinue}
startSaveTrainedModel={startSaveTrainedModel}
dataToSave={dataToSave}
saveStatus={saveStatus}
saveResponseData={saveResponseData}
isSaveComplete={isSaveComplete}
Expand All @@ -306,18 +293,4 @@ const App = ({
);
};

export default connect(
(state: RootState) => ({
panelButtons: getPanelButtons(state),
currentPanel: state.currentPanel,
resultsPhase: state.resultsPhase,
dataToSave: getTrainedModelDataToSave(state),
saveStatus: state.saveStatus,
saveResponseData: state.saveResponseData,
}),
(dispatch: Dispatch) => ({
setCurrentPanel(panel: string) {
dispatch(setCurrentPanel(panel));
},
}),
)(App);
export default App;
19 changes: 6 additions & 13 deletions frontend/packages/labs/ailab/src/UIComponents/AddFeatureButton.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
/* React component to handle selecting columns as features. */
import {connect} from 'react-redux';

import {styles} from '../constants';
import {useAppDispatch} from '../hooks';
import I18n from '../i18n';
import {addSelectedFeature} from '../redux';

interface AddFeatureButtonProps {
column?: string;
addSelectedFeature: (column: string) => void;
}

const AddFeatureButton = ({
column,
addSelectedFeature,
}: AddFeatureButtonProps) => {
const AddFeatureButton = ({column}: AddFeatureButtonProps) => {
const dispatch = useAppDispatch();

const addFeature = (event: React.MouseEvent, column: string) => {
addSelectedFeature(column);
dispatch(addSelectedFeature(column));
event.preventDefault();
};

Expand All @@ -31,8 +28,4 @@ const AddFeatureButton = ({
);
};

export default connect(null, dispatch => ({
addSelectedFeature(column: string) {
dispatch(addSelectedFeature(column));
},
}))(AddFeatureButton);
export default AddFeatureButton;
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
/* React component to handle setting datatype for selected columns. */
import {connect} from 'react-redux';

import {ColumnTypes} from '../constants';
import {useAppDispatch} from '../hooks';
import I18n from '../i18n';
import {setColumnsByDataType} from '../redux';

interface ColumnDataTypeDropdownProps {
columnId?: string;
currentDataType?: string;
setColumnsByDataType: (column: string, dataType: string) => void;
}

const ColumnDataTypeDropdown = ({
columnId,
currentDataType,
setColumnsByDataType,
}: ColumnDataTypeDropdownProps) => {
const dispatch = useAppDispatch();

const handleChangeDataType = (
event: React.ChangeEvent<HTMLSelectElement>,
feature: string,
) => {
event.preventDefault();
setColumnsByDataType(feature, event.target.value);
dispatch(setColumnsByDataType(feature, event.target.value));
};

return (
Expand All @@ -42,8 +41,4 @@ const ColumnDataTypeDropdown = ({
);
};

export default connect(null, dispatch => ({
setColumnsByDataType(column: string, dataType: string) {
dispatch(setColumnsByDataType(column, dataType));
},
}))(ColumnDataTypeDropdown);
export default ColumnDataTypeDropdown;
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
/* React component to handle showing details of categorical columns. */
import {Bar} from 'react-chartjs-2';
import {connect} from 'react-redux';

import {colors, styles} from '../constants';
import {getLocalizedValue} from '../helpers/valueDetails';
import {useAppSelector} from '../hooks';
import I18n from '../i18n';
import type {RootState} from '../redux';
import {getCategoricalColumnDetails} from '../selectors/currentColumnSelectors';
import type {CategoricalColumnDetails} from '../types';

interface ColumnDetailsCategoricalProps {
columnDetails: CategoricalColumnDetails;
datasetId: string;
}

const chartOptions = {
scales: {
Expand All @@ -28,10 +21,10 @@ const chartOptions = {
maintainAspectRatio: false,
};

const ColumnDetailsCategorical = ({
columnDetails,
datasetId,
}: ColumnDetailsCategoricalProps) => {
const ColumnDetailsCategorical = () => {
const columnDetails = useAppSelector(getCategoricalColumnDetails);
const datasetId = useAppSelector(state => state.metadata?.name || 'unknown');

const {id, uniqueOptions, frequencies} = columnDetails;
const labels = uniqueOptions && Object.values(uniqueOptions);
const localizedLabels = labels.map(option =>
Expand Down Expand Up @@ -74,10 +67,4 @@ const ColumnDetailsCategorical = ({
);
};

export default connect(
(state: RootState) => ({
columnDetails: getCategoricalColumnDetails(state),
datasetId: state.metadata?.name || 'unknown',
}),
{},
)(ColumnDetailsCategorical);
export default ColumnDetailsCategorical;
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
/* React component to handle showing details of numerical columns. */
import {connect} from 'react-redux';

import {styles} from '../constants';
import {useAppSelector} from '../hooks';
import I18n from '../i18n';
import type {RootState} from '../redux';
import {getNumericalColumnDetails} from '../selectors/currentColumnSelectors';
import type {NumericalColumnDetails} from '../types';

interface ColumnDetailsNumericalProps {
columnDetails: NumericalColumnDetails;
}
const ColumnDetailsNumerical = () => {
const columnDetails = useAppSelector(getNumericalColumnDetails);

const ColumnDetailsNumerical = ({
columnDetails,
}: ColumnDetailsNumericalProps) => {
const {extrema, containsOnlyNumbers} = columnDetails;

return (
Expand All @@ -35,9 +28,4 @@ const ColumnDetailsNumerical = ({
);
};

export default connect(
(state: RootState) => ({
columnDetails: getNumericalColumnDetails(state),
}),
{},
)(ColumnDetailsNumerical);
export default ColumnDetailsNumerical;
31 changes: 8 additions & 23 deletions frontend/packages/labs/ailab/src/UIComponents/ColumnInspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
React component to handle displaying details, including data visualizations,
for selected columns.
*/
import {connect} from 'react-redux';

import {styles, ColumnTypes} from '../constants';
import {getLocalizedColumnName} from '../helpers/columnDetails';
import {useAppSelector} from '../hooks';
import I18n from '../i18n';
import type {RootState} from '../redux';
import {getCurrentColumnDetails} from '../selectors/currentColumnSelectors';
import type {CurrentColumnInspector} from '../types';

import AddFeatureButton from './AddFeatureButton';
import ColumnDataTypeDropdown from './ColumnDataTypeDropdown';
Expand All @@ -21,17 +18,12 @@ import ScrollableContent from './ScrollableContent';
import SelectLabelButton from './SelectLabelButton';
import UniqueOptionsWarning from './UniqueOptionsWarning';

interface ColumnInspectorProps {
currentColumnDetails: CurrentColumnInspector | undefined;
currentPanel: string;
datasetId: string | undefined;
}

const ColumnInspector = ({
currentColumnDetails,
currentPanel,
datasetId,
}: ColumnInspectorProps) => {
const ColumnInspector = () => {
const currentColumnDetails = useAppSelector(getCurrentColumnDetails);
const currentPanel = useAppSelector(state => state.currentPanel);
const datasetId = useAppSelector(
state => state.metadata && state.metadata.name,
);
const selectingFeatures = currentPanel === 'dataDisplayFeatures';
const selectingLabel = currentPanel === 'dataDisplayLabel';

Expand Down Expand Up @@ -106,11 +98,4 @@ const ColumnInspector = ({
);
};

export default connect(
(state: RootState) => ({
currentColumnDetails: getCurrentColumnDetails(state),
currentPanel: state.currentPanel,
datasetId: state.metadata && state.metadata.name,
}),
{},
)(ColumnInspector);
export default ColumnInspector;
18 changes: 5 additions & 13 deletions frontend/packages/labs/ailab/src/UIComponents/CrossTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@
label values, with a heatmap style applied.
*/
import {useCallback} from 'react';
import {connect} from 'react-redux';

import {styles} from '../constants';
import {getLocalizedValue} from '../helpers/valueDetails';
import {useAppSelector} from '../hooks';
import I18n from '../i18n';
import type {RootState} from '../redux';
import {getCrossTabData} from '../selectors/visualizationSelectors';
import type {CrossTabData} from '../types';

import ScrollableContent from './ScrollableContent';

interface CrossTabProps {
crossTabData: CrossTabData | null;
datasetId: string;
}

const CrossTab = ({crossTabData, datasetId}: CrossTabProps) => {
const CrossTab = () => {
const crossTabData = useAppSelector(getCrossTabData);
const datasetId = useAppSelector(state => state.metadata?.name || 'unknown');
const getCellStyle = useCallback((percent: number) => {
return {
...(styles as Record<string, React.CSSProperties>)[
Expand Down Expand Up @@ -139,7 +134,4 @@ const CrossTab = ({crossTabData, datasetId}: CrossTabProps) => {
);
};

export default connect((state: RootState) => ({
crossTabData: getCrossTabData(state),
datasetId: state.metadata?.name || 'unknown',
}))(CrossTab);
export default CrossTab;
Loading
Loading