Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/dev/1.10' into 1.10
Browse files Browse the repository at this point in the history
  • Loading branch information
rgrebenchuk committed Jan 20, 2017
2 parents f82f1db + 18902f1 commit 53513c5
Show file tree
Hide file tree
Showing 50 changed files with 1,861 additions and 512 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,9 @@ define(function(require) {
},

_onContentChange: function() {
this.disposePageComponents();
this.$(this.options.infoBlock).html(this.model.get('contentHTML'));
this.$(this.options.infoBlock)
.trigger('content:remove') // to dispose only components related to infoBlock
.html(this.model.get('contentHTML'));
this.initLayout().done(_.bind(function() {
// if the activity has an EmailTreadView -- handle comment count change in own way
var emailTreadView = this.getEmailThreadView();
Expand Down
59 changes: 59 additions & 0 deletions src/Oro/Bundle/DashboardBundle/Filter/DateFilterProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

use Doctrine\ORM\QueryBuilder;

use Oro\Bundle\DashboardBundle\Exception\InvalidArgumentException;
use Oro\Bundle\FilterBundle\Datasource\Orm\OrmFilterDatasourceAdapter;
use Oro\Bundle\FilterBundle\Filter\FilterUtility;
use Oro\Bundle\FilterBundle\Form\Type\Filter\AbstractDateFilterType;
use Oro\Bundle\FilterBundle\Utils\DateFilterModifier;
use Oro\Bundle\LocaleBundle\Model\LocaleSettings;

class DateFilterProcessor
{
Expand All @@ -16,6 +19,9 @@ class DateFilterProcessor
/** @var DateFilterModifier */
protected $modifier;

/** @var LocaleSettings */
protected $localeSettings;

/**
* @param DateRangeFilter $filter
* @param DateFilterModifier $modifier
Expand Down Expand Up @@ -54,4 +60,57 @@ public function getModifiedDateData(array $dateData)

return $this->modifier->modify($dateData, ['start', 'end'], false);
}

/**
* Initialize locale settings to be used in the class methods
*
* @param LocaleSettings $localeSettings
*/
public function setLocaleSettings(LocaleSettings $localeSettings)
{
$this->localeSettings = $localeSettings;
}

/**
* @param mixed $date
*
* @throws \Oro\Bundle\DashboardBundle\Exception\InvalidArgumentException in case localeSettings is not set
* @return \DateTime
*/
protected function prepareDate($date)
{
if (!$this->localeSettings) {
throw new InvalidArgumentException('Processor should be initialized with LocaleSettings');
}

return $date instanceof \DateTime
? $date
: new \DateTime($date, new \DateTimeZone($this->localeSettings->getTimeZone()));
}
/**
* @param QueryBuilder $qb
* @param $dateRange
* @param $fieldAlias
*/
public function applyDateRangeFilterToQuery(QueryBuilder $qb, $dateRange, $fieldAlias)
{
$dateRange = $this->getModifiedDateData($dateRange);
switch ($dateRange['type']) {
case AbstractDateFilterType::TYPE_MORE_THAN:
$start = $this->prepareDate($dateRange['value']['start']);
$qb->andWhere(sprintf('%s >= :start', $fieldAlias))->setParameter('start', $start);
break;
case AbstractDateFilterType::TYPE_LESS_THAN:
$end = $this->prepareDate($dateRange['value']['end']);
$qb->andWhere(sprintf('%s <= :end', $fieldAlias))->setParameter('end', $end);
break;
case AbstractDateFilterType::TYPE_ALL_TIME:
return;
default:
$start = $this->prepareDate($dateRange['value']['start']);
$end = $this->prepareDate($dateRange['value']['end']);
$qb->andWhere(sprintf('%s >= :start', $fieldAlias))->setParameter('start', $start);
$qb->andWhere(sprintf('%s <= :end', $fieldAlias))->setParameter('end', $end);
}
}
}
2 changes: 2 additions & 0 deletions src/Oro/Bundle/DashboardBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ services:
arguments:
- '@oro_dashboard.filter.date_range'
- '@oro_filter.utils.date_filter_modifier'
calls:
- ['setLocaleSettings', ['@oro_locale.settings']]

# Twig extension
oro_dashboard.twig.extension:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,21 @@ define(function(require) {
value: -5
},

fieldsDataName: {
datePart: 'date_part',
customPart: 'custom_part'
},

domCache: null,

/**
* @inheritDoc
*/
events: {
'change select': 'skipOnChangeFilterTypeHandler',
'change .date-visual-element': '_onClickUpdateCriteria',
'change select[name=date_part], input[name$="[type]"]': 'onChangeFilterType',
'change select[name=""]': 'onChangeFilterTypeView'
'change select[data-name$="_part"]': 'onChangeFilterTypeView'
},

/**
Expand All @@ -35,22 +43,30 @@ define(function(require) {
options.$form.on('submit' + this.eventNamespace(), _.bind(this.onSubmit, this));
},

onSubmit: function(e) {
createDomCache: function() {
this.domCache = {
$datePart: this.$('select[data-name="' + this.fieldsDataName.datePart + '"]'),
$customPart: this.$('select[data-name="' + this.fieldsDataName.customPart + '"]'),
$dateTypeCriteriaValue: this.$(this.criteriaValueSelectors.date_type)
};
},

onSubmit: function() {
var value = _.extend({}, this.emptyValue, this.getValue());
if (_.values(this.typeValues).indexOf(parseInt(value.type)) !== -1 &&
!value.value.start && !value.value.end
) {
this.$('select[name=""]').eq(0).val(this.typeDefinedValues.all_time).change();
this.applyValue();
var defaultTypeValue = this.getDefaultTypeValue();
this.domCache.$datePart.val(defaultTypeValue).change();
}
},

onChangeFilterTypeView: function(e) {
var val = parseInt($(e.target).val());
if (val === this.customChoice.value) {
val = this.$('select[name=""]').eq(1).val();
val = this.domCache.$customPart.val();
}
this.$(this.criteriaValueSelectors.date_type).val(val).change();
this.domCache.$dateTypeCriteriaValue.val(val).change();
this.applyValue();
},

Expand All @@ -71,6 +87,7 @@ define(function(require) {
return;
}

this.domCache = null;
this.options.$form.off(this.eventNamespace());
WidgetConfigDateRangeFilter.__super__.dispose.apply(this, arguments);
},
Expand All @@ -80,31 +97,32 @@ define(function(require) {

var type = parseInt(value, 10);
if (!isNaN(type)) {
var $select = this.$('.selector:has(select[name=""]):eq(1), select[name=""]:eq(1)').eq(0);
if (_.values(this.typeDefinedValues).indexOf(type) > -1) {
$select.hide();
if (_.values(this.typeDefinedValues).indexOf(type) === -1) {
this.domCache.$customPart.show();
} else {
// set correct width of uniform widget in case <select> was hidden before, since widget
// wasn't initialized yet
var $hiddenSelect = $('select[name=""]:eq(1)');
if ($hiddenSelect.css('display') === 'none' &&
$hiddenSelect.data('bound-input-widget') === 'uniform'
) {
$hiddenSelect.css('display', '').data('input-widget').refresh();
}

$select.css('display', '');
this.domCache.$customPart.hide();
}

// set correct width of uniform widget
if (this.domCache.$customPart.data('bound-input-widget') === 'uniform') {
this.domCache.$customPart.data('input-widget').refresh();
}
}
},

getDefaultTypeValue: function() {
var choiceData = _.pluck(this.choices, 'data');
return choiceData.indexOf(this.typeDefinedValues.all_time) === -1 ?
this.emptyValue.type :
this.typeDefinedValues.all_time;
},

_getParts: function() {
var parts = WidgetConfigDateRangeFilter.__super__._getParts.apply(this, arguments);
if (!this.valueTypes) {
return parts;
return WidgetConfigDateRangeFilter.__super__._getParts.apply(this, arguments);
}

parts.pop();
var parts = [];
var value = _.extend({}, this.emptyValue, this.getValue());
var selectedChoiceLabel = this._getSelectedChoiceLabel('choices', value);
var datePartTemplate = this._getTemplate(this.fieldTemplateSelector);
Expand All @@ -117,6 +135,7 @@ define(function(require) {
parts.push(
datePartTemplate({
name: '',
dataName: this.fieldsDataName.datePart,
choices: typeDefinedValueChoices,
selectedChoice: typeDefinedValues.indexOf(value.type) !== -1 ? value.type : this.customChoice.value,
selectedChoiceLabel: selectedChoiceLabel,
Expand All @@ -131,6 +150,7 @@ define(function(require) {
parts.push(
datePartTemplate({
name: '',
dataName: this.fieldsDataName.customPart,
choices: typeValueChoices,
selectedChoice: value.type,
selectedChoiceLabel: selectedChoiceLabel
Expand All @@ -146,6 +166,11 @@ define(function(require) {
return parts;
},

_appendFilter: function($filter) {
WidgetConfigDateRangeFilter.__super__._appendFilter.call(this, $filter);
this.createDomCache();
},

/**
* @inheritDoc
*/
Expand All @@ -170,6 +195,11 @@ define(function(require) {
_updateDOMValue: function() {
return this._writeDOMValue(this._formatRawValue(this.getValue()));
},

/**
* This method allow us to reset parent event observer
*/
skipOnChangeFilterTypeHandler: function() {}
});

return WidgetConfigDateRangeFilter;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Oro\Bundle\DashboardBundle\Tests\Functional;

use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Field\InputFormField;
use Symfony\Component\DomCrawler\Form;

use Oro\Bundle\TestFrameworkBundle\Test\WebTestCase;
use Oro\Bundle\DashboardBundle\Entity\Widget;

class AbstractWidgetTestCase extends WebTestCase
{
/**
* @param Form $form
* @param string $fieldName
* @param mixed $value
* @param string $fieldType
*/
protected function setOrAdd(Form $form, $fieldName, $value, $fieldType = 'text')
{
if (!$form->has($fieldName)) {
$doc = new \DOMDocument("1.0");
$doc->loadHTML(sprintf('<input type="%s" name="%s" value="" />', $fieldType, $fieldName));
$dynamicField = new InputFormField($doc->getElementsByTagName('input')->item(0));
$form->set($dynamicField);
}

$form[$fieldName] = $value;
}

/**
* @param Widget $widget
* @param array $configFields
*/
protected function configureWidget(Widget $widget, array $configFields)
{
$this->client->request(
'GET',
$this->getUrl(
'oro_dashboard_configure',
['id' => $widget->getId(), '_widgetContainer' => 'dialog']
)
);
$response = $this->client->getResponse();
$this->assertEquals($response->getStatusCode(), 200, 'Failed in getting configure widget dialog window !');

/**
* @var $crawler Crawler
* @var $form Form
*/
$crawler = $this->client->getCrawler();
/** @var Form $form */
$form = $crawler->selectButton('Save')->form();

foreach ($configFields as $fieldsName => $value) {
$this->setOrAdd($form, $fieldsName, $value);
}

$this->client->submit($form);

$response = $this->client->getResponse();
$this->assertEquals($response->getStatusCode(), 200, "Failed in submit widget configuration options !");
}

/**
* Returns data for which will be used to show widget's chart
*
* @param $crawler
* @return array
*/
protected function getChartData($crawler)
{
$dataComponent = $crawler->filter('.column-chart');
if ($dataComponent->extract(['data-page-component-options'])) {
$data = $dataComponent->extract(['data-page-component-options']);
$data = json_decode($data[0]);
return $data->chartOptions->dataSource->data;
} else {
$dataComponent = $crawler->filter('.dashboard-widget-content > [data-page-component-options]');
$data = $dataComponent->extract(['data-page-component-options']);
$data = json_decode($data[0]);
return $data->data;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

<div class="widget-content">
{% set fieldName = (fieldName is defined) ? fieldName : '' %}
{% set scope = entityClass~entityId~date().timestamp %}

<div class="container-fluid">
{% block content %}
{# gridName set from corresponding controllers #}
{{ dataGrid.renderGrid(gridName, {object_class: entityClass, object_id: entityId, field_name: fieldName}) }}
{{ dataGrid.renderGrid(
oro_datagrid_build_fullname(gridName, scope),
{object_class: entityClass, object_id: entityId, field_name: fieldName}
) }}
{% endblock %}
</div>
</div>
Loading

0 comments on commit 53513c5

Please sign in to comment.