mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 17:08:34 +00:00
Show/hide table buttons (#682)
* Show/hide table buttons * clientSide pagination * Remove unwanted comment Co-authored-by: arpitnath <arpitnath42@gmail.com>
This commit is contained in:
parent
3a09f40e35
commit
c55cad0f24
5 changed files with 102 additions and 72 deletions
|
|
@ -6,15 +6,25 @@ export const Pagination = function Pagination({
|
|||
autoGotoPage,
|
||||
autoCanNextPage,
|
||||
autoPageCount,
|
||||
autoPageOptions
|
||||
autoPageOptions,
|
||||
lastActivePageIndex
|
||||
}) {
|
||||
const [pageIndex, setPageIndex] = useState(1);
|
||||
const [pageIndex, setPageIndex] = useState(lastActivePageIndex ?? 1);
|
||||
const [pageCount, setPageCount] = useState(autoPageCount);
|
||||
|
||||
useEffect(() => {
|
||||
setPageCount(autoPageCount);
|
||||
}, [autoPageCount]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if(serverSide && lastActivePageIndex > 0) {
|
||||
setPageCount(lastActivePageIndex)
|
||||
} else if(serverSide || lastActivePageIndex === 0) {
|
||||
setPageIndex(1)
|
||||
}
|
||||
}, [serverSide, lastActivePageIndex ])
|
||||
|
||||
function gotoPage(page) {
|
||||
setPageIndex(page);
|
||||
onPageIndexChanged(page);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,15 @@ export function Table({
|
|||
const displaySearchBoxProperty = component.definition.properties.displaySearchBox;
|
||||
const displaySearchBox = displaySearchBoxProperty ? displaySearchBoxProperty.value : true;
|
||||
|
||||
const showDownloadButtonProperty = component.definition.properties.showDownloadButton?.value;
|
||||
const showDownloadButton = resolveWidgetFieldValue(showDownloadButtonProperty, currentState) ?? true; // default is true for backward compatibility
|
||||
|
||||
const showFilterButtonProperty = component.definition.properties.showFilterButton?.value;
|
||||
const showFilterButton = resolveWidgetFieldValue(showFilterButtonProperty, currentState) ?? true; // default is true for backward compatibility
|
||||
|
||||
const clientSidePaginationProperty = component.definition.properties.clientSidePagination?.value;
|
||||
const clientSidePagination = resolveWidgetFieldValue(clientSidePaginationProperty, currentState) ?? !serverSidePagination; // default is true for backward compatibility
|
||||
|
||||
const tableTypeProperty = component.definition.styles.tableType;
|
||||
let tableType = tableTypeProperty ? tableTypeProperty.value : 'table-bordered';
|
||||
tableType = tableType === '' ? 'table-bordered' : tableType;
|
||||
|
|
@ -584,7 +593,7 @@ export function Table({
|
|||
columns,
|
||||
data,
|
||||
defaultColumn,
|
||||
initialState: { pageIndex: 0, pageSize: serverSidePagination ? -1 : 10}, // pageSize should be unset if server-side pagination is enabled
|
||||
initialState: { pageIndex: 0, pageSize: -1},
|
||||
pageCount: -1,
|
||||
manualPagination: false,
|
||||
getExportFileBlob
|
||||
|
|
@ -598,6 +607,18 @@ export function Table({
|
|||
useExportData
|
||||
);
|
||||
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
if(serverSidePagination || !clientSidePagination) {
|
||||
setPageSize(-1)
|
||||
}
|
||||
if(!serverSidePagination && clientSidePagination) {
|
||||
setPageSize(10)
|
||||
}
|
||||
|
||||
},[clientSidePagination, serverSidePagination])
|
||||
|
||||
useEffect(() => {
|
||||
const pageData = page.map(row => row.original);
|
||||
const currentData = rows.map(row => row.original);;
|
||||
|
|
@ -669,36 +690,15 @@ export function Table({
|
|||
onClick={event => {event.stopPropagation(); onComponentClick(id, component)}}
|
||||
>
|
||||
{/* Show top bar unless search box is disabled and server pagination is enabled */}
|
||||
{(!(!displaySearchBox && serverSidePagination) &&
|
||||
{displaySearchBox &&
|
||||
<div className="card-body border-bottom py-3 jet-data-table-header">
|
||||
<div className="d-flex">
|
||||
{!serverSidePagination &&
|
||||
<div className="text-muted">
|
||||
Show
|
||||
<div className="mx-2 d-inline-block">
|
||||
<select
|
||||
value={pageSize}
|
||||
className="form-control form-control-sm"
|
||||
onChange={(e) => {
|
||||
setPageSize(Number(e.target.value));
|
||||
}}
|
||||
>
|
||||
{[10, 20, 30, 40, 50].map((itemsCount) => (
|
||||
<option key={itemsCount} value={itemsCount}>
|
||||
{itemsCount}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
entries
|
||||
</div>
|
||||
}
|
||||
{displaySearchBox && <div className="ms-auto text-muted">
|
||||
<GlobalFilter />
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
}
|
||||
<div className="table-responsive jet-data-table">
|
||||
<table {...getTableProps()} className={`table table-vcenter table-nowrap ${tableType}`} style={computedStyles}>
|
||||
<thead>
|
||||
|
|
@ -768,53 +768,62 @@ export function Table({
|
|||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="card-footer d-flex align-items-center jet-table-footer">
|
||||
<div className="table-footer row">
|
||||
<div className="col">
|
||||
<Pagination
|
||||
serverSide={serverSidePagination}
|
||||
autoGotoPage={gotoPage}
|
||||
autoCanNextPage={canNextPage}
|
||||
autoPageCount={pageCount}
|
||||
autoPageOptions={pageOptions}
|
||||
onPageIndexChanged={onPageIndexChanged}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{Object.keys(componentState.changeSet || {}).length > 0 && (
|
||||
{(clientSidePagination || serverSidePagination || Object.keys(componentState.changeSet || {}).length > 0 || showFilterButton || showDownloadButton) &&
|
||||
<div className="card-footer d-flex align-items-center jet-table-footer">
|
||||
<div className="table-footer row">
|
||||
<div className="col">
|
||||
<button
|
||||
className={`btn btn-primary btn-sm ${componentState.isSavingChanges ? 'btn-loading' : ''}`}
|
||||
onClick={() => onEvent('onBulkUpdate', { component }).then(() => {
|
||||
handleChangesSaved();
|
||||
})
|
||||
}
|
||||
>
|
||||
Save Changes
|
||||
</button>
|
||||
<button className="btn btn-light btn-sm mx-2" onClick={() => handleChangesDiscarded()}>
|
||||
Discard changes
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="col-auto">
|
||||
<span data-tip="Filter data" className="btn btn-light btn-sm p-1 mx-2" onClick={() => showFilters()}>
|
||||
<img src="/assets/images/icons/filter.svg" width="13" height="13" />
|
||||
{filters.length > 0 &&
|
||||
<a className="badge bg-azure" style={{width: '4px', height: '4px', marginTop: '5px'}}></a>
|
||||
{(clientSidePagination || serverSidePagination) &&
|
||||
<Pagination
|
||||
lastActivePageIndex={currentState.components[component.name]?.pageIndex ?? 1 }
|
||||
serverSide={serverSidePagination}
|
||||
autoGotoPage={gotoPage}
|
||||
autoCanNextPage={canNextPage}
|
||||
autoPageCount={pageCount}
|
||||
autoPageOptions={pageOptions}
|
||||
onPageIndexChanged={onPageIndexChanged}
|
||||
/>
|
||||
}
|
||||
</span>
|
||||
<span
|
||||
data-tip="Download as CSV"
|
||||
className="btn btn-light btn-sm p-1"
|
||||
onClick={() => exportData('csv', true)}
|
||||
>
|
||||
<img src="/assets/images/icons/download.svg" width="13" height="13" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{Object.keys(componentState.changeSet || {}).length > 0 && (
|
||||
<div className="col">
|
||||
<button
|
||||
className={`btn btn-primary btn-sm ${componentState.isSavingChanges ? 'btn-loading' : ''}`}
|
||||
onClick={() => onEvent('onBulkUpdate', { component }).then(() => {
|
||||
handleChangesSaved();
|
||||
})
|
||||
}
|
||||
>
|
||||
Save Changes
|
||||
</button>
|
||||
<button className="btn btn-light btn-sm mx-2" onClick={() => handleChangesDiscarded()}>
|
||||
Discard changes
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="col-auto">
|
||||
{showFilterButton &&
|
||||
<span data-tip="Filter data" className="btn btn-light btn-sm p-1 mx-2" onClick={() => showFilters()}>
|
||||
<img src="/assets/images/icons/filter.svg" width="13" height="13" />
|
||||
{filters.length > 0 &&
|
||||
<a className="badge bg-azure" style={{width: '4px', height: '4px', marginTop: '5px'}}></a>
|
||||
}
|
||||
</span>
|
||||
}
|
||||
{showDownloadButton &&
|
||||
<span
|
||||
data-tip="Download as CSV"
|
||||
className="btn btn-light btn-sm p-1"
|
||||
onClick={() => exportData('csv', true)}
|
||||
>
|
||||
<img src="/assets/images/icons/download.svg" width="13" height="13" />
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{isFiltersVisible && (
|
||||
<div className="table-filters card">
|
||||
<div className="card-header row">
|
||||
|
|
|
|||
|
|
@ -10,10 +10,13 @@ export const componentTypes = [
|
|||
loadingState: { type: 'code', displayName: 'Loading state' },
|
||||
columns: { type: 'array', displayName: 'Table Columns' },
|
||||
serverSidePagination: { type: 'toggle', displayName: 'Server-side pagination' },
|
||||
clientSidePagination: { type: 'toggle', displayName: 'Client-side pagination' },
|
||||
serverSideSearch: { type: 'toggle', displayName: 'Server-side search' },
|
||||
actionButtonBackgroundColor: { type: 'color', displayName: 'Background color' },
|
||||
actionButtonTextColor: { type: 'color', displayName: 'Text color' },
|
||||
displaySearchBox: { type: 'toggle', displayName: 'Display search box' },
|
||||
displaySearchBox: { type: 'toggle', displayName: 'Show search box' },
|
||||
showDownloadButton: { type: 'toggle', displayName: 'Show download button' },
|
||||
showFilterButton: { type: 'toggle', displayName: 'Show filter button' },
|
||||
},
|
||||
others: {
|
||||
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop? ' },
|
||||
|
|
@ -62,7 +65,10 @@ export const componentTypes = [
|
|||
"{{ [ \n\t\t{ id: 1, name: 'Sarah', email: 'sarah@example.com'}, \n\t\t{ id: 2, name: 'Lisa', email: 'lisa@example.com'}, \n\t\t{ id: 3, name: 'Sam', email: 'sam@example.com'}, \n\t\t{ id: 4, name: 'Jon', email: 'jon@example.com'} \n] }}",
|
||||
},
|
||||
serverSidePagination: { value: false },
|
||||
clientSidePagination: { value: true },
|
||||
displaySearchBox: { value: true },
|
||||
showDownloadButton: { value: true },
|
||||
showFilterButton: { value: true },
|
||||
columns: {
|
||||
value: [
|
||||
{ name: 'id', id: 'e3ecbf7fa52c4d7210a93edb8f43776267a489bad52bd108be9588f790126737' },
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ class Table extends React.Component {
|
|||
if (!component.component.definition.properties.displaySearchBox)
|
||||
paramUpdated({ name: 'displaySearchBox' }, 'value', true, 'properties');
|
||||
const displaySearchBox = component.component.definition.properties.displaySearchBox.value;
|
||||
const serverSidePagination = component.component.definition.properties.serverSidePagination?.value ?? false;
|
||||
|
||||
return (
|
||||
<div className="properties-container p-2 " key={this.props.component.id}>
|
||||
|
|
@ -589,8 +590,12 @@ class Table extends React.Component {
|
|||
<hr></hr>
|
||||
|
||||
{renderElement(component, componentMeta, paramUpdated, dataQueries, 'serverSidePagination', 'properties', currentState)}
|
||||
{!serverSidePagination && renderElement(component, componentMeta, paramUpdated, dataQueries, 'clientSidePagination', 'properties', currentState)}
|
||||
{renderElement(component, componentMeta, paramUpdated, dataQueries, 'displaySearchBox', 'properties', currentState)}
|
||||
{displaySearchBox && renderElement(component, componentMeta, paramUpdated, dataQueries, 'serverSideSearch', 'properties', currentState)}
|
||||
{renderElement(component, componentMeta, paramUpdated, dataQueries, 'showDownloadButton', 'properties', currentState)}
|
||||
{renderElement(component, componentMeta, paramUpdated, dataQueries, 'showFilterButton', 'properties', currentState)}
|
||||
|
||||
{Object.keys(componentMeta.styles).map((style) => renderElement(component, componentMeta, paramUpdated, dataQueries, style, 'styles', currentState, components))}
|
||||
<div className="hr-text">Events</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { ToolTip } from './Components/ToolTip';
|
|||
export const Toggle = ({
|
||||
param, definition, onChange, paramType, componentMeta
|
||||
}) => {
|
||||
const value = definition ? definition.value : false;
|
||||
const value = definition?.value !== false ?? false;
|
||||
const paramMeta = componentMeta[paramType][param.name];
|
||||
const displayName = paramMeta.displayName || param.name;
|
||||
|
||||
|
|
@ -21,4 +21,4 @@ export const Toggle = ({
|
|||
</label>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
Loading…
Reference in a new issue