All files / js/widgets DateInputWidget.tsx

95.83% Statements 23/24
95.23% Branches 20/21
83.33% Functions 5/6
95.83% Lines 23/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 661x   1x 1x   7x     5x 5x             1x     3x 1x     2x 2x               1x     1x   1x     3x     4x 4x 4x 1x 1x 1x 1x   3x                            
import React from "react";
import { WidgetProps } from "./types";
import { trans } from "../i18n";
import InputWidgetBase from "./InputWidgetBase";
 
const parseInteger = (s: string) => Number.parseInt(s, 10);
 
export function isValidDate(year: number, month: number, day: number) {
  const date = new Date(year, month - 1, day);
  return (
    date.getFullYear() === year &&
    date.getMonth() === month - 1 &&
    date.getDate() === day
  );
}
 
const DATE_RE = /^\s*(?<year>\d{4})-(?<month>\d{1,2})-(?<day>\d{1,2})\s*$/;
 
export function validateDate(value: string): string | null {
  if (!value) {
    return null;
  }
 
  const groups = value.match(DATE_RE)?.groups;
  if (
    groups &&
    isValidDate(
      parseInteger(groups.year),
      parseInteger(groups.month),
      parseInteger(groups.day)
    )
  ) {
    return null;
  }
 
  return trans("ERROR_INVALID_DATE");
}
const REVERSE_DATE_RE =
  /^(?<day>\d{1,2})\.(?<month>\d{1,2})\.(?<year>\d{4})\s*$/;
 
const pad = (n: number) => (n < 10 ? `0${n}` : `${n}`);
 
export function postprocessDate(value: string) {
  value = value.trim();
  const groups = value.match(REVERSE_DATE_RE)?.groups;
  if (groups) {
    const day = parseInteger(groups.day);
    const month = parseInteger(groups.month);
    const year = parseInteger(groups.year);
    return `${year}-${pad(month)}-${pad(day)}`;
  }
  return value;
}
 
export function DateInputWidget(props: WidgetProps) {
  return (
    <InputWidgetBase
      inputType="date"
      inputAddon={<i className="fa fa-calendar" />}
      postprocessValue={postprocessDate}
      validate={validateDate}
      {...props}
    />
  );
}