UNPKG

baseui

Version:

A React Component library implementing the Base design language

557 lines (549 loc) • 22.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var React = _interopRequireWildcard(require("react")); var _index = _interopRequireDefault(require("date-fns/format/index.js")); var _index2 = _interopRequireDefault(require("date-fns/getYear/index.js")); var _index3 = _interopRequireDefault(require("date-fns/getMonth/index.js")); var _index4 = _interopRequireDefault(require("date-fns/getQuarter/index.js")); var _index5 = _interopRequireDefault(require("date-fns/getDay/index.js")); var _index6 = _interopRequireDefault(require("date-fns/isAfter/index.js")); var _index7 = _interopRequireDefault(require("date-fns/isBefore/index.js")); var _index8 = _interopRequireDefault(require("date-fns/isEqual/index.js")); var _index9 = _interopRequireDefault(require("date-fns/set/index.js")); var _button = require("../button"); var _buttonGroup = require("../button-group"); var _checkbox = require("../checkbox"); var _utils = require("../datepicker/utils"); var _datepicker = require("../datepicker"); var _timepicker = require("../timepicker"); var _styles = require("../styles"); var _select = require("../select"); var _column = _interopRequireDefault(require("./column")); var _constants = require("./constants"); var _filterShell = _interopRequireDefault(require("./filter-shell")); var _locale = require("../locale"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /* Copyright (c) Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars const DATE_FORMAT = 'MM-dd-yyyy'; const MASK = '99-99-9999 - 99-99-9999'; const TIME_FORMAT = 'HH:mm ss:SS'; const FORMAT_STRING = `${DATE_FORMAT} ${TIME_FORMAT}`; // @ts-ignore function sortDates(a, b) { return a - b; } const RANGE_OPERATIONS = [{ localeLabelKey: 'datetimeFilterRangeDatetime', id: _constants.DATETIME_OPERATIONS.RANGE_DATETIME }, { localeLabelKey: 'datetimeFilterRangeDate', id: _constants.DATETIME_OPERATIONS.RANGE_DATE }, { localeLabelKey: 'datetimeFilterRangeTime', id: _constants.DATETIME_OPERATIONS.RANGE_TIME }]; const CATEGORICAL_OPERATIONS = [{ localeLabelKey: 'datetimeFilterCategoricalWeekday', id: _constants.DATETIME_OPERATIONS.WEEKDAY }, { localeLabelKey: 'datetimeFilterCategoricalMonth', id: _constants.DATETIME_OPERATIONS.MONTH }, { localeLabelKey: 'datetimeFilterCategoricalQuarter', id: _constants.DATETIME_OPERATIONS.QUARTER }, { localeLabelKey: 'datetimeFilterCategoricalHalf', id: _constants.DATETIME_OPERATIONS.HALF }, { localeLabelKey: 'datetimeFilterCategoricalYear', id: _constants.DATETIME_OPERATIONS.YEAR }]; const WEEKDAYS = [0, 1, 2, 3, 4, 5, 6]; const MONTHS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; const QUARTERS = [0, 1, 2, 3]; // @ts-ignore function Checks(props) { const [css, theme] = (0, _styles.useStyletron)(); return /*#__PURE__*/React.createElement("div", { className: css({ maxHeight: '256px', overflowY: 'auto' }) }, props.options.map(item => { const checked = props.value.includes(item.id); return /*#__PURE__*/React.createElement("div", { key: item.id, className: css({ marginBottom: theme.sizing.scale200 }) }, /*#__PURE__*/React.createElement(_checkbox.Checkbox, { checked: checked, onChange: () => { if (checked) { // @ts-ignore props.setValue(prev => prev.filter(i => i !== item.id)); } else { // @ts-ignore props.setValue(prev => [...prev, item.id]); } } }, item.label)); })); } // @ts-ignore function filterParamsToInitialState(input) { const output = { exclude: false, comparatorIndex: 0, rangeOperator: RANGE_OPERATIONS[0], categoricalOperator: CATEGORICAL_OPERATIONS[0], // @ts-ignore rangeDates: [], // @ts-ignore years: [], // @ts-ignore halves: [], // @ts-ignore quarters: [], // @ts-ignore months: [], // @ts-ignore weekdays: [] }; if (input) { const op = input.operation; if (input.range && input.range.length) { if (op === _constants.DATETIME_OPERATIONS.RANGE_DATETIME) { output.rangeDates = input.range; output.rangeOperator = RANGE_OPERATIONS[0]; } else if (op === _constants.DATETIME_OPERATIONS.RANGE_DATE) { output.rangeDates = input.range; output.rangeOperator = RANGE_OPERATIONS[1]; } else if (op === _constants.DATETIME_OPERATIONS.RANGE_TIME) { output.rangeDates = input.range; output.rangeOperator = RANGE_OPERATIONS[2]; } } else if (input.selection && input.selection.length) { output.comparatorIndex = 1; if (op === _constants.DATETIME_OPERATIONS.YEAR) { output.years = input.selection; output.categoricalOperator = CATEGORICAL_OPERATIONS[4]; } else if (op === _constants.DATETIME_OPERATIONS.HALF) { output.halves = input.selection; output.categoricalOperator = CATEGORICAL_OPERATIONS[3]; } else if (op === _constants.DATETIME_OPERATIONS.QUARTER) { output.quarters = input.selection; output.categoricalOperator = CATEGORICAL_OPERATIONS[2]; } else if (op === _constants.DATETIME_OPERATIONS.MONTH) { output.months = input.selection; output.categoricalOperator = CATEGORICAL_OPERATIONS[1]; } else if (op === _constants.DATETIME_OPERATIONS.WEEKDAY) { output.weekdays = input.selection; output.categoricalOperator = CATEGORICAL_OPERATIONS[0]; } } if (input.exclude) { output.exclude = input.exclude; } } return output; } // @ts-ignore function DatetimeFilter(props) { const [css, theme] = (0, _styles.useStyletron)(); const locale = React.useContext(_locale.LocaleContext); const mountNode = React.useRef(); const initialState = filterParamsToInitialState(props.filterParams); const datesSorted = React.useMemo(() => { return props.data.sort(sortDates); }, [props.data]); const presentYears = React.useMemo(() => { const dict = {}; // @ts-ignore props.data.forEach(date => { // @ts-ignore dict[(0, _index2.default)(date)] = true; }); return Object.keys(dict).map(n => parseInt(n)); }, [props.data]); const startOfWeek = React.useMemo(() => { return (0, _utils.getStartOfWeek)(new Date(), props.locale); }, [props.locale]); const localizedWeekdays = React.useMemo(() => { return [...WEEKDAYS.slice((0, _index5.default)(startOfWeek), 7), ...WEEKDAYS.slice(0, (0, _index5.default)(startOfWeek))]; }, [props.locale]); const [exclude, setExclude] = React.useState(initialState.exclude); const [comparatorIndex, setComparatorIndex] = React.useState(initialState.comparatorIndex); const [rangeOperator, setRangeOperator] = React.useState([initialState.rangeOperator]); const [categoricalOperator, setCategoricalOperator] = React.useState([initialState.categoricalOperator]); // eslint-disable-next-line @typescript-eslint/no-explicit-any const [rangeDates, setRangeDates] = React.useState(initialState.rangeDates.length ? initialState.rangeDates : [new Date(datesSorted[0]), new Date(datesSorted[datesSorted.length - 1])]); const [years, setYears] = React.useState(initialState.years); const [halves, setHalves] = React.useState(initialState.halves); const [quarters, setQuarters] = React.useState(initialState.quarters); const [months, setMonths] = React.useState(initialState.months); const [weekdays, setWeekdays] = React.useState(initialState.weekdays); const isRange = comparatorIndex === 0; const isCategorical = comparatorIndex === 1; return /*#__PURE__*/React.createElement(_filterShell.default, { exclude: exclude, onExcludeChange: () => setExclude(!exclude), onApply: () => { if (isRange) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const op = rangeOperator[0].id; let description = ''; if (op === _constants.DATETIME_OPERATIONS.RANGE_DATETIME) { const left = (0, _index.default)(rangeDates[0], FORMAT_STRING); const right = (0, _index.default)(rangeDates[1], FORMAT_STRING); description = `${left} - ${right}`; } else if (op === _constants.DATETIME_OPERATIONS.RANGE_DATE) { const left = (0, _index.default)(rangeDates[0], DATE_FORMAT); const right = (0, _index.default)(rangeDates[1], DATE_FORMAT); description = `${left} - ${right}`; } else if (op === _constants.DATETIME_OPERATIONS.RANGE_TIME) { const left = (0, _index.default)(rangeDates[0], TIME_FORMAT); const right = (0, _index.default)(rangeDates[1], TIME_FORMAT); description = `${left} - ${right}`; } props.setFilter({ operation: op, range: rangeDates, selection: [], description: description, exclude }); } if (isCategorical) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const op = categoricalOperator[0].id; let selection = []; let operatorLocaleLabelKey = ''; let description = ''; if (op === _constants.DATETIME_OPERATIONS.WEEKDAY) { selection = weekdays; operatorLocaleLabelKey = CATEGORICAL_OPERATIONS[0].localeLabelKey; description = weekdays.map(w => { const day = (0, _utils.addDays)(startOfWeek, localizedWeekdays.indexOf(w)); return (0, _utils.getWeekdayInLocale)(day, props.locale); }).join(', '); } else if (op === _constants.DATETIME_OPERATIONS.MONTH) { selection = months; operatorLocaleLabelKey = CATEGORICAL_OPERATIONS[1].localeLabelKey; description = months.map(m => (0, _utils.getMonthInLocale)(m, props.locale)).join(', '); } else if (op === _constants.DATETIME_OPERATIONS.QUARTER) { selection = quarters; operatorLocaleLabelKey = CATEGORICAL_OPERATIONS[2].localeLabelKey; description = quarters.map(q => (0, _utils.getQuarterInLocale)(q, props.locale)).join(', '); } else if (op === _constants.DATETIME_OPERATIONS.HALF) { selection = halves; operatorLocaleLabelKey = CATEGORICAL_OPERATIONS[3].localeLabelKey; description = halves.map(h => h === 0 ? locale.datatable.datetimeFilterCategoricalFirstHalf : locale.datatable.datetimeFilterCategoricalSecondHalf).join(', '); } else if (op === _constants.DATETIME_OPERATIONS.YEAR) { selection = years; operatorLocaleLabelKey = CATEGORICAL_OPERATIONS[4].localeLabelKey; description = years.join(', '); } if (operatorLocaleLabelKey) { // @ts-ignore description = `${locale.datatable[operatorLocaleLabelKey]} - ${description}`; } props.setFilter({ operation: op, range: [], selection, description, exclude }); } props.close(); } }, /*#__PURE__*/React.createElement("div", { ref: mountNode }, /*#__PURE__*/React.createElement(_buttonGroup.ButtonGroup, { size: _button.SIZE.compact, mode: _buttonGroup.MODE.radio, selected: comparatorIndex, onClick: (_, index) => setComparatorIndex(index), overrides: { Root: { style: ({ $theme }) => ({ marginBottom: $theme.sizing.scale300 }) } } }, /*#__PURE__*/React.createElement(_button.Button, { type: "button", overrides: { BaseButton: { style: { width: '100%' } } } }, locale.datatable.datetimeFilterRange), /*#__PURE__*/React.createElement(_button.Button, { type: "button", overrides: { BaseButton: { style: { width: '100%' } } } }, locale.datatable.datetimeFilterCategorical)), isRange && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_select.Select, { value: rangeOperator, onChange: params => setRangeOperator(params.value) // eslint-disable-next-line @typescript-eslint/no-explicit-any , mountNode: mountNode.current, options: RANGE_OPERATIONS.map(op => ({ // @ts-ignore label: locale.datatable[op.localeLabelKey], id: op.id })), size: "compact", clearable: false }), /*#__PURE__*/React.createElement("div", { className: css({ paddingTop: theme.sizing.scale600 }) }, (rangeOperator[0].id === _constants.DATETIME_OPERATIONS.RANGE_DATETIME || rangeOperator[0].id === _constants.DATETIME_OPERATIONS.RANGE_DATE) && /*#__PURE__*/React.createElement(_datepicker.Datepicker // eslint-disable-next-line @typescript-eslint/no-explicit-any , { mountNode: mountNode.current, value: rangeDates, onChange: ({ date }) => { if (Array.isArray(date)) { if (!date.length) return; const nextDates = date.map((d, i) => d ? (0, _utils.applyDateToTime)(rangeDates[i], d) : null); setRangeDates(nextDates); } }, formatString: DATE_FORMAT, mask: MASK, placeholder: "MM-DD-YYYY - MM-DD-YYYY", minDate: datesSorted[0], maxDate: datesSorted[datesSorted.length - 1], timeSelectStart: rangeOperator[0].id === _constants.DATETIME_OPERATIONS.RANGE_DATETIME, timeSelectEnd: rangeOperator[0].id === _constants.DATETIME_OPERATIONS.RANGE_DATETIME, overrides: { TimeSelect: { props: { size: 'compact' } } }, range: true, size: "compact", locale: props.locale })), (rangeOperator[0].id === _constants.DATETIME_OPERATIONS.RANGE_DATETIME || rangeOperator[0].id === _constants.DATETIME_OPERATIONS.RANGE_TIME) && /*#__PURE__*/React.createElement("div", { className: css({ display: 'flex', paddingTop: theme.sizing.scale100 }) }, /*#__PURE__*/React.createElement("div", { className: css({ width: '100%', marginRight: theme.sizing.scale300 }) }, /*#__PURE__*/React.createElement(_timepicker.TimePicker, { format: "24", value: rangeDates[0], onChange: time => time && setRangeDates([(0, _utils.applyTimeToDate)(rangeDates[0], time), rangeDates[1]]), creatable: true, size: "compact" })), /*#__PURE__*/React.createElement("div", { className: css({ width: '100%' }) }, /*#__PURE__*/React.createElement(_timepicker.TimePicker, { format: "24", value: rangeDates[1], onChange: time => time && setRangeDates([rangeDates[0], (0, _utils.applyTimeToDate)(rangeDates[1], time)]), creatable: true, size: "compact" })))), isCategorical && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(_select.Select, { value: categoricalOperator, onChange: params => setCategoricalOperator(params.value), options: CATEGORICAL_OPERATIONS.map(op => ({ // @ts-ignore label: locale.datatable[op.localeLabelKey], id: op.id })) // eslint-disable-next-line @typescript-eslint/no-explicit-any , mountNode: mountNode.current, size: "compact", clearable: false }), /*#__PURE__*/React.createElement("div", { className: css({ paddingLeft: theme.sizing.scale300, paddingTop: theme.sizing.scale500 }) }, categoricalOperator[0].id === _constants.DATETIME_OPERATIONS.WEEKDAY && /*#__PURE__*/React.createElement(Checks, { value: weekdays, setValue: setWeekdays, options: localizedWeekdays.map((w, offset) => { const day = (0, _utils.addDays)(startOfWeek, offset); return { label: (0, _utils.getWeekdayInLocale)(day, props.locale), id: w }; }) }), categoricalOperator[0].id === _constants.DATETIME_OPERATIONS.MONTH && /*#__PURE__*/React.createElement(Checks, { value: months, setValue: setMonths, options: MONTHS.map(m => ({ label: (0, _utils.getMonthInLocale)(m, props.locale), id: m })) }), categoricalOperator[0].id === _constants.DATETIME_OPERATIONS.QUARTER && /*#__PURE__*/React.createElement(Checks, { value: quarters, setValue: setQuarters, options: QUARTERS.map(q => ({ label: (0, _utils.getQuarterInLocale)(q, props.locale), id: q })) }), categoricalOperator[0].id === _constants.DATETIME_OPERATIONS.HALF && /*#__PURE__*/React.createElement(Checks, { value: halves, setValue: setHalves, options: [{ label: locale.datatable.datetimeFilterCategoricalFirstHalf, id: 0 }, { label: locale.datatable.datetimeFilterCategoricalSecondHalf, id: 1 }] }), categoricalOperator[0].id === _constants.DATETIME_OPERATIONS.YEAR && /*#__PURE__*/React.createElement(Checks, { value: years, setValue: setYears, options: presentYears.map(year => ({ label: year, id: year })) }))))); } // @ts-ignore function DatetimeCell(props) { const [css, theme] = (0, _styles.useStyletron)(); return /*#__PURE__*/React.createElement("div", { className: css({ ...theme.typography.MonoParagraphXSmall, display: 'flex', justifyContent: 'flex-end', width: '100%', whiteSpace: 'nowrap' }) }, (0, _index.default)(props.value, props.formatString)); } const defaultOptions = { title: '', sortable: true, filterable: true, formatString: FORMAT_STRING }; function DatetimeColumn(options) { const normalizedOptions = { ...defaultOptions, ...options }; return (0, _column.default)({ kind: _constants.COLUMNS.DATETIME, buildFilter: function (params) { return function (data) { let included = true; if (params.operation === _constants.DATETIME_OPERATIONS.YEAR) { included = params.selection.includes((0, _index2.default)(data)); } else if (params.operation === _constants.DATETIME_OPERATIONS.HALF) { const month = (0, _index3.default)(data); const half = month < 6 ? 0 : 1; included = params.selection.includes(half); } else if (params.operation === _constants.DATETIME_OPERATIONS.QUARTER) { // date-fns quarters are 1 indexed const quarter = (0, _index4.default)(data) - 1; included = params.selection.includes(quarter); } else if (params.operation === _constants.DATETIME_OPERATIONS.MONTH) { included = params.selection.includes((0, _index3.default)(data)); } else if (params.operation === _constants.DATETIME_OPERATIONS.WEEKDAY) { included = params.selection.includes((0, _index5.default)(data)); } if (params.operation === _constants.DATETIME_OPERATIONS.RANGE_DATE || params.operation === _constants.DATETIME_OPERATIONS.RANGE_TIME || params.operation === _constants.DATETIME_OPERATIONS.RANGE_DATETIME) { let [left, right] = params.range; if (params.operation === _constants.DATETIME_OPERATIONS.RANGE_DATE) { left = (0, _index9.default)(left, { hours: 0, minutes: 0, seconds: 0 }); right = (0, _index9.default)(right, { hours: 0, minutes: 0, seconds: 0 }); data = (0, _index9.default)(data, { hours: 0, minutes: 0, seconds: 0 }); } if (params.operation === _constants.DATETIME_OPERATIONS.RANGE_TIME) { left = (0, _index9.default)(left, { year: 2000, month: 1, date: 1 }); right = (0, _index9.default)(right, { year: 2000, month: 1, date: 1 }); data = (0, _index9.default)(data, { year: 2000, month: 1, date: 1 }); } const after = (0, _index6.default)(data, left) || (0, _index8.default)(data, left); const before = (0, _index7.default)(data, right) || (0, _index8.default)(data, right); included = after && before; } return params.exclude ? !included : included; }; }, cellBlockAlign: options.cellBlockAlign, fillWidth: options.fillWidth, filterable: normalizedOptions.filterable, mapDataToValue: options.mapDataToValue, maxWidth: options.maxWidth, minWidth: options.minWidth, renderCell: function RenderDatetimeCell(props) { return /*#__PURE__*/React.createElement(DatetimeCell, { value: props.value, formatString: normalizedOptions.formatString }); }, renderFilter: function RenderDatetimeFilter(props) { return /*#__PURE__*/React.createElement(DatetimeFilter, _extends({}, props, { locale: options.locale })); }, sortable: normalizedOptions.sortable, sortFn: sortDates, title: options.title }); } var _default = exports.default = DatetimeColumn;