Skip to content

Commit

Permalink
Merge pull request #1505 from Caltech-IPAC/FIREFLY-1420_cleanup_items
Browse files Browse the repository at this point in the history
Firefly 1420 cleanup items
  • Loading branch information
loitly authored Feb 29, 2024
2 parents 01632c0 + 9b83472 commit b941c25
Show file tree
Hide file tree
Showing 13 changed files with 277 additions and 260 deletions.
51 changes: 37 additions & 14 deletions src/firefly/js/tables/TableUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ export function tableDetailsView(tbl_id, highlightedRow, details_tbl_id) {
}

/**
* returns an object map of the column name and its width.
* returns an array of the value with the maximum length for each column.
* The width is the number of characters needed to display
* the header and the data in a table given columns and dataAry.
* @param {TableColumn[]} columns array of column object
Expand All @@ -1117,39 +1117,62 @@ export function tableDetailsView(tbl_id, highlightedRow, details_tbl_id) {
* @param {number} opt.maxAryWidth maximum width of column with array values
* @param {number} opt.maxColWidth maximum width of column without array values
* @param {boolean} opt.useWidth use width and prefWidth props in calculation
* @returns {number[]} an array of widths corresponding to the given columns array.
* @returns {string[]} an array of values corresponding to the given columns array.
* @memberof firefly.util.table
* @func calcColumnWidths
*/
export function calcColumnWidths(columns, dataAry,
export function getColMaxValues(columns, dataAry,
{
maxAryWidth = Number.MAX_SAFE_INTEGER,
maxColWidth = Number.MAX_SAFE_INTEGER,
useWidth = true,
useCnameMultiplier = false,
}={}) {
return columns.map( (cv, idx) => {

let width = useWidth? cv.prefWidth || cv.width : 0;
const width = useWidth? cv.prefWidth || cv.width : 0;
if (width) {
return width;
return 'O'.repeat(width); // O is a good reference for average width of a character
}
const cnameLength = (cv.label || cv.name)?.length * (useCnameMultiplier ? 1.25 : 1);

width = Math.max(cnameLength, get(cv, 'units.length', 0), getTypeLabel(cv).length, get(cv, 'nullString.length', 0));
let maxVal = '';

// the 4 headers
[cv.label || cv.name, cv.units, getTypeLabel(cv), cv.nullString].forEach( (v) => {
if (v?.length > maxVal.length) maxVal = v;
});

// the data
dataAry.forEach((row) => {
const v = formatValue(columns[idx], row[idx]);
width = Math.max(width, v.length);
if (v.length > maxVal.length) maxVal = v;
});

if (cv.arraySize) {
width = Math.min(width, maxAryWidth);
}
width = Math.min(width, maxColWidth);
return width;
// limits
if (cv.arraySize && maxVal.length > maxAryWidth) maxVal = maxVal.substr(0, maxAryWidth);
if (maxVal.length > maxColWidth) maxVal = maxVal.substr(0, maxColWidth);

return maxVal;
});
}

/**
* returns an array of the maximum width for each column.
* The width is the number of characters needed to display
* the header and the data in a table given columns and dataAry.
* @param {TableColumn[]} columns array of column object
* @param {TableData} dataAry array of array.
* @param {object} opt options
* @param {number} opt.maxAryWidth maximum width of column with array values
* @param {number} opt.maxColWidth maximum width of column without array values
* @param {boolean} opt.useWidth use width and prefWidth props in calculation
* @returns {number[]} an array of widths corresponding to the given columns array.
* @memberof firefly.util.table
* @func calcColumnWidths
*/
export function calcColumnWidths(columns, dataAry, opt) {
return getColMaxValues(columns, dataAry, opt).map((v) => v.length);
}

/**
* There are some inconsistencies in how a request is created.
* This fixes any of the inconsistencies it finds.
Expand Down
15 changes: 6 additions & 9 deletions src/firefly/js/tables/ui/AddOrUpdateColumn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ import {useStoreConnector} from '../../ui/SimpleComponent.jsx';
import {SuggestBoxInputField} from '../../ui/SuggestBoxInputField.jsx';

import MAGNIFYING_GLASS from 'images/icons-2014/magnifyingGlass.png';
import INSERT_COLUMN from 'html/images/insert-col-right-24-24.png';
import INFO from 'html/images/info-icon.png';
import {RadioGroupInputField} from '../../ui/RadioGroupInputField.jsx';
import {setSelectInfo} from 'firefly/tables/TableRequestUtil.js';
import {dispatchHideDialog} from 'firefly/core/ComponentCntlr.js';
import {FilterInfo} from 'firefly/tables/FilterInfo.js';
import {AddColumnButton} from 'firefly/visualize/ui/Buttons.jsx';
import {RequiredFieldMsg} from 'firefly/ui/InputField.jsx';
import {Stacker} from 'firefly/ui/Stacker.jsx';


let hideExpPopup;
Expand Down Expand Up @@ -128,14 +128,11 @@ export const AddOrUpdateColumn = React.memo(({tbl_ui_id, tbl_id, hidePopup, edit
]}/>
{mode === 'Custom' ? <CustomFields {...{tbl_ui_id, tbl_id, groupKey, editColName}}/> : <PresetFields {...{tbl_id, editColName}}/>}
</FieldGroup>
<Stack direction='row' justifyContent='space-between'>
<Stack direction='row' spacing={1} alignItems='center'>
<Button color='primary' variant='solid' onClick={doUpdate}>{buttonLabel}</Button>
{editColName && DelBtn}
<Button onClick={() => hidePopup?.()}> Cancel</Button>
</Stack>
<HelpIcon helpId={'tables.addColumn'}/>
</Stack>
<Stacker endDecorator={<HelpIcon helpId={'tables.addColumn'}/>}>
<Button color='primary' variant='solid' onClick={doUpdate}>{buttonLabel}</Button>
{editColName && DelBtn}
<Button onClick={() => hidePopup?.()}> Cancel</Button>
</Stacker>
</Stack>
);

Expand Down
16 changes: 12 additions & 4 deletions src/firefly/js/tables/ui/BasicTableView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {Column, Table} from 'fixed-data-table-2';
import {wrapResizer} from '../../ui/SizeMeConfig.js';
import {get, set, isEmpty, isUndefined, omitBy, pick} from 'lodash';

import {calcColumnWidths, getCellValue, getColumns, getProprietaryInfo, getTableState, getTableUiById, getTblById, hasRowAccess, isClientTable, tableTextView, TBL_STATE, uniqueTblUiId} from '../TableUtil.js';
import {calcColumnWidths, getCellValue, getColMaxValues, getColumns, getProprietaryInfo, getTableState, getTableUiById, getTblById, hasRowAccess, isClientTable, tableTextView, TBL_STATE, uniqueTblUiId} from '../TableUtil.js';
import {SelectInfo} from '../SelectInfo.js';
import {FilterInfo} from '../FilterInfo.js';
import {SortInfo} from '../SortInfo.js';
import {CellWrapper, HeaderCell, makeDefaultRenderer, SelectableCell, SelectableHeader} from './TableRenderer.js';
import {CellWrapper, getPxWidth, HeaderCell, headerLevel, headerStyle, makeDefaultRenderer, SelectableCell, SelectableHeader} from './TableRenderer.js';
import {useStoreConnector} from '../../ui/SimpleComponent.jsx';
import {dispatchTableUiUpdate, TBL_UI_UPDATE} from '../TablesCntlr.js';
import {Logger} from '../../util/Logger.js';
Expand Down Expand Up @@ -325,8 +325,16 @@ function correctScrollLeftIfNeeded(totalColWidths, scrollLeft, width, triggeredB
}

function columnWidthsInPixel(columns, data) {
return calcColumnWidths(columns, data, {maxColWidth: 100, maxAryWidth: 30, useCnameMultiplier: true}) // set max width for array columns
.map( (w) => (w + 2) * 7);

const maxVals = getColMaxValues(columns, data, {maxColWidth: 100, maxAryWidth: 30});

const paddings = 8;
return maxVals.map((text, idx) => {
const header = columns[idx].label || columns[idx].name;
const style = header === text ? headerStyle : {fontSize:12};
text = text.replace(/[^a-zA-Z0-9]/g, 'O'); // some non-alphanum values can be very narrow. use 'O' in place of them.
return getPxWidth({text, ...style}) + paddings;
});
}

function defHighlightedRowHandler(tbl_id, hlRowIdx, startIdx) {
Expand Down
6 changes: 3 additions & 3 deletions src/firefly/js/tables/ui/TableInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export function TableInfo({tbl_id, tabsProps, ...props}) {
const jobId = getJobIdFromTblId(tbl_id);

return (
<Stack p={1} height={1} spacing={1} {...props}>
<StatefulTabs componentKey='TablePanelOptions' {...tabsProps}>
<Stack p={1} height={1} spacing={1} overflow='hidden' {...props}>
<StatefulTabs componentKey='TablePanelOptions' {...tabsProps} sx={{overflow:'auto'}}>
{jobId &&
<Tab name='Job Info'>
<JobInfo jobId={jobId}/>
Expand All @@ -36,7 +36,7 @@ export function TableInfo({tbl_id, tabsProps, ...props}) {
</div>
</Tab>
</StatefulTabs>
<Stack alignItems='flex-end'>
<Stack alignItems='end' pr={1}>
<HelpIcon helpId='tables.info'/>
</Stack>
</Stack>
Expand Down
81 changes: 33 additions & 48 deletions src/firefly/js/tables/ui/TablePanelOptions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
*/

import React, {useEffect} from 'react';
import React, {useCallback, useEffect} from 'react';
import PropTypes from 'prop-types';
import {Box, Button, Stack, ToggleButtonGroup, Typography} from '@mui/joy';
import {Box, Button, Checkbox, Divider, Stack, Typography} from '@mui/joy';
import {badgeClasses} from '@mui/joy/Badge';

import {cloneDeep, get, isEmpty} from 'lodash';
Expand Down Expand Up @@ -33,6 +33,7 @@ import {BY_SCROLL} from './BasicTableView.jsx';
import EDIT from 'html/images/16x16_edit_icon.png';
import {MAX_ROW} from 'firefly/tables/TableRequestUtil';
import {ClearFilterButton} from 'firefly/visualize/ui/Buttons.jsx';
import {Stacker} from 'firefly/ui/Stacker.jsx';


export const TablePanelOptions = React.memo(({tbl_ui_id, tbl_id, onChange, onOptionReset, clearFilter}) => {
Expand Down Expand Up @@ -81,31 +82,29 @@ export const TablePanelOptions = React.memo(({tbl_ui_id, tbl_id, onChange, onOpt
};

const onSqlFilterChanged = ({op, sql}) => onChange({sqlFilter: sql ? `${op}::${sql}` : ''});
const actions = useCallback(() => <OptionsFilterStats tbl_id={ctm_tbl_id}/>, [ctm_tbl_id]);

return (
<Stack height={1} p={1} pt={0} boxSizing='border-box' spacing={1}>
<Stack height={1} p={1} pt={0} spacing={1}>
<Options {...{uiState, tbl_id, tbl_ui_id, ctm_tbl_id, onOptionReset, onChange}} />
<StatefulTabs componentKey='TablePanelOptions' defaultSelected={0} actions={() => <OptionsFilterStats tbl_id={ctm_tbl_id}/>}>
<Tab name='Column Options'>
<ColumnOptions {...{tbl_id, tbl_ui_id, ctm_tbl_id, onChange}} />
</Tab>
{showAdvFilter &&
<Stack flexGrow={1} overflow='hidden'>
<StatefulTabs componentKey={`${tbl_id}-options`} defaultSelected={0} actions={actions}>
<Tab name='Column Options'>
<ColumnOptions {...{tbl_id, tbl_ui_id, ctm_tbl_id, onChange}} />
</Tab>
{showAdvFilter &&
<Tab name={advFilterName} label={label()}>
<div style={{display: 'flex', flex: '1 1 0', position: 'relative'}}>
<SqlTableFilter {...{tbl_id, tbl_ui_id, onChange}} onChange={onSqlFilterChanged} />
</div>
<SqlTableFilter {...{tbl_id, tbl_ui_id, onChange}} onChange={onSqlFilterChanged} />
</Tab>
}
</StatefulTabs>
{showTblPrefMsg && <TablePrefMsg/>}
<Stack direction='row' justifyContent='space-between'>
<Stack direction='row' alignItems='center' spacing={1}>
<Button variant='solid' color='primary' onClick={onClose}>Close</Button>
<Button onClick={onReset}>Reset column selection</Button>
<Button onClick={onRemoveFilters}>Remove all filters</Button>
</Stack>
<HelpIcon helpId={'tables.options'}/>
}
</StatefulTabs>
</Stack>
{showTblPrefMsg && <TablePrefMsg/>}
<Stacker endDecorator={<HelpIcon helpId={'tables.options'}/>}>
<Button variant='solid' color='primary' onClick={onClose}>Close</Button>
<Button onClick={onReset}>Reset column selection</Button>
<Button onClick={onRemoveFilters}>Remove all filters</Button>
</Stacker>
</Stack>
);
});
Expand Down Expand Up @@ -135,41 +134,27 @@ function OptionsFilterStats({tbl_id}) {
);
}

function Options({uiState, tbl_id, tbl_ui_id, ctm_tbl_id, onOptionReset, onChange}) {
function Options({uiState, onChange}) {
const {pageSize, showPaging=true, showUnits, allowUnits=true, showTypes, allowTypes=true, showFilters} = uiState || {};

const onPageSize = (pageSize) => {
if (pageSize.valid) {
onChange && onChange({pageSize: pageSize.value});
}
};
const [value, setValue] = React.useState([
showUnits && 'showUnits',
showTypes && 'showTypes',
showFilters && 'showFilters'
].filter((v) => v));
const handleChange =(ev) => {
const bname = ev.target?.value;
onChange({[bname]: ev.target.checked});
};
return (
<Stack direction='row' alignItems='center' justifyContent='space-between'>
<Stack direction='row' spacing={1} alignItems='center'>
<Stack direction='row' spacing={2} alignItems='center'>
<Typography level='title-md'>Show/Hide:</Typography>
<ToggleButtonGroup
variant='outlined'
size='sm'
value={value}
onChange={(ev, val) => {
setValue(val);
const bname = ev.target?.value;
onChange({[bname]: val.includes(bname)});
}}
>
{allowUnits &&
<Button value='showUnits' size='sm'>Units</Button>
}
{allowUnits &&
<Button value='showTypes' size='sm'>Data Type</Button>
}
<Button value='showFilters' size='sm'>Filters</Button>
</ToggleButtonGroup>
<Stack direction='row' spacing={1}>
{allowUnits && <> <Checkbox size='sm' label='Units' value='showUnits' checked={showUnits} onChange={handleChange}/> <Divider orientation='vertical'/></>}
{allowTypes && <> <Checkbox size='sm' label='Data Type' value='showTypes' checked={showTypes} onChange={handleChange}/> <Divider orientation='vertical'/></>}
<Checkbox size='sm' label='Filters' value='showFilters' checked={showFilters} onChange={handleChange}/>
</Stack>
</Stack>
{showPaging && pageSize !== MAX_ROW &&
<InputField
Expand Down Expand Up @@ -255,7 +240,7 @@ export const ColumnOptions = React.memo(({tbl_id, tbl_ui_id, ctm_tbl_id, onChang
};

return (
<div style={{flex: '1 1 0'}}>
<Stack position='relative' flexGrow={1} overflow='hidden'>
<TablePanel
border={false}
tbl_ui_id = {cmt_tbl_ui_id}
Expand All @@ -269,7 +254,7 @@ export const ColumnOptions = React.memo(({tbl_id, tbl_ui_id, ctm_tbl_id, onChang
rowHeight = {26}
highlightedRowHandler = {()=>undefined}
/>
</div>
</Stack>
);
});

Expand Down
Loading

0 comments on commit b941c25

Please sign in to comment.