Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firefly 1420 cleanup items #1505

Merged
merged 5 commits into from
Feb 29, 2024
Merged
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
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