ui/lib/shared/addon/components/columns-section/component.js

127 lines
3.6 KiB
JavaScript

import { alias } from '@ember/object/computed';
import Component from '@ember/component';
import ThrottledResize from 'shared/mixins/throttled-resize';
import { computed } from '@ember/object';
import { run } from '@ember/runloop';
import { htmlSafe } from '@ember/string';
import layout from './template';
const MIN_WIDTH = 260; // Minimum width of a column, including margin-right
const COLUMN_MARGIN = 10; // this must match the rule in styles/pod.scss .pod-column
export default Component.extend(ThrottledResize, {
layout,
pods : null, // Override me with an array of content pods
emptyMessage : null,
columnWidth : MIN_WIDTH,
columnFudge : 0,
classNames : ['pods','clearfix'],
tagName : 'section',
columnCount : 3, // Will be reset on didInsertElement and resize
podCount : alias('pods.length'),
lastIndex: computed('columnCount', function() {
return this.get('columnCount')-1;
}),
columnWidthCss: computed('columnWidth', function() {
return htmlSafe('width: ' + this.get('columnWidth') + 'px');
}),
lastColumnWidthCss: computed('columnWidth','columnFudge', function() {
return htmlSafe('width: ' + (this.get('columnWidth')+this.get('columnFudge')) + 'px');
}),
onResize: function() {
if ( this.isDestroyed || this.isDestroying ) {
return;
}
try {
let elem = this.$();
let sectionWidth = $('#application').width(); // On first call the pods aren't rendered yet, so approximate with the screen width
if ( elem && elem.is(':visible') )
{
sectionWidth = elem.width();
}
let margins = COLUMN_MARGIN + 2;
let logicalWidth = (sectionWidth + margins); // Add one extra COLUMN_MARGIN because the last column doesn't actually have one
let columnCount = Math.max(1, Math.floor(logicalWidth/MIN_WIDTH));
let columnWidth = Math.max(50, Math.floor((logicalWidth/columnCount) - margins));
let columnFudge = logicalWidth - (columnCount*(columnWidth+margins)); // Extra pixels that didn't divide evenly go onto the last column.
/*
console.log(
'section='+sectionWidth,
'logical='+logicalWidth,
'count='+columnCount,
'width='+columnWidth,
'fudge='+columnFudge
);
*/
this.setProperties({
columnCount: columnCount,
columnWidth: columnWidth,
columnFudge: columnFudge,
});
} catch (e) {
// Just in case..
}
},
init: function() {
this._super();
this.onResize(); // Estimate the columnCount so it doesn't have to get called twice in most cases
},
podCountChanged: function() {
run.next(this,'onResize');
}.observes('podCount'),
columns: computed('pods.[]','columnCount', function() {
let i;
let idx = 0;
let pods = (this.get('pods')||[]).sortBy('displayName');
let columnCount = this.get('columnCount');
// Pre-initialize all the columns
var columns = [];
for ( i = 0 ; i < columnCount ; i++ )
{
columns[i] = [];
}
// Copy in the hosts
for ( i = 0 ; i < pods.get('length') ; i++ )
{
columns[nextIndex()].push(pods.objectAt(i));
}
return columns;
function nextIndex() {
let out = idx;
idx++;
if ( idx >= columnCount )
{
idx = 0;
}
return out;
}
}),
didInsertElement: function() {
this._super();
// Removes deprecation warning about modifing after insert
run.scheduleOnce('afterRender', this, 'onResize');
},
});