Newer
Older
piotr.kupczyk@id.ethz.ch
committed
import _ from 'lodash'
import autoBind from 'auto-bind'
piotr.kupczyk@id.ethz.ch
committed
import FileSaver from 'file-saver'
import { stringify } from 'csv-stringify'
piotr.kupczyk@id.ethz.ch
committed
import GridFilterOptions from '@src/js/components/common/grid/GridFilterOptions.js'
piotr.kupczyk@id.ethz.ch
committed
import GridExportOptions from '@src/js/components/common/grid/GridExportOptions.js'
piotr.kupczyk@id.ethz.ch
committed
import GridPagingOptions from '@src/js/components/common/grid/GridPagingOptions.js'
import GridSortingOptions from '@src/js/components/common/grid/GridSortingOptions.js'
import compare from '@src/js/common/compare.js'
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
const LOCAL_GRID_RELOAD_PERIOD = 200
const REMOTE_GRID_RELOAD_PERIOD = 500
piotr.kupczyk@id.ethz.ch
committed
piotr.kupczyk@id.ethz.ch
committed
export default class GridController {
constructor() {
autoBind(this)
piotr.kupczyk@id.ethz.ch
committed
this.cache = {}
piotr.kupczyk@id.ethz.ch
committed
}
init(context) {
piotr.kupczyk@id.ethz.ch
committed
const props = context.getProps()
piotr.kupczyk@id.ethz.ch
committed
let filterMode = GridFilterOptions.GLOBAL_FILTER
piotr.kupczyk@id.ethz.ch
committed
if (props.filterModes) {
filterMode = this._getEnumValue(filterMode, props.filterModes)
if (!filterMode) {
filterMode = props.filterModes.length > 0 ? props.filterModes[0] : null
}
}
piotr.kupczyk@id.ethz.ch
committed
let sortings = []
piotr.kupczyk@id.ethz.ch
committed
if (props.sortings) {
props.sortings.forEach(sorting => {
sortings.push({
columnName: sorting.columnName,
sortDirection: sorting.sortDirection
? sorting.sortDirection
: GridSortingOptions.ASC
})
})
} else if (props.sort) {
piotr.kupczyk@id.ethz.ch
committed
sortings.push({
columnName: props.sort,
sortDirection: props.sortDirection
? props.sortDirection
: GridSortingOptions.ASC
})
}
context.initState({
loaded: false,
loading: false,
piotr.kupczyk@id.ethz.ch
committed
filterMode: filterMode,
filters: {},
piotr.kupczyk@id.ethz.ch
committed
globalFilter: {
operator: GridFilterOptions.OPERATOR_AND,
text: null
},
page: 0,
pageSize: 10,
columnsVisibility: {},
columnsSorting: [],
allColumns: [],
piotr.kupczyk@id.ethz.ch
committed
local: null,
rows: [],
filteredRows: [],
sortedRows: [],
allRows: [],
piotr.kupczyk@id.ethz.ch
committed
selectedRow: null,
piotr.kupczyk@id.ethz.ch
committed
multiselectedRows: {},
piotr.kupczyk@id.ethz.ch
committed
heights: {},
piotr.kupczyk@id.ethz.ch
committed
sortings: sortings,
piotr.kupczyk@id.ethz.ch
committed
totalCount: 0,
piotr.kupczyk@id.ethz.ch
committed
exportState: {
loading: false,
piotr.kupczyk@id.ethz.ch
committed
warnings: null,
piotr.kupczyk@id.ethz.ch
committed
error: null,
fileName: null,
filePath: null
},
piotr.kupczyk@id.ethz.ch
committed
exportOptions: {
piotr.kupczyk@id.ethz.ch
committed
columns: GridExportOptions.COLUMNS.VISIBLE,
rows: GridExportOptions.ROWS.CURRENT_PAGE,
values: GridExportOptions.VALUES.RICH_TEXT,
includeDependencies: true
piotr.kupczyk@id.ethz.ch
committed
}
})
this.context = context
}
piotr.kupczyk@id.ethz.ch
committed
async load() {
try {
const props = this.context.getProps()
if ((props.rows && props.loadRows) || (!props.rows && !props.loadRows)) {
throw new Error(
'Incorrect grid configuration. Please set "rows" or "loadRows" property.'
)
}
if (
(props.columns && props.loadColumns) ||
(!props.columns && !props.loadColumns)
) {
throw new Error(
'Incorrect grid configuration. Please set "columns" or "loadColumns" property.'
)
}
await this.context.setState(() => ({
loading: true
}))
const state = this.context.getState()
const newState = {
...state,
heights: {},
loading: false,
loaded: true
}
let settings = null
piotr.kupczyk@id.ethz.ch
committed
if (!state.loaded) {
settings = await this._loadSettings()
_.merge(newState, settings)
}
let result = {}
piotr.kupczyk@id.ethz.ch
committed
if (props.rows) {
result.rows = props.rows
result.totalCount = props.rows.length
result.local = true
} else if (props.loadRows) {
const columns = {}
piotr.kupczyk@id.ethz.ch
committed
newState.allColumns.forEach(column => {
columns[column.name] = column
})
piotr.kupczyk@id.ethz.ch
committed
const loadedResult = await props.loadRows({
columns: columns,
filterMode: newState.filterMode,
filters: newState.filters,
globalFilter: newState.globalFilter,
page: newState.page,
pageSize: newState.pageSize,
sortings: newState.sortings
})
if (_.isArray(loadedResult)) {
result.rows = loadedResult
result.totalCount = loadedResult.length
result.local = true
} else {
result.rows = loadedResult.rows
result.totalCount = loadedResult.totalCount
result.local = false
}
piotr.kupczyk@id.ethz.ch
committed
}
newState.local = result.local
piotr.kupczyk@id.ethz.ch
committed
if (result.local) {
const { newAllColumns, newColumnsVisibility, newColumnsSorting } =
await this._loadColumns(
result.rows,
newState.columnsVisibility,
newState.columnsSorting
)
newState.allColumns = newAllColumns
newState.columnsVisibility = newColumnsVisibility
newState.columnsSorting = newColumnsSorting
newState.allRows = result.rows
newState.filteredRows = this._filterRows(
newState.allRows,
newState.allColumns,
newState.columnsVisibility,
newState.filterMode,
newState.filters,
newState.globalFilter
)
newState.sortedRows = this._sortRows(
newState.filteredRows,
newState.allColumns,
newState.sortings
)
newState.totalCount = newState.filteredRows.length
const pageCount = Math.max(
Math.ceil(newState.totalCount / newState.pageSize),
1
)
newState.page = Math.min(newState.page, pageCount - 1)
newState.rows = this._pageRows(
Loading
Loading full blame...