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

[WIP] flexbox tables with dummy app to play with #54

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ae70b5d
flexbox tables with dummy app to play with
phndiaye Aug 21, 2019
2c2b9c4
add component representing a single cell in the table
phndiaye Aug 23, 2019
d6bcdc2
setup basic table with drag and droppable columns
phndiaye Aug 23, 2019
c2c8a73
add back support for row selection
phndiaye Aug 23, 2019
dd62a39
table columns are only draggable by their header
phndiaye Aug 23, 2019
7a2b000
higher cells
phndiaye Aug 23, 2019
ba7f4dd
better transition when swapping columns (at least for now)
phndiaye Aug 23, 2019
c5bf9c7
add icon commands to the headers, always displayed for now
phndiaye Aug 23, 2019
049ae2c
add only display columns that are supposed to be
phndiaye Aug 26, 2019
2014393
transform columns config to EmberObjects from the start
phndiaye Aug 26, 2019
b6fe401
allow the callee app to handle the columns update
phndiaye Aug 26, 2019
991b44e
mock columns config being sent out by the backend
phndiaye Aug 26, 2019
007a9a3
order available columns alphabetically and avoid stripping hidden col…
phndiaye Aug 27, 2019
88bcd91
hardset an order on columns
phndiaye Aug 28, 2019
d1472f8
setup basic support for column data types
phndiaye Aug 28, 2019
9a089de
skip wraping div on money and numeric cell renderers
phndiaye Sep 3, 2019
3702910
rework the datatable with fixed header and sticky first column support
phndiaye Sep 3, 2019
c3ff3d8
add support for searching through the available columns
phndiaye Sep 4, 2019
79b5ef9
add empty states for the data cell renderers
phndiaye Sep 4, 2019
b7de477
more fake data
phndiaye Sep 4, 2019
b904ef9
use a service to handle the table's state
phndiaye Sep 5, 2019
ef43cdf
add support for sorting on a column
phndiaye Sep 6, 2019
dadd9a1
add back support for search and contextual actions
phndiaye Sep 6, 2019
685bef8
avoid displaying multiple filters panels simultaneously
phndiaye Sep 9, 2019
2706718
add support for date type columns
phndiaye Sep 9, 2019
6b49dbc
add support for date filtering by presets
phndiaye Sep 10, 2019
7b608cc
map the display of the filters icon on filters presence, and same for…
phndiaye Sep 10, 2019
92b227b
move table related css to the package's css so it's available for tes…
phndiaye Sep 10, 2019
53c9cd0
listen to filters changes to update the current column header's state
phndiaye Sep 10, 2019
cac3c76
add support for clearing filters on a column
phndiaye Sep 10, 2019
076f42a
basic support of onBottomReached actions to lay the basis of an infin…
phndiaye Sep 10, 2019
e00d040
move to ember-sortable to shared dependencies
phndiaye Sep 11, 2019
d63c20e
add state when loading more items to the collection and do not handle…
phndiaye Sep 11, 2019
9a65876
group the enabled features in a config dict
phndiaye Sep 11, 2019
b878e4f
handle case where the date data received is already a date object (cf…
phndiaye Sep 11, 2019
494f979
allow rendering component to be overwritten in column config
phndiaye Sep 11, 2019
fceb431
refactor the table service to be able to create multiple table instances
phndiaye Sep 12, 2019
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
7 changes: 6 additions & 1 deletion addon/components/upf-checkbox.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import Component from '@ember/component';
import { equal } from '@ember/object/computed';

export default Component.extend({
classNames: ['upf-checkbox'],
classNameBindings: ['hasLabel:upf-checkbox--has-label']
classNameBindings: [
'hasLabel:upf-checkbox--has-label', 'sizeSmall:upf-checkbox--sm'
],

sizeSmall: equal('size', 'sm')
});
107 changes: 107 additions & 0 deletions addon/components/upf-table/cell.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import Component from '@ember/component';
import { computed, defineProperty, observer } from '@ember/object';
import { or } from '@ember/object/computed';
import { capitalize } from '@ember/string';
import { isEmpty } from '@ember/utils';

const AVAILABLE_RENDERERS = [
'text', 'numeric', 'money', 'date'
];

export default Component.extend({
classNames: ['upf-hypertable__cell'],
classNameBindings: [
'header:upf-hypertable__cell--header',
'item.selected:upf-hypertable__cell--selected',
'loading:upf-hypertable__cell--loading',
'_sorted:upf-hypertable__cell--sorted',
'_filtered:upf-hypertable__cell--filtered',
'isNumeric:upf-hypertable__cell--numeric',
'isMoney:upf-hypertable__cell--numeric'
],

header: false,
selection: false,
loading: false,

_sorted: false,
_filtered: false,
_showFiltersPanel: false,

_sortingIconClass: computed('_sorted', function() {
if (this._sorted) {
let [_, direction] = this.column.sortBy.split(':');

return (direction === 'asc') ? 'fa-long-arrow-up' : 'fa-long-arrow-down';
}
}),

_typeInferredRenderingComponent: computed('column.type', function() {
if (AVAILABLE_RENDERERS.includes(this.column.type)) {
return `upf-table/cell/renderers/${this.column.type}`;
}
}),

_renderingComponent: or(
'column.renderingComponent', '_typeInferredRenderingComponent'
),

_filtersRenderingComponent: computed('column.type', function() {
if (AVAILABLE_RENDERERS.includes(this.column.type)) {
return `upf-table/cell/filters-renderers/${this.column.type}`;
}
}),

_filtersChanged: observer('column.filters.@each', function () {
this.set('_filtered', !isEmpty(this.column.filters));
}),

_tableStateListener() {
this.set('_sorted', !isEmpty(this.column.sortBy));
this.set('_filtered', !isEmpty(this.column.filters));
},

_filtersPanelListener() {
if (this.column.property !== this.manager.applyingFiltersOn) {
this.set('showFiltersPanel', false);
}
},

didReceiveAttrs() {
if (this.column) {
AVAILABLE_RENDERERS.forEach((rendererType) => {
defineProperty(
this,
`is${capitalize(rendererType)}`,
computed('column.type', function() {
return this.column.type === rendererType;
})
);
});

if (this.header) {
this.addObserver(
'manager.columns.@each.sortBy',
this,
this._tableStateListener
);

this.addObserver(
'manager.applyingFiltersOn',
this,
this._filtersPanelListener
);
}

this.set('_sorted', !isEmpty(this.column.sortBy));
this.set('_filtered', !isEmpty(this.column.filters));
}
},

actions: {
toggleFiltersPanel() {
this.toggleProperty('showFiltersPanel');
this.set('manager.applyingFiltersOn', this.column.property);
}
}
});
69 changes: 69 additions & 0 deletions addon/components/upf-table/cell/filters-renderers/date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import Component from '@ember/component';
import { computed } from '@ember/object';

export default Component.extend({
classNames: ['available-filters'],

sortingOptions: {
'Oldest — Newest': 'alphanumerical:asc',
'Newest — Oldest': 'alphanumerical:desc'
},

filteringOptions: {
'Fixed': 'fixed',
'Moving': 'moving'
},

filterOption: 'moving', // or 'moving'

currentMovingDateOption: computed('column.filters.@each.value.alias', function() {
let filter = this.column.filters.find((f) => f.type === 'range');

return (filter) ? filter.value.alias : null;
}),

movingDateOptions: {
'Today': 'today',
'Yesterday': 'yesterday'
},

_buildDateRange(from) {
switch(from) {
case 'today':
return {
alias: 'today',
from: moment().startOf('day').format('X'),
to: moment().endOf('day').format('X')
}
case 'yesterday':
return {
alias: 'yesterday',
from: moment().subtract(1, 'day').startOf('day').format('X'),
to: moment().subtract(1, 'day').endOf('day').format('X')
}
default:
break;
}
},

actions: {
sortingOptionChanged(value) {
this.manager.updateSortBy(this.column, value);
},

filterOptionChanged(value) {
this.set('filterOption', value);
},

selectMovingDate(value) {
this.manager.addFilters(
this.column, 'range', this._buildDateRange(value)
);
},

// Mixin Candidate
clearFilters() {
this.manager.clearFilters(this.column);
}
}
});
16 changes: 16 additions & 0 deletions addon/components/upf-table/cell/filters-renderers/money.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Component from '@ember/component';

export default Component.extend({
classNames: ['available-filters'],

sortingOptions: {
'0 — 9': 'alphanumerical:asc',
'9 — 0': 'alphanumerical:desc'
},

actions: {
sortingOptionChanged(value) {
this.manager.updateSortBy(this.column, value);
}
}
});
16 changes: 16 additions & 0 deletions addon/components/upf-table/cell/filters-renderers/numeric.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Component from '@ember/component';

export default Component.extend({
classNames: ['available-filters'],

sortingOptions: {
'0 — 9': 'alphanumerical:asc',
'9 — 0': 'alphanumerical:desc'
},

actions: {
sortingOptionChanged(value) {
this.manager.updateSortBy(this.column, value);
}
}
});
16 changes: 16 additions & 0 deletions addon/components/upf-table/cell/filters-renderers/text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Component from '@ember/component';

export default Component.extend({
classNames: ['available-filters'],

sortingOptions: {
'A — Z': 'alphanumerical:asc',
'Z — A': 'alphanumerical:desc'
},

actions: {
sortingOptionChanged(value) {
this.manager.updateSortBy(this.column, value);
}
}
});
31 changes: 31 additions & 0 deletions addon/components/upf-table/cell/renderers/date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { empty, or } from '@ember/object/computed';
import { typeOf } from '@ember/utils';

import moment from 'moment';

export default Component.extend({
tagName: '',

value: computed('item', 'column.property', function() {
return this.item.get(this.column.property);
}),

emptyValue: empty('value'),

_defaultDateFormat: 'MM/DD/YYYY',
_dateFormat: or('column.date_format', '_defaultDateFormat'),

_formattedDate: computed('value', '_dateFormat', function() {
let _date;

if (typeOf(this.value) === 'date') {
_date = moment(this.value);
} else {
_date = moment.unix(this.value)
}

return _date.format(this._dateFormat);
})
});
23 changes: 23 additions & 0 deletions addon/components/upf-table/cell/renderers/money.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { empty } from '@ember/object/computed';

export default Component.extend({
tagName: '',

currency: computed('column', 'column.currency_key', function() {
if (this.column && !this.column.currency_key) {
throw new Error(
'[upf-table/cell-renderers][money] You are trying to render Money without a currency'
);
}

return this.item.get(this.column.currency_key);
}),

amount: computed('item', 'column.property', function() {
return this.item.get(this.column.property);
}),

emptyAmount: empty('amount')
});
13 changes: 13 additions & 0 deletions addon/components/upf-table/cell/renderers/numeric.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { empty } from '@ember/object/computed';

export default Component.extend({
tagName: '',

value: computed('item', 'column.property', function() {
return this.item.get(this.column.property);
}),

emptyValue: empty('value')
});
11 changes: 11 additions & 0 deletions addon/components/upf-table/cell/renderers/text.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { empty } from '@ember/object/computed';

export default Component.extend({
value: computed('item', 'column.property', function() {
return this.item.get(this.column.property);
}),

emptyValue: empty('value')
});
Loading