Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
a54b115
Convert Answer view components from JavaScript to TypeScript
claude Nov 15, 2025
b6abade
Convert Answer and User view components from JavaScript to TypeScript
claude Nov 15, 2025
01c5557
Convert Records and SiteMap view components from JavaScript to TypeSc…
claude Nov 15, 2025
758c45e
Convert Record components from JavaScript to TypeScript (batch 4)
claude Nov 15, 2025
8eca020
Fix TypeScript type errors in converted files
claude Nov 15, 2025
9849d16
Convert Favorites, Record, and Reporter components to TypeScript (bat…
claude Nov 15, 2025
a26799c
Convert Core, Reporter, and AttributeFilter components to TypeScript …
claude Nov 15, 2025
7ed0869
Convert AttributeFilter components to TypeScript (batch 7)
claude Nov 15, 2025
6641dd8
Convert AttributeFilter components to TypeScript (batch 8)
claude Nov 15, 2025
edb5e4e
Convert AttributeFilter components to TypeScript (batch 9)
claude Nov 15, 2025
1d5143a
Convert remaining components to TypeScript (batch 10 - final)
claude Nov 15, 2025
9a72e10
Fix TypeScript compilation errors in converted files
claude Nov 15, 2025
1d64f2d
Fix remaining TypeScript compilation errors
claude Nov 15, 2025
aca1ea6
Fix Histogram duplicate identifier errors
claude Nov 15, 2025
b660efe
Fix TypeScript compilation errors in AttributeFilter, Date components…
claude Nov 15, 2025
a662a29
Fix additional Histogram type errors
claude Nov 15, 2025
147dc30
Fix Core/main.ts TypeScript errors
claude Nov 15, 2025
c333af1
Fix AttributeFilter TypeScript errors
claude Nov 15, 2025
2725dd7
Fix RecordUI TypeScript errors
claude Nov 15, 2025
c0a4a11
Fix additional TypeScript errors
claude Nov 15, 2025
2946de7
Fix additional TypeScript errors
claude Nov 15, 2025
c1feb53
Fix TypeScript errors (batch 1 of remaining errors)
claude Nov 15, 2025
53150ee
Fix TypeScript errors (batch 2)
claude Nov 15, 2025
b4a7386
Fix TypeScript errors (batch 3)
claude Nov 15, 2025
d7fcd68
Fix TypeScript errors in FavoritesList (batch 4)
claude Nov 15, 2025
13e860c
Fix TypeScript errors in Answer component (batch 5)
claude Nov 15, 2025
5f15594
Fix TypeScript errors (batch 6)
claude Nov 15, 2025
afd3227
Fix TypeScript errors in RecordMainCategorySection (batch 7)
claude Nov 15, 2025
733397b
Fix TypeScript errors in Answer component (batch 8)
claude Nov 15, 2025
130cd38
Fix TypeScript errors in RecordTable (batch 9)
claude Nov 15, 2025
84a41b1
Fix TypeScript errors in DownloadFormContainer (batch 10)
claude Nov 15, 2025
c412c5c
Fix TypeScript errors in RecordTable and RecordTableSection (batch 11)
claude Nov 15, 2025
1504f85
Fix TypeScript errors in RecordUI and RecordNavigationSection (batch 12)
claude Nov 15, 2025
79906b2
Fix final TypeScript errors - all 64 errors resolved! (batch 13)
claude Nov 15, 2025
37570ed
Convert Mesa component from JavaScript to TypeScript
claude Nov 15, 2025
856a335
Improve RecordTable type safety using Mesa TypeScript types
claude Nov 15, 2025
ee1a421
Reduce 'as any' assertions in RecordTable and Answer components
claude Nov 15, 2025
56d265d
Improve type safety in utility files by replacing 'as' assertions
claude Nov 15, 2025
e20492a
Add comprehensive TypeScript conversion guide
claude Nov 15, 2025
48cfd25
Update compilation verification guidance in TS conversion guide
claude Nov 15, 2025
09aa101
Add git mv guidance to TypeScript conversion guide
claude Nov 15, 2025
df1f97a
Fix initial TypeScript compilation errors in Mesa components
claude Nov 15, 2025
f883287
Fix all TypeScript compilation errors in Mesa components
claude Nov 15, 2025
5c59a01
Merge remote-tracking branch 'origin/claude/convert-javascript-to-typ…
claude Nov 15, 2025
aa5b808
Fix TableState type definitions and sortDirection case
claude Nov 15, 2025
7856884
Fix Mesa column type mismatches in AttributeFilter components
claude Nov 15, 2025
c62aae5
Fix Mesa type issues in CommonResultTable and MembershipField
claude Nov 15, 2025
ffec370
Fix Mesa state and sort type issues in Answer and ResultTable
claude Nov 15, 2025
24ccd65
Fix Mesa type issues in Strategy components
claude Nov 15, 2025
c6d4709
Fix remaining Mesa type errors - final batch
claude Nov 15, 2025
392a2cd
Improve type safety in AllStrategies - properly type functions
claude Nov 15, 2025
6476b9c
Remove 'as any' assertion in AllStrategies.tsx
claude Nov 15, 2025
86bc4c6
Remove 'as any' assertions in Answer.tsx and ResultTable.tsx
claude Nov 15, 2025
e8d52b3
Remove 'as any' assertions in Strategy view components
claude Nov 15, 2025
af0b61f
fixed up some as anys with regular CC
bobular Nov 16, 2025
201a2e7
fixed up remaining as anys with regular CC
bobular Nov 16, 2025
ab5b064
Fix onExpandedRowsChange type at source in RecordTable
claude Nov 16, 2025
4b8724d
Remove unnecessary type assertions in FavoritesList
claude Nov 16, 2025
a89d10b
Remove unnecessary type assertions in FilterList
claude Nov 16, 2025
406d7f7
Fix type assertions in CategoryUtils
claude Nov 16, 2025
4742713
Add urlSegment to IndividualNode.wdkReference type
claude Nov 16, 2025
d8d4c1d
Use discriminated union for MultiFilter in FilterList
claude Nov 16, 2025
93ae7db
Replace 'as any' with specific type assertion in AttributeAnalysisTabs
claude Nov 16, 2025
d193688
Remove and refine type assertions in Answer and MultiFieldFilter
claude Nov 16, 2025
35acffa
Remove unnecessary 'as any' from natsort call
claude Nov 16, 2025
53d0a97
Refine type assertions in CommonResultTable from 'as any' to specific…
claude Nov 16, 2025
853137a
unnecessary fix I thought was changing behaviour; it wasn't
bobular Nov 17, 2025
903927e
clean up IndeterminateCheckbox
bobular Nov 17, 2025
13ddd81
clean up SelectBox
bobular Nov 17, 2025
baabb59
const style
bobular Nov 17, 2025
423ed4a
fix MesaAction type def and ActionToolbar.tsx
bobular Nov 17, 2025
8f60871
fix getValue and childRow wrong types
bobular Nov 17, 2025
321eed6
update guidance
bobular Nov 17, 2025
0020681
update guidance timestamp
bobular Nov 17, 2025
7785801
more Mesa type safety to satisfy TypeScript 4.9.5
bobular Nov 17, 2025
f2bc57b
more cleanup, including HeadingCell
bobular Nov 17, 2025
c97471c
HeadingRow fixes
bobular Nov 17, 2025
b2f6bbb
mostly Row extends... updates
bobular Nov 17, 2025
d364b78
more cleanup, made fallback behaviour in getSelectedRows in MesaState…
bobular Nov 18, 2025
f843f4e
further clean-up of Mesa and its consumers in wdk-client
bobular Nov 18, 2025
797afe7
tighten boundary assertion
bobular Nov 18, 2025
c5f5cb8
remove two 'as any' related to getHelpText by inlining
bobular Nov 18, 2025
2b132b9
tidy up DateField timeformat issues
bobular Nov 18, 2025
72494e1
Mesa-related typing
bobular Nov 18, 2025
6e8e68d
narrow props for actual use cases
bobular Nov 18, 2025
5cad9e1
fix up EDA-WDK MultiFilter relationship
bobular Nov 18, 2025
48a8846
MembershipField-TableFilter fixes
bobular Nov 18, 2025
4c0eb55
last two eda fixes
bobular Nov 18, 2025
b8ccf17
minor TS fixes for multi-blast
bobular Nov 18, 2025
d02fe08
fix genomics-site for JS-TS convo
bobular Nov 18, 2025
fc3a1dd
fix ortho types
bobular Nov 18, 2025
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
904 changes: 904 additions & 0 deletions CLAUDE-TS-conversion-guide.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,27 @@ import { debounce } from 'lodash';
import MesaTooltip from './MesaTooltip';
import Events from '../Utils/Events';

class AnchoredTooltip extends React.Component {
constructor(props) {
interface Position {
left?: number;
top?: number;
}

interface AnchoredTooltipProps {
className?: string;
children?: React.ReactNode;
content: React.ReactNode;
[key: string]: any;
}

class AnchoredTooltip extends React.Component<AnchoredTooltipProps> {
private childWrapperRef: React.RefObject<HTMLDivElement>;
private listeners: { scroll?: string; resize?: string } = {};
public updatePosition: (() => void) & { cancel: () => void };

constructor(props: AnchoredTooltipProps) {
super(props);
this.getPosition = this.getPosition.bind(this);
this.updatePosition = debounce(this.updatePosition.bind(this), 100);
this.updatePosition = debounce(this._updatePosition.bind(this), 100);
this.componentDidMount = this.componentDidMount.bind(this);
this.componentWillUnmount = this.componentWillUnmount.bind(this);
this.childWrapperRef = React.createRef();
Expand All @@ -22,17 +38,17 @@ class AnchoredTooltip extends React.Component {
}

componentWillUnmount() {
Object.values(this.listeners).forEach((listenerId) =>
Events.remove(listenerId)
);
Object.values(this.listeners).forEach((listenerId) => {
if (listenerId) Events.remove(listenerId);
});
this.updatePosition.cancel();
}

updatePosition() {
_updatePosition() {
this.forceUpdate();
}

getPosition() {
getPosition(): Position | undefined {
const element = this.childWrapperRef.current;
if (!element) return undefined;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';

class BodyLayer extends React.Component {
constructor(props) {
interface BodyLayerProps {
[key: string]: any;
}

class BodyLayer extends React.Component<BodyLayerProps> {
private el: HTMLDivElement;

constructor(props: BodyLayerProps) {
super(props);
// XXX This will have to be guarded if we ever use server side rendering
this.el = document.createElement('div');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
import React from 'react';
import IndeterminateCheckbox from '../../inputs/checkboxes/IndeterminateCheckbox';

class Checkbox extends React.Component {
constructor(props) {
interface CheckboxProps {
checked: boolean;
onChange?: (checked: boolean) => void;
className?: string;
disabled?: boolean;
indeterminate?: boolean;
}

class Checkbox extends React.Component<CheckboxProps> {
constructor(props: CheckboxProps) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick(e) {
handleClick(
isCheckedOrEvent: boolean | React.ChangeEvent<HTMLInputElement>
): void {
let { checked, onChange } = this.props;
if (typeof onChange === 'function') onChange(!!checked);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ import React from 'react';
import Icon from './Icon';
import AnchoredTooltip from './AnchoredTooltip';

class HelpTrigger extends React.Component {
constructor(props) {
interface HelpTriggerProps {
className?: string;
children?: React.ReactNode;
[key: string]: any;
}

class HelpTrigger extends React.Component<HelpTriggerProps> {
constructor(props: HelpTriggerProps) {
super(props);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import React from 'react';

class Icon extends React.PureComponent {
interface IconProps {
fa: string;
className?: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
style?: React.CSSProperties;
}

class Icon extends React.PureComponent<IconProps> {
render() {
let { fa, className, onClick, style } = this.props;
className = `icon fa fa-${fa} ${className || ''}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface MesaTooltipProps {
corner?: string;
position?: Position;
style?: CSSProperties;
getPosition?: () => Position;
getPosition?: () => Position | undefined;
renderHtml?: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';

import { uid, makeClassifier } from '../Utils/Utils';

const modalBoundaryClass = makeClassifier('ModalBoundary');

class ModalBoundary extends React.Component {
constructor(props) {
interface Modal {
_id?: string;
render: React.ComponentType<any>;
[key: string]: any;
}

interface ModalBoundaryProps {
children?: React.ReactNode;
style?: React.CSSProperties;
}

interface ModalBoundaryState {
modals: Modal[];
}

class ModalBoundary extends React.Component<
ModalBoundaryProps,
ModalBoundaryState
> {
constructor(props: ModalBoundaryProps) {
super(props);

this.state = { modals: [] };
Expand All @@ -28,19 +45,19 @@ class ModalBoundary extends React.Component {
);
}

addModal(modal) {
addModal(modal: Modal): string {
let { modals } = this.state;
modal._id = uid();
modals.push(modal);
this.setState({ modals });
return modal._id;
}

triggerModalRefresh() {
triggerModalRefresh(): void {
this.forceUpdate();
}

removeModal(id) {
removeModal(id: string): void {
let { modals } = this.state;
let index = modals.findIndex((modal) => modal._id === id);
if (index < 0) return;
Expand All @@ -55,7 +72,7 @@ class ModalBoundary extends React.Component {

renderModalWrapper() {
const { modals } = this.state;
const style = {
const style: React.CSSProperties = {
top: 0,
left: 0,
width: '100vw',
Expand All @@ -76,10 +93,17 @@ class ModalBoundary extends React.Component {
render() {
const { children, style } = this.props;
const ModalWrapper = this.renderModalWrapper;
const fullStyle = Object.assign({}, style ? style : {}, {
const fullStyle: React.CSSProperties = Object.assign(
{},
style ? style : {},
{
position: 'relative',
}
);
const zIndex = (z: number): React.CSSProperties => ({
position: 'relative',
zIndex: z,
});
const zIndex = (z) => ({ position: 'relative', zIndex: z });

return (
<div
Expand All @@ -95,15 +119,4 @@ class ModalBoundary extends React.Component {
}
}

ModalBoundary.childContextTypes = {
addModal: PropTypes.func,
removeModal: PropTypes.func,
triggerModalRefresh: PropTypes.func,
};

ModalBoundary.propTypes = {
children: PropTypes.oneOfType([PropTypes.node, PropTypes.element]),
style: PropTypes.object,
};

export default ModalBoundary;
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import React from 'react';

class OverScroll extends React.Component {
constructor(props) {
interface OverScrollProps {
className?: string;
height?: number;
children?: React.ReactNode;
}

class OverScroll extends React.Component<OverScrollProps> {
constructor(props: OverScrollProps) {
super(props);
}

render() {
let { className, height } = this.props;
className = 'OverScroll' + (className ? ' ' + className : '');
height = typeof height === 'number' ? height + 'px' : 'none';
const heightValue = typeof height === 'number' ? height + 'px' : 'none';

const style = {
maxHeight: height,
const style: React.CSSProperties = {
maxHeight: heightValue,
overflowY: 'auto',
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import React from 'react';

class SelectBox extends React.PureComponent {
constructor(props) {
interface SelectOption {
name: string;
value: string | number;
}

interface SelectBoxProps {
name?: string;
className?: string;
selected?: string | number;
options?: (SelectOption | string | number)[];
onChange?: (value: string) => void;
}

class SelectBox extends React.PureComponent<SelectBoxProps> {
constructor(props: SelectBoxProps) {
super(props);
this.handleChange = this.handleChange.bind(this);
}

handleChange(e) {
handleChange(e: React.ChangeEvent<HTMLSelectElement>): void {
const { onChange } = this.props;
const value = e.target.value;
if (onChange) onChange(value);
}

getOptions() {
getOptions(): SelectOption[] {
let { options } = this.props;
if (!Array.isArray(options)) return [];
options = options.map((option) => {
const normalizedOptions: SelectOption[] = options.map((option) => {
return typeof option === 'object' && 'name' in option && 'value' in option
? option
: { name: option.toString(), value: option };
});
return options;
return normalizedOptions;
}

render() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,36 +1,45 @@
import React from 'react';

import Icon from '../../../Components/Mesa/Components/Icon';
import Icon from './Icon';

class Toggle extends React.Component {
constructor(props) {
interface ToggleProps {
enabled: boolean;
onChange?: (enabled: boolean) => void;
className?: string;
disabled?: boolean;
style?: React.CSSProperties;
}

class Toggle extends React.Component<ToggleProps> {
constructor(props: ToggleProps) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick(e) {
let { enabled, onChange } = this.props;
handleClick(e: React.MouseEvent): void {
const { enabled, onChange } = this.props;
if (typeof onChange === 'function') onChange(!!enabled);
}

render() {
let { enabled, className, disabled, style } = this.props;
const { enabled, disabled, style } = this.props;
let className = this.props.className;
className = 'Toggle' + (className ? ' ' + className : '');
className += ' ' + (enabled ? 'Toggle-On' : 'Toggle-Off');
className += disabled ? ' Toggle-Disabled' : '';
let offStyle = {
const offStyle: React.CSSProperties = {
fontSize: '1.2rem',
color: '#989898',
};
let onStyle = Object.assign({}, offStyle, {
const onStyle: React.CSSProperties = Object.assign({}, offStyle, {
color: '#198835',
});

return (
<span
style={style}
className={className}
onClick={disabled ? null : this.handleClick}
onClick={disabled ? undefined : this.handleClick}
>
<Icon
fa={enabled ? 'toggle-on' : 'toggle-off'}
Expand Down
Loading
Loading