@gpa-gemstone/react-forms
Version:
React Form modules for gpa webapps
144 lines (143 loc) • 7.61 kB
JavaScript
;
// ******************************************************************************************************
// DateRangePicker.tsx - Gbtc
//
// Copyright © 2020, Grid Protection Alliance. All Rights Reserved.
//
// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
// the NOTICE file distributed with this work for additional information regarding copyright ownership.
// The GPA licenses this file to you under the MIT License (MIT), the "License"; you may not use this
// file except in compliance with the License. You may obtain a copy of the License at:
//
// http://opensource.org/licenses/MIT
//
// Unless agreed to in writing, the subject software distributed under the License is distributed on an
// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
// License for the specific language governing permissions and limitations.
//
// Code Modification History:
// ----------------------------------------------------------------------------------------------------
// 02/05/2020 - Billy Ernest
// Generated original version of source code.
//
// ******************************************************************************************************
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = DateRangePicker;
var React = require("react");
var moment = require("moment");
/**
* DateRangePicker Component.
* Allows users to select a date range either by choosing predefined durations or by specifying custom dates.
*/
function DateRangePicker(props) {
// Range box vars, need a secondary var to avoid looping react hooks
var _a = React.useState('Custom'), formRange = _a[0], setFormRange = _a[1];
var _b = React.useState('Custom'), range = _b[0], setRange = _b[1];
// Tracks weather or not props.Record changes are due to internal input boxes or externally
var _c = React.useState(false), internal = _c[0], setInternal = _c[1];
// Adds a buffer between the outside props and what the box is reading to prevent box overwriting every render with a keystroke
var _d = React.useState(ParseRecord()), boxRecord = _d[0], setBoxRecord = _d[1];
// Formats that will be used for dateBoxes
var boxFormat = "YYYY-MM-DD" + (props.Type === undefined || props.Type === 'date' ? "" : "[T]hh:mm:ss");
var recordFormat = props.Format !== undefined ? props.Format : "YYYY-MM-DD" + (props.Type === undefined || props.Type === 'date' ? "" : "[T]hh:mm:ss.SSS[Z]");
// Effect for handling changes to the props.Record.
React.useEffect(function () {
setRange(ToRange(moment(props.Record[props.ToField], recordFormat).diff(moment(props.Record[props.FromField], recordFormat), 'days')));
if (!internal)
setBoxRecord(ParseRecord());
setInternal(false);
}, [props.Record]);
// Effect for handling changes to the formRange state.
React.useEffect(function () {
var _a, _b;
setRange(formRange);
var toTime = moment(props.Record[props.FromField], recordFormat).add(GetDays(formRange), 'days');
props.Setter(__assign(__assign({}, props.Record), (_a = {}, _a[props.ToField] = toTime.format(recordFormat), _a)));
setBoxRecord(__assign(__assign({}, boxRecord), (_b = {}, _b[props.ToField] = toTime.format(boxFormat), _b)));
}, [formRange]);
// Parses the record for display in the date boxes.
function ParseRecord() {
var record = __assign({}, props.Record);
var ParseExternalField = function (field) { return props.Record[field] === null ? '' : moment(props.Record[field], recordFormat).format(boxFormat); };
record[props.ToField] = ParseExternalField(props.ToField);
record[props.FromField] = ParseExternalField(props.FromField);
return record;
}
// Converts the selected duration to a number of days.
function GetDays(val) {
if (val === '1 Day')
return 1;
if (val === '7 Days')
return 7;
if (val === '30 Days')
return 30;
if (val === '90 Days')
return 90;
if (val === '180 Days')
return 180;
if (val === '365 Days')
return 365;
return 0;
}
// Maps a number of days to a Duration value.
function ToRange(days) {
if (days === 1)
return ('1 Day');
else if (days === 7)
return ('7 Days');
else if (days === 30)
return ('30 Days');
else if (days === 90)
return ('90 Days');
else if (days === 180)
return ('180 Days');
else if (days === 365)
return ('365 Days');
else
return ('Custom');
}
// Renders a date input box.
function dateBox(field) {
return React.createElement("div", { className: "col" },
React.createElement("input", { className: "form-control" + (props.Valid(props.FromField, props.ToField) ? '' : ' is-invalid'), type: props.Type === undefined ? 'date' : props.Type, onChange: function (evt) {
var _a;
var record = __assign({}, props.Record);
if (evt.target.value !== '')
record[field] = moment(evt.target.value, boxFormat).format(recordFormat);
else
record[field] = null;
// These two updates should be batched together
props.Setter(record);
setBoxRecord(__assign(__assign({}, boxRecord), (_a = {}, _a[field] = evt.target.value, _a)));
setInternal(true);
}, value: boxRecord[field], disabled: props.Disabled === undefined ? false : props.Disabled }),
field !== props.FromField ? null :
React.createElement("div", { className: "invalid-feedback" }, props.Feedback === undefined ? 'From and to dates required, and from must be before to.' : props.Feedback));
}
// Main render method for the component.
return (React.createElement("div", { className: "form-group" },
props.Label === "" ? null : React.createElement("label", null, props.Label),
React.createElement("div", { className: "row" },
React.createElement("div", { className: "col" },
React.createElement("select", { className: "form-control", value: range, onChange: function (evt) { return setFormRange(evt.target.value); } },
React.createElement("option", { value: "Custom" }, "Custom"),
React.createElement("option", { value: "1 Day" }, "1 Day"),
React.createElement("option", { value: "7 Days" }, "7 Days"),
React.createElement("option", { value: "30 Days" }, "30 Days"),
React.createElement("option", { value: "90 Days" }, "90 Days"),
React.createElement("option", { value: "180 Days" }, "180 Days"),
React.createElement("option", { value: "365 Days" }, "365 Days"))),
dateBox(props.FromField),
dateBox(props.ToField))));
}