Skip to content

Commit

Permalink
Add Dynamic Values to Date and Date Range Parameters (getredash#3904)
Browse files Browse the repository at this point in the history
* Draft for Date Dynamic values

* Use value with prefix instead of specific attr

* Fix not possible to select static value

* Update antd version

* Cleanup and DateRangeParameter

* Dynamic DateTimeRange

* Add Dynamic options to Date Parameters

* UI refinements

* Add getDynamicValue function

* Add 'This' options and prevent text clipping

* Make allowClear available

* Update ScheduleDialog snapshot

* Add some protections and separate Date/DateRange

* Accept null values on date or daterange parameters

* Handle undefined values on Moment propType

* Move export to end of files

* Remove Today/Now option

* Update with Apply Changes

* Show name instead of value for dynamic values

* Add comment about supporting useCurrentDateTime

* Cypress Tests: Date Parameters

* Cypress Tests: Date Range Parameters

* Don't put null params in the url

* Add workaround comments to Cypress tests

Co-Authored-By: Ran Byron <[email protected]>

* Fix Dynamic Value as default for global parameters

* Update Back to Static Value

* Add isValid to value on Date and DateRange inputs

* CR suggestions

* Fix Back to Static Value for Dates

* Update Dynamic Value Styling

* Fix failing Date tests

* Fix selectedDynamicValue

* Parameter spec: Remove date range clickThrough

* Add transition

* Fix failing Cypress tests

* Back with 'width: auto'

* Check value is valid on Back to Static value

* CR

* Update Date Range width
  • Loading branch information
gabrieldutra authored and harveyrendell committed Nov 14, 2019
1 parent 03732e1 commit 01336b8
Show file tree
Hide file tree
Showing 21 changed files with 983 additions and 367 deletions.
1 change: 1 addition & 0 deletions client/app/assets/less/ant.less
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
@import "~antd/lib/notification/style/index";
@import "~antd/lib/collapse/style/index";
@import "~antd/lib/progress/style/index";
@import "~antd/lib/typography/style/index";
@import 'inc/ant-variables';

// Increase z-indexes to avoid conflicts with some other libraries (e.g. Plotly)
Expand Down
14 changes: 11 additions & 3 deletions client/app/components/DateInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import { clientConfig } from '@/services/auth';
import { Moment } from '@/components/proptypes';

export function DateInput({
defaultValue,
value,
onSelect,
className,
...props
}) {
const format = clientConfig.dateFormat || 'YYYY-MM-DD';
const additionalAttributes = {};
if (value && value.isValid()) {
additionalAttributes.defaultValue = value;
if (defaultValue && defaultValue.isValid()) {
additionalAttributes.defaultValue = defaultValue;
}
if (value === null || (value && value.isValid())) {
additionalAttributes.value = value;
}
return (
<DatePicker
Expand All @@ -22,18 +27,21 @@ export function DateInput({
format={format}
placeholder="Select Date"
onChange={onSelect}
{...props}
/>
);
}

DateInput.propTypes = {
defaultValue: Moment,
value: Moment,
onSelect: PropTypes.func,
className: PropTypes.string,
};

DateInput.defaultProps = {
value: null,
defaultValue: null,
value: undefined,
onSelect: () => {},
className: '',
};
Expand Down
14 changes: 11 additions & 3 deletions client/app/components/DateRangeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,41 @@ import { Moment } from '@/components/proptypes';
const { RangePicker } = DatePicker;

export function DateRangeInput({
defaultValue,
value,
onSelect,
className,
...props
}) {
const format = clientConfig.dateFormat || 'YYYY-MM-DD';
const additionalAttributes = {};
if (isArray(value) && value[0].isValid() && value[1].isValid()) {
additionalAttributes.defaultValue = value;
if (isArray(defaultValue) && defaultValue[0].isValid() && defaultValue[1].isValid()) {
additionalAttributes.defaultValue = defaultValue;
}
if (value === null || (isArray(value) && value[0].isValid() && value[1].isValid())) {
additionalAttributes.value = value;
}
return (
<RangePicker
className={className}
{...additionalAttributes}
format={format}
onChange={onSelect}
{...props}
/>
);
}

DateRangeInput.propTypes = {
defaultValue: PropTypes.arrayOf(Moment),
value: PropTypes.arrayOf(Moment),
onSelect: PropTypes.func,
className: PropTypes.string,
};

DateRangeInput.defaultProps = {
value: null,
defaultValue: null,
value: undefined,
onSelect: () => {},
className: '',
};
Expand Down
14 changes: 11 additions & 3 deletions client/app/components/DateTimeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ import { clientConfig } from '@/services/auth';
import { Moment } from '@/components/proptypes';

export function DateTimeInput({
defaultValue,
value,
withSeconds,
onSelect,
className,
...props
}) {
const format = (clientConfig.dateFormat || 'YYYY-MM-DD') +
(withSeconds ? ' HH:mm:ss' : ' HH:mm');
const additionalAttributes = {};
if (value && value.isValid()) {
additionalAttributes.defaultValue = value;
if (defaultValue && defaultValue.isValid()) {
additionalAttributes.defaultValue = defaultValue;
}
if (value === null || (value && value.isValid())) {
additionalAttributes.value = value;
}
return (
<DatePicker
Expand All @@ -25,19 +30,22 @@ export function DateTimeInput({
format={format}
placeholder="Select Date and Time"
onChange={onSelect}
{...props}
/>
);
}

DateTimeInput.propTypes = {
defaultValue: Moment,
value: Moment,
withSeconds: PropTypes.bool,
onSelect: PropTypes.func,
className: PropTypes.string,
};

DateTimeInput.defaultProps = {
value: null,
defaultValue: null,
value: undefined,
withSeconds: false,
onSelect: () => {},
className: '',
Expand Down
14 changes: 11 additions & 3 deletions client/app/components/DateTimeRangeInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ import { Moment } from '@/components/proptypes';
const { RangePicker } = DatePicker;

export function DateTimeRangeInput({
defaultValue,
value,
withSeconds,
onSelect,
className,
...props
}) {
const format = (clientConfig.dateFormat || 'YYYY-MM-DD') +
(withSeconds ? ' HH:mm:ss' : ' HH:mm');
const additionalAttributes = {};
if (isArray(value) && value[0].isValid() && value[1].isValid()) {
additionalAttributes.defaultValue = value;
if (isArray(defaultValue) && defaultValue[0].isValid() && defaultValue[1].isValid()) {
additionalAttributes.defaultValue = defaultValue;
}
if (value === null || (isArray(value) && value[0].isValid() && value[1].isValid())) {
additionalAttributes.value = value;
}
return (
<RangePicker
Expand All @@ -27,19 +32,22 @@ export function DateTimeRangeInput({
{...additionalAttributes}
format={format}
onChange={onSelect}
{...props}
/>
);
}

DateTimeRangeInput.propTypes = {
defaultValue: PropTypes.arrayOf(Moment),
value: PropTypes.arrayOf(Moment),
withSeconds: PropTypes.bool,
onSelect: PropTypes.func,
className: PropTypes.string,
};

DateTimeRangeInput.defaultProps = {
value: null,
defaultValue: null,
value: undefined,
withSeconds: false,
onSelect: () => {},
className: '',
Expand Down
20 changes: 2 additions & 18 deletions client/app/components/EditParameterSettingsDialog.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@

import { includes, startsWith, words, capitalize, clone, isNull } from 'lodash';
import { includes, words, capitalize, clone, isNull } from 'lodash';
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Modal from 'antd/lib/modal';
import Form from 'antd/lib/form';
import Checkbox from 'antd/lib/checkbox';
import Button from 'antd/lib/button';
import Select from 'antd/lib/select';
import Input from 'antd/lib/input';
Expand All @@ -20,10 +19,6 @@ function getDefaultTitle(text) {
return capitalize(words(text).join(' ')); // humanize
}

function isTypeDate(type) {
return startsWith(type, 'date') && !isTypeDateRange(type);
}

function isTypeDateRange(type) {
return /-range/.test(type);
}
Expand Down Expand Up @@ -167,22 +162,11 @@ function EditParameterSettingsDialog(props) {
<Option disabled key="dv2">
<Divider className="select-option-divider" />
</Option>
<Option value="date-range">Date Range</Option>
<Option value="date-range" data-test="DateRangeParameterTypeOption">Date Range</Option>
<Option value="datetime-range">Date and Time Range</Option>
<Option value="datetime-range-with-seconds">Date and Time Range (with seconds)</Option>
</Select>
</Form.Item>
{isTypeDate(param.type) && (
<Form.Item label=" " colon={false} {...formItemProps}>
<Checkbox
defaultChecked={param.useCurrentDateTime}
onChange={e => setParam({ ...param, useCurrentDateTime: e.target.checked })}
data-test="UseCurrentDateTimeCheckbox"
>
Default to Today/Now if no other value is set
</Checkbox>
</Form.Item>
)}
{param.type === 'enum' && (
<Form.Item label="Values" help="Dropdown list values (newline delimeted)" {...formItemProps}>
<Input.TextArea
Expand Down
8 changes: 7 additions & 1 deletion client/app/components/ParameterMappingInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,13 @@ export class ParameterMappingListInput extends React.Component {
param = param.clone().setValue(mapping.value);
}

const value = Parameter.getValue(param);
let value = Parameter.getValue(param);

// in case of dynamic value display the name instead of value
if (param.hasDynamicValue) {
value = param.dynamicValue.name;
}

return this.getStringValue(value);
}

Expand Down
82 changes: 20 additions & 62 deletions client/app/components/ParameterValueInput.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import { react2angular } from 'react2angular';
import Select from 'antd/lib/select';
import Input from 'antd/lib/input';
import InputNumber from 'antd/lib/input-number';
import DateParameter from '@/components/dynamic-parameters/DateParameter';
import DateRangeParameter from '@/components/dynamic-parameters/DateRangeParameter';
import { toString } from 'lodash';
import { DateInput } from './DateInput';
import { DateRangeInput } from './DateRangeInput';
import { DateTimeInput } from './DateTimeInput';
import { DateTimeRangeInput } from './DateTimeRangeInput';
import { QueryBasedParameterInput } from './QueryBasedParameterInput';

import './ParameterValueInput.less';
Expand Down Expand Up @@ -58,69 +56,29 @@ export class ParameterValueInput extends React.Component {
this.props.onSelect(value, isDirty);
}

renderDateTimeWithSecondsInput() {
const { value } = this.props;
return (
<DateTimeInput
className={this.props.className}
value={value}
onSelect={this.onSelect}
withSeconds
/>
);
}

renderDateTimeInput() {
const { value } = this.props;
return (
<DateTimeInput
className={this.props.className}
value={value}
onSelect={this.onSelect}
/>
);
}

renderDateInput() {
const { value } = this.props;
return (
<DateInput
className={this.props.className}
value={value}
onSelect={this.onSelect}
/>
);
}

renderDateTimeRangeWithSecondsInput() {
const { value } = this.props;
return (
<DateTimeRangeInput
className={this.props.className}
value={value}
onSelect={this.onSelect}
withSeconds
/>
);
}

renderDateTimeRangeInput() {
const { value } = this.props;
renderDateParameter() {
const { type, parameter } = this.props;
const { value } = this.state;
return (
<DateTimeRangeInput
<DateParameter
type={type}
className={this.props.className}
value={value}
parameter={parameter}
onSelect={this.onSelect}
/>
);
}

renderDateRangeInput() {
const { value } = this.props;
renderDateRangeParameter() {
const { type, parameter } = this.props;
const { value } = this.state;
return (
<DateRangeInput
<DateRangeParameter
type={type}
className={this.props.className}
value={value}
parameter={parameter}
onSelect={this.onSelect}
/>
);
Expand Down Expand Up @@ -193,12 +151,12 @@ export class ParameterValueInput extends React.Component {
renderInput() {
const { type } = this.props;
switch (type) {
case 'datetime-with-seconds': return this.renderDateTimeWithSecondsInput();
case 'datetime-local': return this.renderDateTimeInput();
case 'date': return this.renderDateInput();
case 'datetime-range-with-seconds': return this.renderDateTimeRangeWithSecondsInput();
case 'datetime-range': return this.renderDateTimeRangeInput();
case 'date-range': return this.renderDateRangeInput();
case 'datetime-with-seconds':
case 'datetime-local':
case 'date': return this.renderDateParameter();
case 'datetime-range-with-seconds':
case 'datetime-range':
case 'date-range': return this.renderDateRangeParameter();
case 'enum': return this.renderEnumInput();
case 'query': return this.renderQueryBasedInput();
case 'number': return this.renderNumberInput();
Expand Down
Loading

0 comments on commit 01336b8

Please sign in to comment.