;\n }\n\n private getStateSavingTableKey() {\n if (!this.props.stateSaving || !this.props.stateSaving.tableUniqueKey) {\n console.log('State saving unique table key not set!');\n return '';\n }\n\n return 'DataTable_' + this.props.stateSaving.tableUniqueKey;\n }\n\n private getGlobalSearch = () => {\n if (!this.props.globalSearch) {\n return null;\n }\n\n return (\n \n }\n size=\"middle\"\n value={this.state.globalFilter || ''}\n onChange={(e: any) => this.setState({ globalFilter: e.target.value })}\n onPressEnter={() => this.onSearch()}\n onSearch={() => this.onSearch()}\n />\n \n );\n };\n\n private callFetchData(pagination: any, filters: any, sorter: any, globalFilter: string | null) {\n if (this.props.fetchData && typeof this.props.fetchData === 'function') {\n const requestState = this.getTableStateDTO(pagination, filters, sorter, globalFilter);\n\n this.props.fetchData(\n requestState,\n () => requestState.echo === this.echo,\n (response) => {\n const pager = { ...pagination };\n pager.total = response.filteredCount;\n pager.dataTableUnfilteredTotal = response.totalCount;\n if (pager.pageSize * (pager.current - 1) > response.filteredCount) {\n pager.current = 0;\n }\n this.setState({\n data: response.results || [],\n pagination: pager,\n sumResult: response.sumResult,\n });\n }\n );\n } else if (this.props.fetchData && this.props.fetchData.fetch) {\n const requestState = this.getTableStateDTO(pagination, filters, sorter, globalFilter);\n this.setState({ loading: true });\n\n this.props.fetchData.fetch(requestState)\n .then(response => {\n if (requestState.echo !== this.echo) {\n return;\n }\n\n const pager = { ...pagination };\n pager.total = response.filteredCount;\n pager.dataTableUnfilteredTotal = response.totalCount;\n if (pager.pageSize * (pager.current - 1) > response.filteredCount) {\n pager.current = 0;\n }\n this.setState({\n data: response.results || [],\n loading: false,\n pagination: pager,\n sumResult: response.sumResult,\n }, () => {\n if (this.props.fetchData && typeof this.props.fetchData !== 'function' && this.props.fetchData.success) {\n this.props.fetchData.success(response.results || []);\n }\n });\n })\n .catch((error: any) => {\n this.setState({ loading: false });\n if (this.props.fetchData && typeof this.props.fetchData !== 'function' && this.props.fetchData.fail) {\n this.props.fetchData.fail(error);\n } else {\n notification.error({\n message: (this.props.fetchData && typeof this.props.fetchData !== 'function' && this.props.fetchData.failureMessage) ?\n this.props.fetchData?.failureMessage :\n 'Failed to retrieve data.'\n });\n }\n });\n }\n }\n\n private handleTableChange(pagination: any, filters: any, sorter: any) {\n const pager = { ...this.state.pagination };\n pager.current = pagination.current;\n pager.pageSize = pagination.pageSize;\n\n this.setState({\n pagination: pager,\n sorter: sorter,\n });\n\n this.callFetchData(pager, this.state.filters, sorter, this.state.globalFilter);\n\n if (this.props.stateSaving && this.props.stateSaving.enabled) {\n if (this.state.sorter.columnKey !== sorter.columnKey || this.state.sorter.order !== sorter.order) {\n this.saveTableState(\n {\n columnKey: sorter.columnKey,\n field: sorter.field,\n order: sorter.order,\n },\n this.state.filters,\n this.state.columnStates,\n this.state.globalFilter\n );\n }\n }\n }\n\n private saveTableState(sorter: any, filters: any, columnStates: any, globalFilter: string | null) {\n if (this.props.stateSaving && this.props.stateSaving.enabled) {\n const data = JSON.stringify({\n sorter,\n filters,\n columnStates,\n globalFilter,\n });\n\n this.props.stateSaving.perSession\n ? sessionStorage.setItem(this.getStateSavingTableKey(), data)\n : localStorage.setItem(this.getStateSavingTableKey(), data);\n }\n }\n\n private getTableStateDTO(pagination: any, filters: any, sorter: any, globalFilter: string | null): TableRequestDTO {\n this.echo += 1;\n return {\n pageLength: pagination.pageSize || pagination.defaultPageSize,\n page: (pagination.current || pagination.defaultCurrent) - 1,\n sortField: sorter.field || null,\n sortOrder: sorter.order || null,\n echo: this.echo,\n filters: filters,\n globalFilter,\n };\n }\n\n private textFilter(stateObject: TableColumnState, columnTitle: any): any {\n if (!stateObject) {\n return ;\n }\n\n return (\n \n (this.searchInputs[stateObject.columnProp] = ele)}\n placeholder={TranslationUtil.translate('datatables.searchColumn', { columnTitle: columnTitle })} // TODO: columnTitle could be react element\n value={stateObject.searchText || ''}\n onChange={(e: any) => this.onInputChange(e, stateObject)}\n onPressEnter={() => this.onSearch(stateObject)}\n allowClear={true}\n width={130}\n />\n \n
\n );\n }\n\n private dateFilter(stateObject: TableColumnState, columnTitle: any): any {\n let div: any;\n const searchButtonId = 'button_' + stateObject.columnProp;\n return (\n (div = ele)} className=\"date-filter-dropdown\">\n (this.searchInputs[stateObject.columnProp] = ele)}\n placeholder={TranslationUtil.translate('datatables.searchColumn', { columnTitle: columnTitle })} // TODO: columnTitle could be react element\n // value={stateObject.searchText}\n onChange={(date, dateString) => this.onDateInputChange(date, dateString, stateObject, searchButtonId)}\n getPopupContainer={() => div}\n format=\"M/D/YYYY\"\n allowClear={true}\n />\n \n
\n );\n }\n\n private dateRangeFilter(\n stateObject: TableColumnState,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n columnTitle: any\n ): any {\n let div: any;\n const searchButtonId = 'button_' + stateObject.columnProp;\n return (\n (div = ele)} className=\"daterange-filter-dropdown\">\n (this.searchInputs[stateObject.columnProp] = ele)}\n onChange={(date, dateString) => this.onDateRangeInputChange(date, dateString, stateObject, document.getElementById(searchButtonId))}\n onOpenChange={(status) => this.onDateRangePickerOpenChange(status, stateObject)}\n value={stateObject.searchText ?\n [moment(stateObject.searchText.split(' - ')[0]), moment(stateObject.searchText.split(' - ')[1])] :\n undefined}\n getPopupContainer={() => div}\n format=\"M/D/YYYY\"\n allowClear={true}\n />\n \n
\n );\n }\n\n private booleanCheckboxFilter(\n stateObject: TableColumnState,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n columnTitle: any\n ): any {\n let searchButton: any;\n return (\n \n (this.searchInputs[stateObject.columnProp] = ele)}\n onChange={(e) => this.onInputChange(e, stateObject, searchButton, (stateCopy) => this.onSearch(stateCopy))}\n checked={!!stateObject.searchText}\n />\n
\n );\n }\n\n private booleanRadioFilter(\n stateObject: TableColumnState,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n columnTitle: any\n ): any {\n const searchButtonId = 'button_' + stateObject.columnProp;\n return (\n \n {/* TODO: Fix this ref because Ant broke it... */}\n (this.searchInputs[stateObject.columnProp] = ele)}\n onChange={(e) => this.onInputChange(e, stateObject, document.getElementById(searchButtonId))}\n value={stateObject.searchText ? stateObject.searchText : ''}\n >\n \n \n \n \n \n
\n );\n }\n\n private dropdownFilter(stateObject: TableColumnState, column: any): any {\n if (column.filterMode == 'tree') {\n const treeData: { title: string; key: string; children: [{ title: string; key: string;}] }[] = column.dropdownFilterOptions || []; // title, key\n return (\n \n
{ this.onInputChange({ target: { value: opts.join(','), type: 'title' } }, stateObject); }}\n treeData={treeData}\n />\n \n \n \n );\n }\n else {\n const options: { text: string; value: string }[] = column.dropdownFilterOptions || []; // text, value\n return (\n \n {column.filterType === FilterType.DropdownMulti ? (\n
this.onInputChange({ target: { value: opts.join(','), type: 'text' } }, stateObject)}\n value={(stateObject.searchText || '').split(',')}\n style={{ textAlign: 'left' }}\n >\n {options.map((o: any, i: number) => (\n \n (this.searchInputs[stateObject.columnProp] = ele)} value={o.value}>\n {o.text}\n \n {i < options.length - 1 ?
: null}\n \n ))}\n \n ) : (\n // TODO: Fix this ref because Ant broke it...\n
(this.searchInputs[stateObject.columnProp] = ele)}\n onChange={(e) => this.onInputChange(e, stateObject)}\n value={stateObject.searchText || undefined}\n style={{ textAlign: 'left' }}\n >\n {options.map((o: any, i: number) => (\n \n {o.text}\n {i < options.length - 1 ?
: null}\n \n ))}\n \n )}\n\n
\n
\n
\n );\n }\n }\n\n private filterIcon(stateObject: TableColumnState) {\n return stateObject.filtered ? (\n \n ) : (\n \n );\n }\n\n private onFilterVisibleChangeWithFocus(stateObject: TableColumnState): any {\n return (visible: boolean) => {\n const stateCopy = { ...stateObject };\n stateCopy.filterVisible = visible;\n\n this.setState({ columnStates: this.getUpdatedColumnStateList(stateCopy) }, () => {\n // Use setTimeout so that the element ref exists after first rendering\n setTimeout(() => {\n if (this.searchInputs[stateCopy.columnProp]) {\n this.searchInputs[stateCopy.columnProp].focus();\n }\n }, 100); //Changed from 0 to 100 to prevent focus at top of screen\n });\n };\n }\n\n private onFilterVisibleChange(stateObject: TableColumnState): any {\n return (visible: boolean) => {\n const stateCopy = { ...stateObject };\n stateCopy.filterVisible = visible;\n\n this.setState({\n columnStates: this.getUpdatedColumnStateList(stateCopy),\n });\n };\n }\n\n private onDateRangePickerOpenChange(\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n open: boolean,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n stateObject: TableColumnState\n ): any {\n // return (status: boolean) => {\n // let picker = this.searchInputs[stateObject.columnProp];\n // let currentText = (picker.value[0] as moment.Moment).format(picker.format) +\n // ' - ' + (picker.value[1] as moment.Moment).format(picker.format);\n //console.log(`date range picker ${status ? 'opened' : 'closed'}`);\n // if (currentText !== stateObject.searchText) {\n // console.log('date range filter changed');\n // }\n // var stateCopy = { ...stateObject };\n // stateCopy.filterVisible = visible;\n // this.setState(\n // { columnStates: this.getUpdatedColumnStateList(stateCopy) },\n // () => this.searchInputs[stateCopy.columnProp] && this.searchInputs[stateCopy.columnProp].focus());\n // };\n }\n\n private onInputChange = (\n e: any,\n stateObject: TableColumnState,\n searchButton?: any,\n callback?: (columnState: TableColumnState) => any\n ) => {\n const stateCopy = { ...stateObject };\n stateCopy.searchText = e.target.type === 'checkbox' ? e.target.checked : e.target.value;\n\n this.setState({ columnStates: this.getUpdatedColumnStateList(stateCopy) }, () => {\n if (searchButton) {\n searchButton.focus();\n }\n if (callback) {\n callback(stateCopy);\n }\n });\n };\n\n private onDateInputChange = (\n date: moment.Moment | null,\n dateString: string,\n stateObject: TableColumnState,\n searchButtonId: string\n ) => {\n const stateCopy = { ...stateObject };\n stateCopy.searchText = dateString;\n\n this.setState({ columnStates: this.getUpdatedColumnStateList(stateCopy) }, () => {\n const e = document.getElementById(searchButtonId);\n if (e) {\n e.focus();\n }\n });\n };\n\n private onDateRangeInputChange = (\n dates: any, // RangeValue,\n dateStrings: [string, string],\n stateObject: TableColumnState,\n searchButton: any\n ) => {\n const stateCopy = { ...stateObject };\n stateCopy.searchText = dateStrings[0] && dateStrings[1] ? `${dateStrings[0]} - ${dateStrings[1]}` : null;\n\n this.setState({ columnStates: this.getUpdatedColumnStateList(stateCopy) }, () => {\n searchButton.focus();\n });\n };\n\n private onSearch = (stateObject?: TableColumnState) => {\n let updatedColumnsStates: TableColumnState[] = [];\n const filters: TableRequestFilterDTO[] = this.state.filters.map((f) => f);\n\n if (stateObject) {\n const stateCopy = { ...stateObject };\n const { searchText } = stateCopy;\n // const reg = new RegExp(searchText ? searchText : '', 'gi');\n stateCopy.filterVisible = false;\n stateCopy.filtered = !!searchText;\n\n const filterObj = filters.filter((value) => value.columnProp === stateCopy.columnProp);\n if (filterObj.length > 0) {\n filterObj[0].filter = searchText;\n } else {\n filters.push({ columnProp: stateCopy.columnProp, filter: searchText });\n }\n\n updatedColumnsStates = this.getUpdatedColumnStateList(stateCopy);\n } else {\n updatedColumnsStates = this.state.columnStates;\n }\n\n if (this.props.serverSide) {\n this.setState(\n {\n filters,\n pagination: { ...this.state.pagination, current: 1 },\n columnStates: updatedColumnsStates,\n },\n () => this.callFetchData(this.state.pagination, filters, this.state.sorter, this.state.globalFilter)\n );\n } else {\n const data = (this.props.data || [])\n .map((item: T): any => {\n let match = true;\n filters.forEach((f) => {\n let reg = new RegExp(f.filter ? f.filter : '', 'gi');\n const columnState = updatedColumnsStates.filter((ucs) => ucs.columnProp === f.columnProp)[0];\n const propVal = columnState.renderDataTransform\n ? columnState.renderDataTransform(item[columnState.columnProp], item)\n : item[columnState.columnProp];\n const propType = columnState.columnType || typeof propVal;\n switch (propType) {\n case ColumnType.Text:\n if (f.filter && (columnState.filterType === FilterType.DropdownSingle || columnState.filterType === FilterType.DropdownMulti)) {\n let fSplit: string[] = [f.filter || ''];\n if (f.filter?.includes(',')) {\n fSplit = f.filter.split(',');\n }\n\n match = match && propVal ? fSplit.includes(propVal) : false;\n }\n else {\n match = match && (propVal ? propVal.match(reg) : false);\n }\n break;\n case ColumnType.Date:\n if (columnState.filterType === FilterType.DateRange) {\n if (moment.isMoment(propVal) && f.filter) {\n const dateSplit = f.filter.split(' - ');\n if (dateSplit.length === 2) {\n match = match && propVal.isBetween(moment(dateSplit[0]), moment(dateSplit[1]), 'days', '[]');\n }\n }\n }\n else {\n if (f.filter && moment(propVal).isValid() && moment(f.filter).isValid()) {\n match = match && moment(f.filter).isSame(moment(propVal));\n }\n }\n break;\n case 'string':\n match = match && propVal.match(reg);\n break;\n case ColumnType.Number:\n case 'number':\n reg = new RegExp(f.filter ? parseFloat(f.filter).toString() : '', 'gi');\n match = match && propVal.toFixed(2) === f.filter;\n break;\n case ColumnType.Boolean:\n case 'boolean':\n match = match && (!f.filter || propVal?.toString() === f.filter);\n break;\n case 'object':\n if (moment.isMoment(propVal) && f.filter) {\n const dateSplit = f.filter.split(' - ');\n if (dateSplit.length === 2) {\n match = match && propVal.isBetween(moment(dateSplit[0]), moment(dateSplit[1]), 'days', '[]');\n }\n }\n break;\n default:\n break;\n }\n });\n\n let globalMatch = true;\n if (this.state.globalFilter) {\n this.state.globalFilter.split(',').forEach((f) => {\n f = f.trim();\n const reg = new RegExp(f ? f : '', 'gi');\n let rowMatch = false;\n for (const prop in item) {\n // eslint-disable-next-line no-prototype-builtins\n if ((item as any).hasOwnProperty(prop)) {\n const propVal = item[prop];\n switch (typeof propVal) {\n case 'string':\n rowMatch = rowMatch || !!propVal.match(reg);\n break;\n case 'number':\n // Use starts with for numbers?\n rowMatch = rowMatch || !!(propVal as number).toString().match(reg);\n break;\n case 'boolean':\n rowMatch = rowMatch || !f || (propVal as boolean).toString() === f;\n break;\n case 'object':\n if (moment.isMoment(propVal) && f) {\n // Ignore\n }\n break;\n default:\n break;\n }\n }\n }\n globalMatch = globalMatch && rowMatch;\n });\n }\n\n if (!match || !globalMatch) {\n return null;\n }\n return {\n ...item,\n // name: (\n // \n // {part.name.split(reg).map((text, i) => (\n // i > 0 ? [{match[0]}, text] : text\n // ))}\n // \n // ),\n };\n })\n .filter((item: any) => !!item);\n\n this.setState({\n filters,\n columnStates: updatedColumnsStates,\n filteredData: data,\n sumResult: this.getLocalSumResult(data),\n });\n }\n\n this.saveTableState(\n {\n columnKey: this.state.sorter.columnKey,\n field: this.state.sorter.field,\n order: this.state.sorter.order,\n },\n filters,\n updatedColumnsStates,\n this.state.globalFilter\n );\n };\n\n private getColumnState(customColumnProps: DataTableColumnProps): TableColumnState {\n return (\n this.state.columnStates.find(\n (cs) => cs.columnProp === (customColumnProps.dataIndex || customColumnProps.key)\n ) ||\n TableColumnState.create({\n columnProp: customColumnProps.dataIndex || customColumnProps.key,\n columnType: customColumnProps.columnType,\n initialSearchValue: customColumnProps.initialFilterValue || '',\n searchText:\n customColumnProps.initialFilterValue !== null && customColumnProps.initialFilterValue !== undefined\n ? (customColumnProps.initialFilterValue as string)\n : '',\n filtered: customColumnProps.initialFilterValue !== null && customColumnProps.initialFilterValue !== undefined,\n renderDataTransform: customColumnProps.renderDataTransform,\n })\n );\n }\n\n private getUpdatedColumnStateList(modifiedColumnState: TableColumnState): TableColumnState[] {\n return this.state.columnStates.map((cs) =>\n cs.columnProp === modifiedColumnState.columnProp ? modifiedColumnState : cs\n );\n }\n\n private isEditing = (record: T) => {\n return record === this.state.editingRecord;\n };\n\n private edit = (record: T, form?: FormInstance, index?: number, saveOnClickOutside?: boolean) => {\n if (this.props.editOptions && !this.props.editOptions.fullTableEdit && index === this.state.editingIndex) {\n return;\n }\n\n const editRow = () => {\n if (form) {\n this.editingRowForm = form;\n this.editingRowForm.setFieldsValue(record);\n }\n\n this.setState({ editingRecord: record, editingIndex: index });\n };\n\n if (saveOnClickOutside) {\n this.saveOnClickOutside(form || this.editingRowForm, record || ({} as T), index || -1);\n }\n\n if (form) {\n this.save(form, record || ({} as T), index || -1, (saved) => {\n if (!saved) {\n return;\n }\n\n editRow();\n });\n } else {\n editRow();\n }\n };\n\n private save = (form: FormInstance, record: T, index: number, callback?: (saved: boolean) => void) => {\n form\n .validateFields()\n .then((row) => {\n let isChanged = false;\n\n for (const property in row) {\n if (moment.isMoment(row[property])) {\n if (property.toLowerCase().indexOf('time') > -1 && property.toLowerCase().indexOf('date') === -1) {\n row[property] = (row[property] as moment.Moment).format('HH:mm:ss');\n } else {\n row[property] = (row[property] as moment.Moment).format();\n }\n }\n }\n\n for (const property in row) {\n if (row[property] !== record[property]) {\n isChanged = true;\n }\n }\n\n const finishSave = (success: boolean, updatedRows?: T[]) => {\n this.setState(\n {\n data: success && updatedRows ? updatedRows : this.state.data,\n editingRecord: null,\n editingIndex: null,\n },\n () => {\n this.refresh();\n if (callback) {\n callback(success);\n }\n }\n );\n };\n\n if (isChanged) {\n if (this.props.editOptions && this.props.editOptions.saveRow) {\n this.props.editOptions.saveRow(record, row as T, (success, updatedRows) => {\n if (!success) {\n return;\n }\n\n finishSave(success, updatedRows);\n });\n } else {\n finishSave(true);\n }\n }\n\n // const newData = [...this.state.timesheetDetails];\n // const index = newData.findIndex(item => id === item.id);\n // if (index > -1) {\n // const item = newData[index];\n // newData.splice(index, 1, {\n // ...item,\n // ...row,\n // });\n // this.setState({ timesheetDetails: newData, editingId: null }, () => this._timesheetEntryDataTable.refresh());\n // } else {\n // newData.push(row);\n // this.setState({ timesheetDetails: newData, editingId: null }, () => this._timesheetEntryDataTable.refresh());\n // }\n })\n .catch(() => {\n return;\n });\n };\n\n private cancel = () => {\n this.setState({ editingRecord: null, editingIndex: null }, () =>\n this.props.editOptions ? (this.props.editOptions.cancelEdit ? this.props.editOptions.cancelEdit() : null) : null\n );\n };\n\n private getLocalSumResult = (data: T[]) => {\n if (!this.props.showSum) {\n return null;\n }\n\n const columns = this.props.columns;\n\n if (data.length <= 1) {\n return null;\n }\n\n // TODO: dataIndex is probably an array...\n const result: any = {};\n columns.forEach((c) => {\n result[(c.dataIndex as string) || ''] = undefined;\n });\n\n data.forEach((d) => {\n columns.forEach((c) => {\n const dataIndexSplit = ((c.dataIndex as string) || '').split('.');\n let temp = d;\n dataIndexSplit.forEach((dis) => (temp = temp[dis]));\n const val = temp;\n result[(c.dataIndex as string) || ''] =\n (result[(c.dataIndex as string) || ''] || 0) + (val || 0);\n });\n });\n\n return result || null;\n };\n}\n\nexport default DataTable;\n","import { getTranslate, TranslateOptions, TranslatePlaceholderData } from 'react-localize-redux';\nimport { store } from '../redux/Store';\n\nexport default class TranslationUtil {\n public static translate(\n id: string,\n data?: TranslatePlaceholderData | undefined,\n options?: TranslateOptions | undefined\n ): string | any {\n const translate = getTranslate(store.getState().localize);\n return translate(id, data, options);\n }\n}\n","import { InputNumber } from 'antd';\nimport * as React from 'react';\n\ninterface NumberInputProps {\n value?: number;\n onChange?: (value: number) => void;\n onKeyUp?: (event: React.KeyboardEvent) => void;\n // onBlur?: (value: number) => void;\n prefixCls?: string;\n min?: number;\n max?: number;\n step?: number | string;\n defaultValue?: number;\n tabIndex?: number;\n onKeyDown?: React.FormEventHandler;\n disabled?: boolean;\n readOnly?: boolean;\n size?: 'large' | 'small' | 'default';\n formatter?: (value: number | string | undefined) => string;\n parser?: (displayValue: string | undefined) => number;\n placeholder?: string;\n style?: React.CSSProperties;\n className?: string;\n name?: string;\n id?: string;\n precision?: 0 | 1 | 2 | 3 | 4 | 5;\n minFractionDigits?: 0 | 1 | 2 | 3 | 4 | 5;\n}\nconst parseRegex = /\\$\\s?|(,*)|(\\w+)/g;\nconst removeAddlDotRegex = /(\\..*)\\./g;\nconst removeTrailingZeroRegex = /\\.0+$|(\\.0?[1-9]+)0+$/;\nconst formatRegex = /(?!^-)[^0-9,.]/g;\nconst empty = '';\nconst replace = '$1';\n\nclass NumberInput extends React.Component {\n private readonly _inputRef = React.createRef();\n private justFocused!: boolean;\n private formatterFunction: (num: number) => string;\n\n constructor(props: NumberInputProps) {\n super(props);\n this.formatter = this.formatter.bind(this);\n this.parser = this.parser.bind(this);\n this.onFocus = this.onFocus.bind(this);\n this.onBlur = this.onBlur.bind(this);\n\n if (typeof this.props.precision === 'number') {\n this.formatterFunction = new Intl.NumberFormat(undefined, {\n maximumFractionDigits: this.props.precision,\n minimumFractionDigits:\n this.props.minFractionDigits === null ? this.props.precision : this.props.minFractionDigits,\n }).format;\n } else {\n this.formatterFunction = new Intl.NumberFormat(undefined, {\n maximumFractionDigits: 5,\n minimumFractionDigits: this.props.minFractionDigits === null ? 0 : this.props.minFractionDigits,\n }).format;\n }\n }\n\n getFormat(val: string | number | undefined) {\n if (\n (typeof val === 'number' && isNaN(val)) ||\n (typeof val === 'string' && val === 'NaN') ||\n val === '' ||\n val === undefined\n ) {\n return '';\n }\n\n const num = parseFloat(`${val}`.replace(parseRegex, empty));\n\n return this.formatterFunction(num);\n }\n\n formatter(val: string | number | undefined) {\n if (!this._inputRef.current || !this._inputRef.current.state.focused) {\n return this.getFormat(val);\n }\n\n const newVal = `${val}`.replace(removeAddlDotRegex, replace).replace(formatRegex, empty);\n\n if (this.justFocused) {\n this.justFocused = false;\n return newVal.replace(removeTrailingZeroRegex, replace);\n }\n return newVal;\n }\n\n parser(val: string | undefined) {\n return (val || '').replace(parseRegex, '') as any;\n }\n\n onFocus(evt: any) {\n const input = evt.target;\n this.justFocused = true;\n setTimeout(() => input.setSelectionRange(0, 9999), 100);\n }\n\n onBlur(evt: any) {\n const input = evt.target;\n const formatted = this.getFormat(input.value);\n input.value = formatted;\n this.justFocused = false;\n }\n\n render() {\n const theseProps = {\n ref: this._inputRef,\n onFocus: this.onFocus,\n onBlur: this.onBlur,\n formatter: this.formatter,\n parser: this.parser,\n };\n\n const props = { ...theseProps, ...this.props };\n // props.onBlur = (evt: any) => {\n // if (this.props.onBlur) {\n // this.props.onBlur(evt.target.value);\n // }\n // this.onBlur(evt);\n // };\n props.className = 'right-align ' + this.props.className;\n\n return ;\n }\n}\n\nexport default NumberInput;\n","import { Input } from 'antd';\nimport { SizeType } from 'antd/lib/config-provider/SizeContext';\nimport moment from 'moment';\nimport * as React from 'react';\n\ninterface Time24HourProps {\n value?: moment.Moment | null;\n onChange?: (e: moment.Moment | undefined) => void;\n format?: string;\n disabled?: boolean;\n size?: SizeType;\n className?: string;\n style?: React.CSSProperties;\n minuteStep?: number;\n}\n\ninterface Time24HourState {\n value: moment.Moment | undefined;\n editing: boolean;\n raw: string | undefined;\n}\n\nclass Time24Hour extends React.Component {\n private isDirty = false;\n\n constructor(props: Time24HourProps) {\n super(props);\n\n this.state = {\n value: props.value || undefined,\n editing: false,\n raw: props.value ? props.value.format('HHmm') : undefined,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n componentDidUpdate(prevProps: Time24HourProps, prevState: Time24HourState) {\n if (prevProps.value !== this.props.value) {\n this.setState({\n value: this.props.value || undefined,\n raw: this.props.value ? this.props.value.format('HHmm') : '',\n });\n }\n }\n\n render() {\n const { raw, value, editing } = this.state;\n const val = editing ? raw : value ? value.format(this.props.format || 'HH:mm') : undefined;\n\n return (\n {\n const target = e.target;\n this.setState({ editing: true }, () => {\n target.select();\n });\n }}\n onBlur={() => this.setState({ editing: false }, this.sendChange)}\n type={editing ? 'number' : ''}\n size={this.props.size || 'small'}\n value={val}\n placeholder=\"Time\"\n onChange={this.onChange}\n disabled={this.props.disabled || false}\n className={this.props.className}\n style={this.props.style}\n />\n );\n }\n\n private onChange = (e: React.ChangeEvent) => {\n this.isDirty = true;\n const val = e.target.value;\n let value = this.parseValue(val);\n if (value != null && this.props.minuteStep) {\n value = this.roundToNearestXXMinutes(value, this.props.minuteStep);\n }\n this.setState({ raw: val, value: value });\n };\n\n private roundToNearestXXMinutes = (dateTime: moment.Moment, roundTo: number) => {\n let remainder = roundTo - ((dateTime.minute() + dateTime.second() / 60) % roundTo);\n remainder = remainder > roundTo / 2 ? (remainder = -roundTo + remainder) : remainder;\n return dateTime.clone().add(remainder, 'minutes').seconds(0);\n };\n\n private parseValue = (value: string | undefined) => {\n if (!value) {\n return undefined;\n }\n\n let parsed = moment(value, 'HHmm');\n\n if (!parsed.isValid() && value.length === 3) {\n parsed = moment(`0${value}`, 'HHmm');\n }\n\n if (!parsed.isValid()) {\n return undefined;\n }\n\n return parsed;\n };\n\n private sendChange = () => {\n if (this.props.onChange && this.isDirty) {\n this.isDirty = false;\n this.props.onChange(this.state.value);\n }\n };\n}\n\nexport default Time24Hour;\n","import TableRequestDTO from '../../../models/TableRequestDTO';\nimport { DataTableButton, DataTableButtonType, ExportButton, ResetButton } from './DataTable';\n\nclass DataTableButtonUtil {\n public static Default(label: string, onClick: () => void) {\n const button: DataTableButton = {\n dataTableButtonType: DataTableButtonType.Generic,\n label,\n onClick\n };\n return button;\n }\n\n public static Primary(label: string, onClick: () => void) {\n const button: DataTableButton = {\n dataTableButtonType: DataTableButtonType.Generic,\n label,\n onClick,\n type: 'primary'\n };\n return button;\n }\n\n public static Danger(label: string, onClick: () => void) {\n const button: DataTableButton = {\n dataTableButtonType: DataTableButtonType.Generic,\n label,\n onClick,\n danger: true\n };\n return button;\n }\n\n public static Export(exportHandler: (tableState: TableRequestDTO) => any, loading?: boolean) {\n const button: ExportButton = {\n dataTableButtonType: DataTableButtonType.Export,\n label: 'Export',\n export: exportHandler,\n loading,\n disabled: loading\n };\n return button;\n }\n\n public static Reset() {\n const button: ResetButton = {\n dataTableButtonType: DataTableButtonType.Reset,\n label: 'Reset'\n };\n return button;\n }\n\n /*\n public static Link(label: string, to: string) {\n const button: LinkButton = {\n dataTableButtonType: DataTableButtonType.Link,\n label,\n to\n };\n return button;\n }\n */\n}\n\nexport default DataTableButtonUtil;","export default class PhoneNumberFormatUtil {\n public static format = (phoneNumber: string): string => {\n const cleaned = ('' + phoneNumber).replace(/D/g, '');\n const match = cleaned.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n if (match) {\n return `(${match[1]}) ${match[2]}-${match[3]}`;\n }\n return '';\n }\n}\n","import moment from 'moment';\nimport * as React from 'react';\nimport PhoneNumberFormatUtil from '../../../utils/PhoneNumberFormatUtil';\n\nexport interface Address {\n name?: string | null;\n line1: string | null;\n line2?: string | null;\n city: string | null;\n state: string | null;\n zip: string | null;\n}\n\nexport interface AddressWithContact extends Address, Contact {\n}\n\nexport interface Contact {\n phone?: string | null;\n email?: string | null;\n}\n\nclass DataTableCellRendererUtil {\n public static ShortDate = (value: string | moment.Moment) => {\n if (!value) {\n return;\n }\n\n const date = moment.isMoment(value) ? value : moment(value);\n\n if (!date.isValid()) {\n return '';\n }\n\n return {date.format('M/D/YYYY')};\n }\n\n public static ShortTime = (value: string | moment.Moment) => {\n if (!value) {\n return;\n }\n\n let date = moment.isMoment(value) ? value : moment(value);\n\n if (!date.isValid()) {\n date = moment(value, 'HH:mm:ss');\n\n if (!date.isValid()) {\n return '';\n }\n }\n\n return {date.format('h:mm a')};\n }\n\n public static LongDate = (value: string | moment.Moment) => {\n if (!value) {\n return;\n }\n\n const date = moment.isMoment(value) ? value : moment(value);\n\n if (!date.isValid()) {\n return '';\n }\n\n return {date.format('ddd, MMM D YYYY')};\n }\n\n public static DateAndTime = (value: string | moment.Moment) => {\n if (!value) {\n return;\n }\n\n const date = moment.isMoment(value) ? value : moment(value);\n\n if (!date.isValid()) {\n return '';\n }\n\n return {date.format('M/D/YYYY h:mm a')};\n }\n\n public static Currency = (value: string) => {\n if (!value || isNaN(value as any)) {\n return;\n }\n\n try {\n const num = parseFloat(value);\n return ${num.toFixed(2).replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,')};\n } catch (error) {\n return;\n }\n }\n\n public static Percentage = (value: string) => {\n if (!value || isNaN(value as any)) {\n return;\n }\n\n try {\n const num = +parseFloat(value).toFixed(2);\n\n return {num.toString().replace(/(\\d)(?=(\\d{3})+\\.)/g, '$1,')}%;\n } catch (error) {\n return;\n }\n }\n\n public static Decimal = (value: string | number, decimalPlaces: number) => {\n if ((!value && value !== 0) || isNaN(value as any)) {\n return;\n }\n\n try {\n const num = typeof value === 'number' ? value : parseFloat(value);\n return {num.toFixed(decimalPlaces)};\n } catch (error) {\n return;\n }\n }\n\n public static BooleanYesNo = (value: boolean) => value ? 'Yes' : 'No';\n\n public static BooleanYesNoEmpty = (value: boolean) => value === false ? 'No' : value === true ? 'Yes' : '';\n\n public static BooleanYesEmpty = (value: boolean) => value ? 'Yes' : '';\n\n //changed for 508 compliance\n //public static BooleanCheckbox = (value: boolean) => ;\n public static BooleanCheckbox = (value: boolean) => value ? 'Yes' : 'No'; \n\n public static Address(transform: (rowData: T) => Address) {\n const addressRender = (value: any, rowData: T) => {\n const address = transform(rowData);\n\n const hasCityStateOrZip = address.city || address.state || address.zip;\n const needNewlineAfterName = address.name && (address.line1 || address.line2 || hasCityStateOrZip);\n const needNewlineAfterAddress1 = address.line1 && (address.line2 || hasCityStateOrZip);\n const needNewlineAfterAddress2 = address.line2 && hasCityStateOrZip;\n\n return (\n <>\n {address.name ? address.name : ''}\n {needNewlineAfterName ?
: ''}\n {address.line1}\n {needNewlineAfterAddress1 ?
: ''}\n {address.line2}\n {needNewlineAfterAddress2 ?
: ''}\n {address.city}\n {address.city && (address.state || address.zip) ? ', ' : ''}\n {address.state}\n {address.state && address.zip ? ' ' : ''}\n {address.zip}\n >\n );\n };\n\n return addressRender;\n }\n\n public static AddressWithContact(transform: (rowData: T) => AddressWithContact) {\n const addressRender = (value: any, rowData: T) => {\n const addressAndContact = transform(rowData);\n const hasAddress = addressAndContact.line1 && addressAndContact.city && addressAndContact.state && addressAndContact.zip;\n return (\n <>\n {addressAndContact.name ? addressAndContact.name : ''}\n {addressAndContact.name && hasAddress ?
: ''}\n {hasAddress ? addressAndContact.line1 : ''}\n {hasAddress ?
: ''}\n {addressAndContact.line2 ? addressAndContact.line2 : ''}\n {addressAndContact.line2 ?
: ''}\n {hasAddress ? addressAndContact.city + ', ' + addressAndContact.state + ', ' + addressAndContact.zip : ''}\n {
}\n {addressAndContact.phone ? PhoneNumberFormatUtil.format(addressAndContact.phone) : ''}\n {addressAndContact.phone && PhoneNumberFormatUtil.format(addressAndContact.phone) !== '' ?
: ''}\n {addressAndContact.email ? addressAndContact.email : ''}\n >\n );\n };\n\n return addressRender;\n }\n\n // public static LinkButtons(links: string | { link: string; icon: JSX.Element }[]) {\n // if (!links || links.length === 0) {\n // return;\n // }\n\n // const isString = typeof links === 'string';\n // const strVal = links as string;\n // const arrVal = links as { link: string; icon: JSX.Element }[];\n // return (\n // \n // {isString\n // ? strVal\n // ? this.LinkButton(strVal)\n // : ''\n // : arrVal.map((link, index) => this.LinkButton(link.link, link.icon, undefined, index))}\n //
\n // );\n // }\n\n // public static LinkButton(link: string, icon?: JSX.Element, shape?: ButtonShape, index?: number) {\n // shape = shape ? shape : !icon ? 'circle' : undefined;\n // if (!icon) {\n // icon = ;\n // }\n\n // return (\n // \n // {shape ? : icon}\n // \n // );\n // }\n}\n\nexport default DataTableCellRendererUtil;\n","import { CheckCircleTwoTone, FlagTwoTone, DownloadOutlined } from '@ant-design/icons';\nimport { Button, Tooltip } from 'antd';\nimport { SizeType } from 'antd/lib/config-provider/SizeContext';\nimport * as React from 'react';\nimport { Link } from 'react-router-dom';\nimport PhoneNumberFormatUtil from '../../../utils/PhoneNumberFormatUtil';\nimport { ColumnType, DataTableColumnProps, FilterType } from './DataTable';\nimport DataTableCellRendererUtil, { Address, AddressWithContact } from './DataTableCellRendererUtil';\n\nexport interface ColumnButton {\n text: string;\n onClick: (rowData: T) => void;\n /** Default size is 'small' */\n size?: SizeType;\n visible?: (rowData: T) => boolean;\n}\n\nexport interface ColumnIconButton {\n onClick: (rowData: T) => void;\n size?: SizeType;\n visible?: (rowData: T) => boolean;\n}\n\nclass DataTableColumnUtil {\n public static Text(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = FilterType.Text;\n res.columnType = ColumnType.Text;\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter = res.sorter === undefined ? true : res.sorter;\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static Currency(\n title: string,\n dataIndex: string,\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = FilterType.Text;\n res.columnType = ColumnType.Number;\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter =\n res.sorter === undefined ? (a: any, b: any) => a[dataIndex] - b[dataIndex] : res.sorter;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n res.render = (value: number, record: T) => (value || value === 0 ? FORMAT.currency2(value) : '');\n res.align = 'right';\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static Number(\n title: string,\n dataIndex: string,\n precision?: 0 | 2 | 5,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = FilterType.Text;\n res.columnType = ColumnType.Number;\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter =\n res.sorter === undefined ? (a: any, b: any) => a[dataIndex] - b[dataIndex] : res.sorter;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n res.render = (value: number, record: T) =>\n value || value === 0\n ? precision === 0\n ? FORMAT.quantity0(value)\n : precision === 2\n ? FORMAT.quantity2(value)\n : precision === 5\n ? FORMAT.quantity5(value)\n : value\n : '';\n res.align = 'right';\n return res;\n }\n\n public static Phone(\n title: string,\n dataIndex: string,\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = FilterType.Text;\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter = res.sorter === undefined ? true : res.sorter;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n res.render = (value: number, record: T) => (value || value === 0 ? PhoneNumberFormatUtil.format(value.toString()) : '');\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static BooleanYesNo(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n filterType?: FilterType,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n return DataTableColumnUtil.Boolean(title, dataIndex, width, filterType, DataTableCellRendererUtil.BooleanYesNo, props);\n }\n\n public static YesNoEmpty(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n filterType?: FilterType,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n return DataTableColumnUtil.Boolean(title, dataIndex, width, filterType, DataTableCellRendererUtil.BooleanYesNoEmpty, props);\n }\n\n public static BooleanYesEmpty(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n filterType?: FilterType,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n return DataTableColumnUtil.Boolean(title, dataIndex, width, filterType, DataTableCellRendererUtil.BooleanYesEmpty, props);\n }\n\n public static BooleanCheckbox(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n filterType?: FilterType,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n return DataTableColumnUtil.Boolean(title, dataIndex, width, filterType, DataTableCellRendererUtil.BooleanCheckbox, props);\n }\n\n public static Boolean(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n filterType?: FilterType,\n render?: (value: any, record: T) => React.ReactNode,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = filterType ? filterType : FilterType.BooleanCheckbox;\n res.columnType = ColumnType.Boolean;\n res.render = render;\n res.title = title;\n res.dataIndex = dataIndex;\n res.align = 'center';\n res.sorter = res.sorter === undefined ? true : res.sorter;\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static Date(\n title: string | React.ReactElement,\n dataIndex: string | number | readonly React.ReactText[],\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = res.filterType || FilterType.DateRange;\n res.columnType = ColumnType.Date;\n res.render = DataTableCellRendererUtil.ShortDate;\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter = res.sorter === undefined ? true : res.sorter;\n res.align = 'center';\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static Address(\n title: string | React.ReactElement,\n dataIndex: string | number | readonly React.ReactText[],\n transform: (rowData: T) => Address,\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = FilterType.Text;\n res.columnType = ColumnType.Text;\n res.renderDataTransform = (value, record) => {\n const address = transform(record);\n return address.name + '|' + address.line1 + '|' + address.line2 + '|'\n + address.city + '|' + address.state + '|' + address.zip;\n };\n res.render = DataTableCellRendererUtil.Address(transform);\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter = res.sorter === undefined ? true : res.sorter;\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static AddressWithContact(\n title: string | React.ReactElement,\n dataIndex: string | number | readonly React.ReactText[],\n transform: (rowData: T) => AddressWithContact,\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.filterType = FilterType.Text;\n res.columnType = ColumnType.Text;\n res.renderDataTransform = (value, record) => {\n const address = transform(record);\n return address.name + '|' + address.line1 + '|' + address.line2 + '|'\n + address.city + '|' + address.state + '|' + address.zip\n + address.email + '|' + address.phone;\n };\n res.render = DataTableCellRendererUtil.AddressWithContact(transform);\n res.title = title;\n res.dataIndex = dataIndex;\n res.sorter = res.sorter === undefined ? true : res.sorter;\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static Buttons(\n //title: string,\n dataIndex: string | number | readonly React.ReactText[],\n buttons: ColumnButton[],\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.dataIndex = dataIndex;\n // eslint-disable-next-line\n res.render = (text, record) => (\n \n {buttons.map((b, index) => (\n (!b.visible || (b.visible && b.visible(record))) &&\n \n ))}\n
\n );\n res.title = 'Actions'; //508 compliance\n res.align = 'center';\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n public static CheckmarkButton(\n dataIndex: string | number | readonly React.ReactText[],\n icons: ColumnIconButton[],\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps);\n res.dataIndex = dataIndex;\n // eslint-disable-next-line\n res.render = (text, record) => (\n \n {icons.map((b, index) => (\n (!b.visible || (b.visible && b.visible(record))) &&\n \n ))}\n
\n );\n res.align = 'center';\n res.sorter = res.sorter === undefined ? true : res.sorter;\n if (width !== null && width !== undefined) {\n res.width = width;\n }\n return res;\n }\n\n\n public static DownloadButton(\n title: string,\n dataIndex: string | number | readonly React.ReactText[],\n icons: ColumnIconButton[],\n width?: string | number | null,\n props?: DataTableColumnProps\n ): DataTableColumnProps {\n const res = props || ({} as DataTableColumnProps