Convert Date utilties to TypeScript

pull/7640/head
Mark McDowall 2 months ago
parent 782af002d6
commit 8482f3da1a
No known key found for this signature in database

@ -1,6 +1,6 @@
import ModelBase from 'App/ModelBase';
import { DateFilterValue } from 'Components/Filter/Builder/DateFilterBuilderRowValue';
import { FilterBuilderTypes } from 'Helpers/Props/filterBuilderTypes';
import { DateFilterValue, FilterType } from 'Helpers/Props/filterTypes';
import { Error } from './AppSectionState';
import BlocklistAppState from './BlocklistAppState';
import CalendarAppState from './CalendarAppState';
@ -42,7 +42,7 @@ export interface FilterBuilderProp<T> {
export interface PropertyFilter {
key: string;
value: string | string[] | number[] | boolean[] | DateFilterValue;
type: string;
type: FilterType;
}
export interface Filter {

@ -4,17 +4,16 @@ import SelectInput from 'Components/Form/SelectInput';
import TextInput from 'Components/Form/TextInput';
import usePrevious from 'Helpers/Hooks/usePrevious';
import {
IN_LAST,
IN_NEXT,
NOT_IN_LAST,
NOT_IN_NEXT,
DateFilterBuilderTime,
DateFilterValue,
FilterType,
} from 'Helpers/Props/filterTypes';
import { InputChanged, InputOnChange } from 'typings/inputs';
import isString from 'Utilities/String/isString';
import { FilterBuilderRowValueProps, NAME } from './FilterBuilderRowValue';
import styles from './DateFilterBuilderRowValue.css';
const timeOptions = [
const timeOptions: DateFilterBuilderTime[] = [
{ key: 'seconds', value: 'seconds' },
{ key: 'minutes', value: 'minutes' },
{ key: 'hours', value: 'hours' },
@ -23,20 +22,15 @@ const timeOptions = [
{ key: 'months', value: 'months' },
];
function isInFilter(filterType: string | undefined) {
function isInFilter(filterType: FilterType) {
return (
filterType === IN_LAST ||
filterType === NOT_IN_LAST ||
filterType === IN_NEXT ||
filterType === NOT_IN_NEXT
filterType === 'inLast' ||
filterType === 'notInLast' ||
filterType === 'inNext' ||
filterType === 'notInNext'
);
}
export interface DateFilterValue {
time: string;
value: number | null;
}
interface DateFilterBuilderRowValueProps<T>
extends Omit<
FilterBuilderRowValueProps<T, string>,

@ -23,10 +23,10 @@ import translate from 'Utilities/String/translate';
import FilterBuilderRow from './FilterBuilderRow';
import styles from './FilterBuilderModalContent.css';
const NEW_FILTER: Partial<PropertyFilter> = {
key: undefined,
value: undefined,
type: '',
const NEW_FILTER: PropertyFilter = {
key: '',
value: '',
type: 'unknown',
};
interface FilterBuilderModalContentProps<T> {
@ -76,7 +76,7 @@ function FilterBuilderModalContent<T>({
const [label, setLabel] = useState(initialLabel);
// Push an empty filter if there aren't any filters. FilterBuilderRow
// will handle initializing the filter.
const [filters, setFilters] = useState<Partial<PropertyFilter>[]>(
const [filters, setFilters] = useState<PropertyFilter[]>(
initialFilters.length ? initialFilters : [NEW_FILTER]
);
const [labelErrors, setLabelErrors] = useState<ValidationMessage[]>([]);

@ -7,12 +7,11 @@ import {
FilterBuilderTypes,
possibleFilterTypes,
} from 'Helpers/Props/filterBuilderTypes';
import { DateFilterValue, FilterType } from 'Helpers/Props/filterTypes';
import { InputChanged } from 'typings/inputs';
import sortByProp from 'Utilities/Array/sortByProp';
import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue';
import DateFilterBuilderRowValue, {
DateFilterValue,
} from './DateFilterBuilderRowValue';
import DateFilterBuilderRowValue from './DateFilterBuilderRowValue';
import DefaultFilterBuilderRowValue from './DefaultFilterBuilderRowValue';
import HistoryEventTypeFilterBuilderRowValue from './HistoryEventTypeFilterBuilderRowValue';
import IndexerFilterBuilderRowValue from './IndexerFilterBuilderRowValue';
@ -134,7 +133,7 @@ interface FilterBuilderRowProps<T> {
index: number;
filterKey?: string;
filterValue?: (DateFilterValue | string) | string[] | number[] | boolean[];
filterType?: string;
filterType: FilterType;
filterCount: number;
filterBuilderProps: FilterBuilderProp<T>[];
sectionItems: T[];
@ -195,7 +194,7 @@ function FilterBuilderRow<T>({
);
const handleFilterTypeChange = useCallback(
({ value }: InputChanged<string>) => {
({ value }: InputChanged<FilterType>) => {
if (filterKey == null || filterValue == null || filterType == null) {
return;
}

@ -6,6 +6,7 @@ import {
filterBuilderValueTypes,
kinds,
} from 'Helpers/Props';
import { FilterType } from 'Helpers/Props/filterTypes';
import { InputOnChange } from 'typings/inputs';
import convertToBytes from 'Utilities/Number/convertToBytes';
import formatBytes from 'Utilities/Number/formatBytes';
@ -93,7 +94,7 @@ export interface FilterBuilderRowValueProps<
T,
V extends string | number | boolean
> {
filterType?: string;
filterType: FilterType;
filterValue: V[];
sectionItems: T[];
selectedFilterBuilderProp: FilterBuilderProp<T>;

@ -1,5 +1,5 @@
import translate from 'Utilities/String/translate';
import * as filterTypes from './filterTypes';
import { FilterType } from './filterTypes';
export const ARRAY = 'array';
export const CONTAINS = 'contains';
@ -11,6 +11,11 @@ export const STRING = 'string';
export const all = [ARRAY, CONTAINS, DATE, EQUAL, EXACT, NUMBER, STRING];
interface FilterBuilderTypeOption {
key: FilterType;
value: () => string;
}
export type FilterBuilderTypes =
| 'array'
| 'contains'
@ -20,128 +25,131 @@ export type FilterBuilderTypes =
| 'number'
| 'string';
export const possibleFilterTypes = {
export const possibleFilterTypes: Record<
FilterBuilderTypes,
FilterBuilderTypeOption[]
> = {
array: [
{
key: filterTypes.CONTAINS,
key: 'contains',
value: () => translate('FilterContains'),
},
{
key: filterTypes.NOT_CONTAINS,
key: 'notContains',
value: () => translate('FilterDoesNotContain'),
},
],
contains: [
{
key: filterTypes.CONTAINS,
key: 'contains',
value: () => translate('FilterContains'),
},
],
date: [
{
key: filterTypes.LESS_THAN,
key: 'lessThan',
value: () => translate('FilterIsBefore'),
},
{
key: filterTypes.GREATER_THAN,
key: 'greaterThan',
value: () => translate('FilterIsAfter'),
},
{
key: filterTypes.IN_LAST,
key: 'inLast',
value: () => translate('FilterInLast'),
},
{
key: filterTypes.NOT_IN_LAST,
key: 'notInLast',
value: () => translate('FilterNotInLast'),
},
{
key: filterTypes.IN_NEXT,
key: 'inNext',
value: () => translate('FilterInNext'),
},
{
key: filterTypes.NOT_IN_NEXT,
key: 'notInNext',
value: () => translate('FilterNotInNext'),
},
],
equal: [
{
key: filterTypes.EQUAL,
key: 'equal',
value: () => translate('FilterIs'),
},
],
exact: [
{
key: filterTypes.EQUAL,
key: 'equal',
value: () => translate('FilterIs'),
},
{
key: filterTypes.NOT_EQUAL,
key: 'notEqual',
value: () => translate('FilterIsNot'),
},
],
number: [
{
key: filterTypes.EQUAL,
key: 'equal',
value: () => translate('FilterEqual'),
},
{
key: filterTypes.GREATER_THAN,
key: 'greaterThan',
value: () => translate('FilterGreaterThan'),
},
{
key: filterTypes.GREATER_THAN_OR_EQUAL,
key: 'greaterThanOrEqual',
value: () => translate('FilterGreaterThanOrEqual'),
},
{
key: filterTypes.LESS_THAN,
key: 'lessThan',
value: () => translate('FilterLessThan'),
},
{
key: filterTypes.LESS_THAN_OR_EQUAL,
key: 'lessThanOrEqual',
value: () => translate('FilterLessThanOrEqual'),
},
{
key: filterTypes.NOT_EQUAL,
key: 'notEqual',
value: () => translate('FilterNotEqual'),
},
],
string: [
{
key: filterTypes.CONTAINS,
key: 'contains',
value: () => translate('FilterContains'),
},
{
key: filterTypes.NOT_CONTAINS,
key: 'notContains',
value: () => translate('FilterDoesNotContain'),
},
{
key: filterTypes.EQUAL,
key: 'equal',
value: () => translate('FilterEqual'),
},
{
key: filterTypes.NOT_EQUAL,
key: 'notEqual',
value: () => translate('FilterNotEqual'),
},
{
key: filterTypes.STARTS_WITH,
key: 'startsWith',
value: () => translate('FilterStartsWith'),
},
{
key: filterTypes.NOT_STARTS_WITH,
key: 'notStartsWith',
value: () => translate('FilterDoesNotStartWith'),
},
{
key: filterTypes.ENDS_WITH,
key: 'endsWith',
value: () => translate('FilterEndsWith'),
},
{
key: filterTypes.NOT_ENDS_WITH,
key: 'notEndsWith',
value: () => translate('FilterDoesNotEndWith'),
},
],

@ -31,5 +31,42 @@ export const all = [
STARTS_WITH,
NOT_STARTS_WITH,
ENDS_WITH,
NOT_ENDS_WITH
NOT_ENDS_WITH,
];
export type FilterType =
| 'unknown'
| 'contains'
| 'equal'
| 'greaterThan'
| 'greaterThanOrEqual'
| 'inLast'
| 'notInLast'
| 'inNext'
| 'notInNext'
| 'lessThan'
| 'lessThanOrEqual'
| 'notContains'
| 'notEqual'
| 'startsWith'
| 'notStartsWith'
| 'endsWith'
| 'notEndsWith';
export type FilterDateType =
| 'seconds'
| 'minutes'
| 'hours'
| 'days'
| 'weeks'
| 'months';
export interface DateFilterBuilderTime {
key: FilterDateType;
value: string;
}
export interface DateFilterValue {
time: string;
value: number | null;
}

@ -1,43 +0,0 @@
import moment from 'moment';
import * as filterTypes from 'Helpers/Props/filterTypes';
import isAfter from 'Utilities/Date/isAfter';
import isBefore from 'Utilities/Date/isBefore';
export default function(itemValue, filterValue, type) {
if (!itemValue) {
return false;
}
switch (type) {
case filterTypes.LESS_THAN:
return moment(itemValue).isBefore(filterValue);
case filterTypes.GREATER_THAN:
return moment(itemValue).isAfter(filterValue);
case filterTypes.IN_LAST:
return (
isAfter(itemValue, { [filterValue.time]: filterValue.value * -1 }) &&
isBefore(itemValue)
);
case filterTypes.NOT_IN_LAST:
return (
isBefore(itemValue, { [filterValue.time]: filterValue.value * -1 })
);
case filterTypes.IN_NEXT:
return (
isAfter(itemValue) &&
isBefore(itemValue, { [filterValue.time]: filterValue.value })
);
case filterTypes.NOT_IN_NEXT:
return (
isAfter(itemValue, { [filterValue.time]: filterValue.value })
);
default:
return false;
}
}

@ -0,0 +1,50 @@
import moment, { MomentInput } from 'moment';
import { FilterType } from 'Helpers/Props/filterTypes';
import isAfter from 'Utilities/Date/isAfter';
import isBefore from 'Utilities/Date/isBefore';
export default function (
itemValue: MomentInput,
filterValue: string | { time: string; value: number },
type: FilterType
) {
if (!itemValue) {
return false;
}
if (typeof filterValue === 'string') {
if (type === 'lessThan') {
return moment(itemValue).isSame(filterValue);
}
if (type === 'greaterThan') {
return moment(itemValue).isAfter(filterValue);
}
return false;
}
if (type === 'inLast') {
return (
isAfter(itemValue, { [filterValue.time]: filterValue.value * -1 }) &&
isBefore(itemValue)
);
}
if (type === 'notInLast') {
return isBefore(itemValue, { [filterValue.time]: filterValue.value * -1 });
}
if (type === 'inNext') {
return (
isAfter(itemValue) &&
isBefore(itemValue, { [filterValue.time]: filterValue.value })
);
}
if (type === 'notInNext') {
return isAfter(itemValue, { [filterValue.time]: filterValue.value });
}
return false;
}

@ -1,6 +1,6 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function formatDate(date, dateFormat) {
function formatDate(date: MomentInput, dateFormat: string) {
if (!date) {
return '';
}

@ -1,11 +1,11 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
import translate from 'Utilities/String/translate';
import formatTime from './formatTime';
import isToday from './isToday';
import isTomorrow from './isTomorrow';
import isYesterday from './isYesterday';
function getRelativeDay(date, includeRelativeDate) {
function getRelativeDay(date: MomentInput, includeRelativeDate: boolean) {
if (!includeRelativeDate) {
return '';
}
@ -25,17 +25,29 @@ function getRelativeDay(date, includeRelativeDate) {
return '';
}
function formatDateTime(date, dateFormat, timeFormat, { includeSeconds = false, includeRelativeDay = false } = {}) {
function formatDateTime(
date: MomentInput,
dateFormat: string,
timeFormat: string,
{ includeSeconds = false, includeRelativeDay = false } = {}
) {
if (!date) {
return '';
}
const relativeDay = getRelativeDay(date, includeRelativeDay);
const formattedDate = moment(date).format(dateFormat);
const formattedTime = formatTime(date, timeFormat, { includeMinuteZero: true, includeSeconds });
const formattedTime = formatTime(date, timeFormat, {
includeMinuteZero: true,
includeSeconds,
});
if (relativeDay) {
return translate('FormatDateTimeRelative', { relativeDay, formattedDate, formattedTime });
return translate('FormatDateTimeRelative', {
relativeDay,
formattedDate,
formattedTime,
});
}
return translate('FormatDateTime', { formattedDate, formattedTime });
}

@ -1,7 +1,7 @@
import moment from 'moment';
import moment, { DurationInputArg1 } from 'moment';
import translate from 'Utilities/String/translate';
function formatShortTimeSpan(timeSpan) {
function formatShortTimeSpan(timeSpan: DurationInputArg1) {
if (!timeSpan) {
return '';
}

@ -1,6 +1,10 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function formatTime(date, timeFormat, { includeMinuteZero = false, includeSeconds = false } = {}) {
function formatTime(
date: MomentInput,
timeFormat: string,
{ includeMinuteZero = false, includeSeconds = false } = {}
) {
if (!date) {
return '';
}

@ -1,8 +1,8 @@
import moment from 'moment';
import moment, { DurationInputArg1 } from 'moment';
import padNumber from 'Utilities/Number/padNumber';
import translate from 'Utilities/String/translate';
function formatTimeSpan(timeSpan) {
function formatTimeSpan(timeSpan: DurationInputArg1) {
if (!timeSpan) {
return '';
}

@ -74,7 +74,7 @@ function getRelativeDate({
return includeTime ? translate('DayOfWeekAt', { day, time }) : day;
}
return includeTime
return includeTime && timeFormat
? formatDateTime(date, shortDateFormat, timeFormat, { includeSeconds })
: moment(date).format(shortDateFormat);
}

@ -1,17 +0,0 @@
import moment from 'moment';
function isAfter(date, offsets = {}) {
if (!date) {
return false;
}
const offsetTime = moment();
Object.keys(offsets).forEach((key) => {
offsetTime.add(offsets[key], key);
});
return moment(date).isAfter(offsetTime);
}
export default isAfter;

@ -0,0 +1,21 @@
import moment, { MomentInput } from 'moment';
import { FilterDateType } from 'Helpers/Props/filterTypes';
function isAfter(
date: MomentInput,
offsets: Partial<Record<FilterDateType, number>> = {}
) {
if (!date) {
return false;
}
const offsetTime = moment();
Object.entries(offsets).forEach(([key, value]) => {
offsetTime.add(value, key as FilterDateType);
});
return moment(date).isAfter(offsetTime);
}
export default isAfter;

@ -1,17 +0,0 @@
import moment from 'moment';
function isBefore(date, offsets = {}) {
if (!date) {
return false;
}
const offsetTime = moment();
Object.keys(offsets).forEach((key) => {
offsetTime.add(offsets[key], key);
});
return moment(date).isBefore(offsetTime);
}
export default isBefore;

@ -0,0 +1,21 @@
import moment, { MomentInput } from 'moment';
import { FilterDateType } from 'Helpers/Props/filterTypes';
function isBefore(
date: MomentInput,
offsets: Partial<Record<FilterDateType, number>> = {}
) {
if (!date) {
return false;
}
const offsetTime = moment();
Object.entries(offsets).forEach(([key, value]) => {
offsetTime.add(value, key as FilterDateType);
});
return moment(date).isBefore(offsetTime);
}
export default isBefore;

@ -1,6 +1,6 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function isInNextWeek(date) {
function isInNextWeek(date: MomentInput) {
if (!date) {
return false;
}

@ -1,6 +1,6 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function isSameWeek(date) {
function isSameWeek(date: MomentInput) {
if (!date) {
return false;
}

@ -1,6 +1,6 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function isToday(date) {
function isToday(date: MomentInput) {
if (!date) {
return false;
}

@ -1,6 +1,6 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function isTomorrow(date) {
function isTomorrow(date: MomentInput) {
if (!date) {
return false;
}

@ -1,6 +1,6 @@
import moment from 'moment';
import moment, { MomentInput } from 'moment';
function isYesterday(date) {
function isYesterday(date: MomentInput) {
if (!date) {
return false;
}
Loading…
Cancel
Save