UNPKG

novo-elements

Version:

1 lines 79.4 kB
{"version":3,"file":"novo-elements-services.mjs","sources":["../../../projects/novo-elements/src/services/component-utils/ComponentUtils.ts","../../../projects/novo-elements/src/services/data-provider/CollectionEvent.ts","../../../projects/novo-elements/src/services/data-provider/ArrayCollection.ts","../../../projects/novo-elements/src/services/data-provider/PagedArrayCollection.ts","../../../projects/novo-elements/src/services/novo-label-service.ts","../../../projects/novo-elements/src/services/date-format/DateFormat.ts","../../../projects/novo-elements/src/services/global/global.service.ts","../../../projects/novo-elements/src/services/options/OptionsService.ts","../../../projects/novo-elements/src/services/security/Security.ts","../../../projects/novo-elements/src/services/storage/storage.service.ts","../../../projects/novo-elements/src/services/template/NovoTemplateService.ts","../../../projects/novo-elements/src/services/novo-elements-services.ts"],"sourcesContent":["// NG2\nimport { ComponentRef, Injectable, Injector, StaticProvider, Type, ViewContainerRef } from '@angular/core';\n\n@Injectable()\nexport class ComponentUtils<T = any> {\n\n append<T>(ComponentClass: Type<T>, location: ViewContainerRef, providers?: StaticProvider[], onTop?: boolean): ComponentRef<T> { //eslint-disable-line\n const parent = location.injector;\n const index = onTop ? 0 : location.length;\n const injector = Injector.create({ providers, parent });\n return location.createComponent(ComponentClass, {\n index,\n injector,\n });\n }\n}\n","export class CollectionEvent {\n static REFRESH: string = 'Collection.REFRESH';\n static ADD: string = 'Collection.ADD';\n static REMOVE: string = 'Collection.REMOVE';\n static REMOVE_ALL: string = 'Collection.REMOVE_ALL';\n static REPLACE: string = 'Collection.REPLACE';\n static INVALIDATE_ALL: string = 'Collection.INVALIDATE_ALL';\n static SORT: string = 'Collection.SORT';\n static FILTER: string = 'Collection.FILTER';\n static CHANGE: string = 'Collection.CHANGE';\n static CURRENTPAGE_CHANGE: string = 'Collection.CURRENTPAGE_CHANGE';\n static PAGESIZE_CHANGE: string = 'Collection.PAGESIZE_CHANGE';\n static NUMBEROFPAGES_CHANGE: string = 'Collection.NUMBEROFPAGES_CHANGE';\n\n type: string = '';\n data: Array<any> = [];\n\n constructor(type = 'Collection.REFRESH', data = []) {\n this.type = type;\n this.data = data;\n }\n}\n","// Ng\nimport { EventEmitter } from '@angular/core';\nimport { Helpers } from 'novo-elements/utils';\n// App\nimport { Collection } from './Collection';\nimport { CollectionEvent } from './CollectionEvent';\n\n/**\n * Base Class for all Collection based data providers\n *\n * @example\n * var dp:DataProvider = new DataProvider();\n * dp.addItem({label:\"Item 1\"});\n * dp.addItem({label:\"Item 2\"});\n * dp.addItem({label:\"Item 3\"});\n * dp.addItem({label:\"Item 4\"});\n\n * var myList:List = new List();\n * myList.dataProvider = dp;\n */\nexport class ArrayCollection<T> implements Collection<T> {\n dataChange: EventEmitter<CollectionEvent> = new EventEmitter<CollectionEvent>();\n source: Array<T> = [];\n editData: Array<T> = [];\n isEditing: boolean = false;\n filterData: Array<T> = [];\n _filter: any = {};\n _sort: Array<any> = [];\n\n constructor(source: Array<T> = []) {\n this.source = source;\n this.editData = this.copy(this.source);\n this.filterData = this.source.slice();\n }\n\n get length() {\n return this.filterData.length;\n }\n\n get total(): number {\n return this.filterData.length;\n }\n\n get list(): Array<T> {\n return this.filterData;\n }\n\n isEmpty(): boolean {\n return this.length <= 0 && !this.isLoading() && !this.hasErrors();\n }\n\n hasErrors(): boolean {\n return false;\n }\n\n isLoading(): boolean {\n return false;\n }\n\n isFiltered(): boolean {\n return Object.keys(this._filter).length > 0;\n }\n\n /**\n * Method to switch the isEditingflag for the data source\n */\n edit() {\n this.isEditing = true;\n this.editData = this.copy(this.source);\n }\n\n /**\n * Method to leave edit mode and reset source\n */\n undo() {\n this.isEditing = false;\n this.source = this.copy(this.editData);\n this.refresh();\n }\n\n /**\n * Method to leave edit mode and save editData\n */\n commit() {\n this.isEditing = false;\n this.source = this.filterData.slice();\n this.refresh();\n }\n\n /**\n * Appends an item to the end of the data provider.\n *\n *\n * @memberOf ArrayCollection\n */\n addItem(item: T): void {\n this.isEditing ? this.editData.push(item) : this.source.push(item);\n this.onDataChange(new CollectionEvent(CollectionEvent.ADD, [item]));\n this.refresh();\n }\n\n /**\n * Adds a new item to the data provider at the specified index.\n *\n *\n * @memberOf ArrayCollection\n */\n addItemAt(item: T, index: number): void {\n this.isEditing ? this.editData.splice(index, 0, item) : this.source.splice(index, 0, item);\n this.onDataChange(new CollectionEvent(CollectionEvent.ADD, [item]));\n this.refresh();\n }\n\n /**\n * Appends multiple items to the end of the DataProvider and dispatches a CollectionEvent.ADD event.\n *\n * @memberOf ArrayCollection\n */\n addItems(items: Array<T>): void {\n this.isEditing ? this.editData.push(...items) : this.source.push(...items);\n this.onDataChange(new CollectionEvent(CollectionEvent.ADD, items));\n this.refresh();\n }\n\n /**\n * Adds several items to the data provider at the specified index and dispatches a CollectionEvent.ADD event.\n *\n * @memberOf ArrayCollection\n */\n addItemsAt(items: Array<T>, index: number): void {\n this.isEditing ? this.editData.splice(index, 0, ...items) : this.source.splice(index, 0, ...items);\n }\n\n /**\n * Creates a copy of the current ArrayCollection any.\n *\n * @memberOf ArrayCollection\n */\n clone(): ArrayCollection<T> {\n return new ArrayCollection(this.isEditing ? this.copy(this.editData) : this.copy(this.source));\n }\n\n /**\n * Creates a copy of the current ArrayCollection any.\n *\n * @memberOf ArrayCollection\n */\n copy(array: any[]) {\n return Helpers.deepClone(array);\n }\n\n /**\n * Concatenates the specified items to the end of the current data provider.\n *\n * @memberOf ArrayCollection\n */\n concat(items: Array<T>): void {\n this.addItems(items);\n }\n\n /**\n * Returns the item at the specified index.\n *\n * @memberOf ArrayCollection\n */\n getItemAt(index: number): any {\n return this.isEditing ? this.editData[index] : this.source[index];\n }\n\n /**\n * Returns the index of the specified item.\n *\n * @memberOf ArrayCollection\n */\n getItemIndex(item: T): number {\n return this.isEditing ? this.editData.indexOf(item) : this.source.indexOf(item);\n }\n\n /**\n * Invalidates all the data items that the DataProvider contains and dispatches a CollectionEvent.INVALIDATE_ALL event.\n *\n * @memberOf ArrayCollection\n */\n invalidate(): void {\n this.onDataChange(new CollectionEvent(CollectionEvent.INVALIDATE_ALL));\n }\n\n /**\n * Appends the specified data into the data that the data provider contains and removes any duplicate items.\n *\n * @memberOf ArrayCollection\n */\n merge(newData: Array<T>): void {\n for (const obj of newData) {\n const existing = ~this.getItemIndex(obj);\n if (existing) {\n this.replaceItem(obj, existing);\n } else {\n this.addItem(obj);\n }\n }\n }\n\n /**\n * Removes all items from the data provider and dispatches a CollectionEvent.REMOVE_ALL event.\n *\n * @memberOf ArrayCollection\n */\n removeAll(): void {\n this.source = [];\n this.editData = [];\n this.filterData = [];\n this.onDataChange(new CollectionEvent(CollectionEvent.REMOVE_ALL, []));\n this.refresh();\n }\n\n /**\n * Removes the specified item from the data provider and dispatches a CollectionEvent.REMOVE event.\n *\n * @memberOf ArrayCollection\n */\n removeItem(item: T): boolean {\n const index = this.getItemIndex(item);\n return this.removeItemAt(index);\n }\n\n /**\n * Removes the item at the specified index and dispatches a CollectionEvent.REMOVE event.\n *\n * @memberOf ArrayCollection\n */\n removeItemAt(index: number): boolean {\n const success = !!this.source.splice(index, 1);\n this.refresh();\n return success;\n }\n\n /**\n * Replaces an existing item with a new item and dispatches a CollectionEvent.REPLACE event.\n *\n * @memberOf ArrayCollection\n */\n replaceItem(newItem: any, oldItem: any): any {\n const index = this.getItemIndex(oldItem);\n if (index >= 0) {\n this.replaceItemAt(newItem, index);\n }\n }\n\n /**\n * Replaces the item at the specified index and dispatches a CollectionEvent.REPLACE event.\n *\n * @memberOf ArrayCollection\n */\n replaceItemAt(newItem: any, index: number): any {\n this.filterData.splice(index, 1, newItem);\n }\n\n /**\n * Sorts the items that the data provider contains and dispatches a CollectionEvent.SORT event.\n *\n * @memberOf ArrayCollection\n */\n get sort(): Array<any> {\n return this._sort;\n }\n\n set sort(value: Array<any>) {\n this._sort = value;\n this.refresh();\n }\n\n /**\n * Sorts the items that the data provider contains by the specified field and dispatches a CollectionEvent.SORT event.\n *\n * @memberOf ArrayCollection\n */\n sortOn(fieldName: any, reverse = false): Array<T> {\n this.filterData = this.filterData.sort(Helpers.sortByField(fieldName, reverse));\n this.onDataChange(new CollectionEvent(CollectionEvent.SORT));\n return this.filterData;\n }\n\n get filter(): any {\n return this._filter;\n }\n\n set filter(value: any) {\n this._filter = value;\n this.refresh();\n }\n\n filterOn(fieldName: any, value: any = null): Array<T> {\n this.filterData = this.filterData.filter(Helpers.filterByField(fieldName, value));\n return this.filterData;\n }\n\n onDataChange(event: CollectionEvent): void {\n this.dataChange.emit(event);\n }\n\n refresh(): void {\n this.filterData = this.isEditing ? this.editData.slice() : this.source.slice();\n for (const item of this._sort.reverse()) {\n this.sortOn(item.field, item.reverse);\n }\n for (const key in this._filter) {\n if (key) {\n this.filterOn(key, this._filter[key]);\n }\n }\n this.onDataChange(new CollectionEvent(CollectionEvent.CHANGE, this.filterData));\n }\n\n /**\n * Creates an Array any representation of the data that the data provider contains.\n *\n * @memberOf ArrayCollection\n */\n toArray(): Array<T> {\n return this.isEditing ? this.editData : this.source;\n }\n\n toJSON() {\n return this.isEditing ? this.editData : this.source;\n }\n}\n","import { ArrayCollection } from './ArrayCollection';\nimport { CollectionEvent } from './CollectionEvent';\nimport { PagedCollection } from './PagedCollection';\n\nexport class PagedArrayCollection<T> extends ArrayCollection<T> implements PagedCollection<T> {\n _page: number = 1;\n _numberOfPages: number = 1;\n _pageSize: number = 10;\n\n constructor(source: Array<T> = []) {\n super(source);\n }\n\n get numberOfPages(): number {\n let result: number = this.source.length / this.pageSize;\n result = Math.ceil(result);\n return result;\n }\n\n get page(): number {\n return this._page;\n }\n\n set page(value: number) {\n this._page = value;\n this.refresh();\n }\n\n get pageSize(): number {\n return this._pageSize;\n }\n\n set pageSize(value: number) {\n this._pageSize = value;\n this.refresh();\n }\n\n next(): number {\n if (this.page === this.numberOfPages) {\n return this.page;\n }\n this.page++;\n return this.page;\n }\n\n prev(): number {\n if (this._page === 1) {\n return this.page;\n }\n this.page--;\n return this.page;\n }\n\n first(): number {\n if (this.page === 1) {\n return this.page;\n }\n this.page = 1;\n return this.page;\n }\n\n last(): number {\n if (this.page === this.numberOfPages) {\n return this.page;\n }\n this.page = this.numberOfPages;\n return this.page;\n }\n\n refresh(): void {\n this.filterData = this.isEditing ? this.editData.slice() : this.source.slice();\n for (const item of this._sort.reverse()) {\n this.sortOn(item.field, item.reverse);\n }\n for (const key in this._filter) {\n if (key) {\n this.filterOn(key, this._filter[key]);\n }\n }\n if (this.page >= 0) {\n const start = (this.page - 1) * this.pageSize;\n const end = start + this.pageSize;\n const result = this.filterData.slice(start, end);\n this.onDataChange(new CollectionEvent(CollectionEvent.CHANGE, result));\n } else {\n this.onDataChange(new CollectionEvent(CollectionEvent.CHANGE, this.filterData));\n }\n }\n}\n","// NG2\nimport { Inject, Injectable, LOCALE_ID, Optional } from '@angular/core';\nimport { Day } from 'date-fns';\n\ninterface TimeFormatParts {\n hour: string;\n minute: string;\n dayPeriod?: string;\n}\n\nexport interface BigDecimalFormatOptions extends Intl.NumberFormatOptions {\n useAccountingFormat?: boolean; // Render negative numbers using parens. True: \"(3.14)\", False: \"-3.14\"\n}\n\n@Injectable()\nexport class NovoLabelService {\n and = 'and';\n not = 'not';\n filters = 'Filter';\n filterss = 'Filters';\n clear = 'Clear';\n sort = 'Sort';\n distributionListOwner = 'Owner';\n dateAdded = 'Date Added';\n emptyTableMessage = 'No Records to display...';\n noMatchingRecordsMessage = 'No Matching Records';\n noMoreRecordsMessage = 'No More Records';\n erroredTableMessage = 'Oops! An error occurred.';\n pickerError = 'Oops! An error occurred.';\n pickerTextFieldEmpty = 'Begin typing to see results.';\n pickerEmpty = 'No results to display...';\n tabbedGroupPickerEmpty = 'No results found';\n quickNoteError = 'Oops! An error occurred.';\n quickNoteEmpty = 'No results to display...';\n required = 'Required';\n numberTooLarge = 'Number is too large';\n apply = 'Apply';\n save = 'Save';\n cancel = 'Cancel';\n next = 'Next';\n itemsPerPage = 'Items per page:';\n chooseAField = 'Choose a field...';\n operator = 'Operator...';\n select = 'Select...';\n value = 'Value...';\n selectDateRange = 'Select Date Range...'\n typeToAddChips = 'Type and press Enter to add...'\n selected = 'Selected';\n selectAllOnPage = 'Select all on page';\n deselectAll = 'Deselect all';\n refresh = 'Refresh';\n close = 'Close';\n move = 'Move';\n startDate = 'Start Date';\n endDate = 'End Date';\n rate = 'Rate';\n more = 'more';\n clearAll = 'CLEAR ALL';\n clearAllNormalCase = 'Clear All';\n clearSort = 'Clear Sort';\n clearFilter = 'Clear Filter';\n clearSearch = 'Clear Search';\n clearSelected = 'Clear Selected';\n today = 'Today';\n now = 'Now';\n isRequired = 'is required';\n notValidYear = 'is not a valid year';\n isTooLarge = 'is too large';\n invalidAddress = 'requires at least one field filled out';\n invalidEmail = 'requires a valid email (ex. abc@123.com)';\n minLength = 'is required to be a minimum length of';\n past1Day = 'Past 1 Day';\n past7Days = 'Past 7 Days';\n past14Days = 'Past 14 Days';\n past21Days = 'Past 21 Days';\n past30Days = 'Past 30 Days';\n past60Days = 'Past 60 Days';\n past90Days = 'Past 90 Days';\n past180Days = 'Past 180 Days';\n past270Days = 'Past 270 Days';\n past1Year = 'Past 1 Year';\n next1Day = 'Next 1 Day';\n next7Days = 'Next 7 Days';\n next14Days = 'Next 14 Days';\n next21Days = 'Next 21 Days';\n next30Days = 'Next 30 Days';\n next60Days = 'Next 60 Days';\n next90Days = 'Next 90 Days';\n next180Days = 'Next 180 Days';\n next270Days = 'Next 270 Days';\n next1Year = 'Next 1 Year';\n future = 'Future';\n customDateRange = 'Custom Date Range';\n backToPresetFilters = 'Back to Preset Filters';\n okGotIt = 'Ok, Got it';\n address = 'Address';\n address1 = 'Address';\n apt = 'Apt'; // TODO delete\n address2 = 'Apt';\n city = 'City / Locality';\n state = 'State / Region';\n zip = 'Postal Code';\n zipCode = 'Postal Code'; // TODO delete\n country = 'Country';\n or = 'or';\n clickToBrowse = 'click to browse';\n chooseAFile = 'Choose a file';\n no = 'No';\n yes = 'Yes';\n search = 'SEARCH';\n noItems = 'There are no items';\n dateFormat = 'MM/dd/yyyy';\n dateFormatPlaceholder = 'MM/DD/YYYY';\n localDatePlaceholder = 'mm/dd/yyyy';\n timeFormatPlaceholderAM = 'hh:mm AM';\n timeFormatPlaceholder24Hour = 'HH:mm';\n timeFormatAM = 'AM';\n timeFormatPM = 'PM';\n confirmChangesModalMessage = 'Are you sure you want to change this field?';\n promptModalMessage = 'Do you want to perform the following changes?';\n asyncFailure = 'Async validation was not called within the 10s threshold, you might want to reload the page to try again';\n previous = 'Previous';\n actions = 'Actions';\n all = 'All';\n groupedMultiPickerEmpty = 'No items to display';\n groupedMultiPickerSelectCategory = 'Select a category from the left to get started';\n add = 'Add';\n encryptedFieldTooltip = 'This data has been stored at the highest level of security';\n noStatesForCountry = 'No states available for the selected country';\n selectCountryFirst = 'Please select a country before selecting a state';\n invalidIntegerInput = 'Special characters are not allowed for';\n maxRecordsReached = 'Sorry, you have reached the maximum number of records allowed for this field';\n selectFilterOptions = 'Please select one or more filter options below.';\n addCondition = 'Add Condition';\n includeAny = 'Include Any';\n includeAll = 'Include All';\n exclude = 'Exclude';\n excludeAny = 'Exclude Any';\n radius = 'Radius';\n insideRadius = 'Radius (Inside)';\n outsideRadius = 'Radius (Outside)';\n equals = 'Equals';\n equalTo = 'Equal To';\n greaterThan = 'Greater Than';\n lessThan = 'Less Than';\n doesNotEqual = 'Does Not Equal';\n beginsWith = 'Begins With';\n true = 'True';\n false = 'False';\n before = 'Before';\n after = 'After';\n within = 'Within';\n isNull = 'Is Empty';\n isEmpty = 'Is Empty?';\n between = 'Is Between';\n refreshPagination = 'Refresh Pagination';\n location = 'Location';\n showLess = 'Show Less';\n miles = 'Miles';\n km = 'Km';\n minimumPlaceholder = 'Minimum';\n maximumPlaceholder = 'Maximum';\n minGreaterThanMax = 'The minimum is greater than the maximum value';\n\n constructor(\n @Optional()\n @Inject(LOCALE_ID)\n public userLocale = 'en-US',\n ) {}\n\n maxlengthMetWithField(field: string, maxlength: number): string {\n return `Sorry, you have reached the maximum character count of ${maxlength} for ${field}.`;\n }\n\n maxlengthMet(maxlength: number): string {\n return `Sorry, you have reached the maximum character count of ${maxlength} for this field.`;\n }\n\n invalidMaxlengthWithField(field: string, maxlength: number): string {\n return `Sorry, you have exceeded the maximum character count of ${maxlength} for ${field}.`;\n }\n\n invalidMaxlength(maxlength: number): string {\n return `Sorry, you have exceeded the maximum character count of ${maxlength} for this field.`;\n }\n\n getToManyPlusMore(toMany: { quantity: number }): string {\n return `+${toMany.quantity} more`;\n }\n\n selectedRecords(selected: number) {\n return `${selected} records are selected.`;\n }\n\n showingXofXResults(shown: number, total: number) {\n return `Showing ${shown} of ${total} Results.`;\n }\n\n ofXAmount(amount: number) {\n return `of ${amount}`;\n }\n\n totalRecords(total: number, select = false) {\n return select ? `Select all ${total} records.` : `De-select remaining ${total} records.`;\n }\n\n dateFormatString(): string {\n return this.dateFormat;\n }\n\n localizedDatePlaceholder(): string {\n return this.localDatePlaceholder;\n }\n\n tabbedGroupClearSuggestion(tabLabelPlural: string): string {\n return `Clear your search to see all ${tabLabelPlural}.`;\n }\n\n formatDateWithFormat(value: any, format: Intl.DateTimeFormatOptions) {\n const date = value instanceof Date ? value : new Date(value);\n if (date.getTime() !== date.getTime()) {\n return value;\n }\n return new Intl.DateTimeFormat(this.userLocale, format).format(date);\n }\n\n formatToTimeOnly(param) {}\n\n formatToDateOnly(param) {}\n\n formatTimeWithFormat(value: any, format: Intl.DateTimeFormatOptions): string {\n const date = value instanceof Date ? value : new Date(value);\n if (date.getTime() !== date.getTime()) {\n return value;\n }\n const timeParts: { [type: string]: string } = Intl.DateTimeFormat(this.userLocale, format)\n .formatToParts(date)\n .reduce((obj, part) => {\n obj[part.type] = part.value;\n return obj;\n }, {});\n const dayPeriod = timeParts.dayPeriod ? timeParts.dayPeriod : '';\n const res = `${timeParts.hour}:${timeParts.minute} ${dayPeriod}`;\n return res;\n }\n\n getWeekdays(weekStartsOn: Day = 0): string[] {\n function getDay(dayOfWeek) {\n const dt = new Date();\n return dt.setDate(dt.getDate() - dt.getDay() + dayOfWeek);\n }\n\n let weekdays = [getDay(0), getDay(1), getDay(2), getDay(3), getDay(4), getDay(5), getDay(6)].reduce((dayList, dt) => {\n dayList.push(new Intl.DateTimeFormat(this.userLocale, { weekday: 'long' }).format(dt));\n return dayList;\n }, []);\n\n if (weekStartsOn > 0 && weekStartsOn <= 6) {\n const newStart = weekdays.splice(weekStartsOn);\n weekdays = [...newStart, ...weekdays];\n }\n return weekdays;\n }\n\n getMonths(): string[] {\n function getMonth(month) {\n const dt = new Date();\n return dt.setMonth(month, 1);\n }\n\n return [\n getMonth(0),\n getMonth(1),\n getMonth(2),\n getMonth(3),\n getMonth(4),\n getMonth(5),\n getMonth(6),\n getMonth(7),\n getMonth(8),\n getMonth(9),\n getMonth(10),\n getMonth(11),\n ].reduce((months, dt) => {\n months.push(new Intl.DateTimeFormat(this.userLocale, { month: 'long' }).format(dt));\n return months;\n }, []);\n }\n\n getProperty(value: string) {\n return this[value];\n }\n\n getRangeText(page: number, pageSize: number, length: number, short: boolean): string {\n if (length === 0 || pageSize === 0) {\n return `Displaying 0 of ${length}`;\n }\n\n length = Math.max(length, 0);\n\n const startIndex = page * pageSize;\n\n // If the start index exceeds the list length, do not try and fix the end index to the end.\n const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;\n\n return short ? `${startIndex + 1} - ${endIndex}/${length}` : `Displaying ${startIndex + 1} - ${endIndex} of ${length}`;\n }\n\n formatCurrency(value: number): string {\n const options: Intl.NumberFormatOptions = { style: 'currency', currency: 'USD' };\n return new Intl.NumberFormat(this.userLocale, options).format(value);\n }\n\n /**\n * Extends the Intl.numberFormat capability with two extra features:\n * - Does NOT round values, but instead truncates to maximumFractionDigits\n * - By default uses accounting format for negative numbers: (3.14) instead of -3.14.\n *\n * @param value The number value to convert to string\n * @param overrideOptions Allows for overriding options used and passed to Intl.NumberFormat()\n */\n formatBigDecimal(value: number, overrideOptions?: BigDecimalFormatOptions): string {\n const defaultOptions: BigDecimalFormatOptions = {\n style: 'decimal',\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n useAccountingFormat: true,\n };\n const options: BigDecimalFormatOptions = Object.assign(defaultOptions, overrideOptions);\n const truncatedValue = this.truncateToPrecision(value, options.maximumFractionDigits);\n let _value = new Intl.NumberFormat(this.userLocale, options).format(truncatedValue);\n if (value < 0) {\n _value = options.useAccountingFormat ? `(${_value.slice(1)})` : `-${_value.slice(1)}`;\n }\n return _value;\n }\n\n /**\n * Performs a string-based truncating of a number with no rounding\n */\n truncateToPrecision(value: number, precision: number) {\n let valueAsString = value ? value.toString() : '0';\n const decimalIndex = valueAsString.indexOf('.');\n if (decimalIndex > -1 && decimalIndex + precision + 1 < valueAsString.length) {\n valueAsString = valueAsString.substring(0, valueAsString.indexOf('.') + precision + 1);\n }\n return Number(valueAsString);\n }\n\n formatNumber(value, options?: Intl.NumberFormatOptions) {\n return new Intl.NumberFormat(this.userLocale, options).format(value);\n }\n\n formatDateShort(value: string | number | Date) {\n const options: Intl.DateTimeFormatOptions = {\n // DD/MM/YYYY, HH:MM A - 02/14/2017, 1:17 PM\n month: '2-digit',\n day: '2-digit',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n };\n const _value = value === null || value === undefined || value === '' ? new Date() : new Date(value);\n return new Intl.DateTimeFormat(this.userLocale, options).format(_value);\n }\n\n formatTime(value: string | number | Date) {\n const options: Intl.DateTimeFormatOptions = {\n // HH:MM A - 1:17 PM\n hour: 'numeric',\n minute: '2-digit',\n };\n const _value = value === null || value === undefined || value === '' ? new Date() : new Date(value);\n return new Intl.DateTimeFormat(this.userLocale, options).format(_value);\n }\n\n formatDate(value: string | number | Date) {\n const options: Intl.DateTimeFormatOptions = {\n // DD/MM/YYYY - 02/14/2017\n month: '2-digit',\n day: '2-digit',\n year: 'numeric',\n };\n const _value = value === null || value === undefined || value === '' ? new Date() : new Date(value);\n return new Intl.DateTimeFormat(this.userLocale, options).format(_value);\n }\n}\n\nexport const NOVO_ELEMENTS_LABELS_PROVIDERS = [{ provide: NovoLabelService, useClass: NovoLabelService }];\n","// NG2\nimport { Injectable } from '@angular/core';\nimport { NovoLabelService } from '../novo-label-service';\n// APP\nimport { format, parse } from 'date-fns';\nimport { MaskedOptions, MaskedEnum, MaskedRange } from 'imask';\nimport { DateUtil, Helpers, convertTokens } from 'novo-elements/utils';\n\n@Injectable()\nexport class DateFormatService {\n\n public readonly dateFormatAsImaskPattern: string;\n\n constructor(private labels: NovoLabelService) {\n this.dateFormatAsImaskPattern = this.dateFormatToImaskPattern(this.labels.dateFormatString());\n }\n\n getTimeMask(militaryTime: boolean): MaskedOptions {\n const amFormat = this.labels.timeFormatAM.toUpperCase();\n const pmFormat = this.labels.timeFormatPM.toUpperCase();\n const mask = {\n mask: Date,\n pattern: militaryTime ? 'HH:mm' : 'hh:mm aa',\n overwrite: true,\n autofix: true,\n lazy: false,\n min: new Date(1970, 0, 1),\n max: new Date(2100, 0, 1),\n prepare(str) {\n return str.toUpperCase();\n },\n format(date) {\n return DateUtil.format(date, militaryTime ? 'HH:mm' : 'hh:mm A');\n },\n parse: (str) => {\n const time = militaryTime ? str : this.convertTime12to24(str);\n return DateUtil.parse(`${DateUtil.format(Date.now(), 'YYYY-MM-DD')}T${time}`);\n },\n blocks: {\n HH: {\n mask: MaskedRange,\n placeholderChar: 'H',\n maxLength: 2,\n from: 0,\n to: 23,\n },\n hh: {\n mask: MaskedRange,\n placeholderChar: 'h',\n maxLength: 2,\n from: 1,\n to: 12,\n },\n mm: {\n mask: MaskedRange,\n placeholderChar: 'm',\n maxLength: 2,\n from: 0,\n to: 59,\n },\n aa: {\n mask: MaskedEnum,\n placeholderChar: 'x',\n enum: ['AM', 'PM', 'am', 'pm', amFormat, pmFormat],\n },\n },\n };\n return mask;\n }\n\n getDateMask(): MaskedOptions {\n return {\n mask: /^((\\d)(\\d|\\/|\\.|\\-){0,7})?(\\d){0,2}$/,\n };\n }\n\n getDateTimeMask(militaryTime: boolean = false): Array<any> {\n return [this.getDateMask(), /\\,?/, /\\s/, this.getTimeMask(militaryTime)];\n }\n\n getTimePlaceHolder(militaryTime: boolean): string {\n if (militaryTime) {\n return this.labels.timeFormatPlaceholder24Hour;\n }\n return this.labels.timeFormatPlaceholderAM;\n }\n\n parseCustomDateString(dateString: string, customFormat?: string): [Date, string, boolean] {\n let isInvalidDate = true;\n let date: Date = null;\n if (!customFormat) {\n customFormat = this.labels.dateFormatString();\n }\n customFormat = convertTokens(customFormat);\n const [cleanDateString, cleanFormat] = this.removeNonstandardFormatCharacters(dateString, customFormat);\n try {\n date = parse(cleanDateString, cleanFormat, new Date(), {\n useAdditionalWeekYearTokens: false,\n });\n if (isNaN(date.getTime())) {\n date = null;\n } else if (cleanDateString !== dateString) {\n // Verify that this parse matches the original dateString through this format. If not, then something may have mismatched -\n // in which case we consider the date to be invalid.\n // For instance, if we parsed \"Fri Oct 18, 2023\" as \" Oct 18 2023\" (removing the duplicative day-of-week) then it\n // would re-format as \"Wed Oct 18 2023\" and is an invalid date.\n const reformattedDate = format(date, customFormat);\n if (reformattedDate !== dateString) {\n date = null;\n } else {\n isInvalidDate = false;\n }\n } else {\n isInvalidDate = false;\n }\n } catch (err) {\n // ignore error - keep isInvalidDate true and date null\n }\n return [date, dateString, isInvalidDate];\n }\n\n private dateFormatToImaskPattern(formatString: string): string {\n const partsReg = /(\\w)\\1+|([\\.\\\\/-])/g;\n let output: string = '';\n let match: RegExpExecArray;\n while ((match = partsReg.exec(formatString)) != null) {\n if (match[1]) {\n const matchLow = match[1].toLowerCase();\n if (matchLow === 'y') {\n output += 'Y';\n } else {\n output += matchLow;\n }\n } else {\n output += `{${match[2]}}\\``;\n }\n }\n return output;\n }\n\n /**\n * Certain date format characters are considered nonstandard. We can still use them, but remove them for date parsing to avoid errors\n * @param dateString\n * @param formatString\n * @returns date string and format in array, both having had their\n */\n private removeNonstandardFormatCharacters(dateString: string, formatString: string): [string, string] {\n const bannedChars = /[iIRoPp]+/;\n // remove quotes\n formatString = formatString.replace(/['\"]/g, '');\n let match: RegExpExecArray = null;\n while ((match = bannedChars.exec(formatString)) != null) {\n formatString = formatString.substring(0, match.index) + formatString.substring(match.index + match[0].length);\n dateString = dateString.substring(0, match.index) + dateString.substring(match.index + match[0].length);\n }\n return [dateString, formatString];\n }\n\n parseDateString(dateString: string): [Date, string, boolean] {\n let dateFormat: string = this.labels.dateFormatString();\n const dateFormatRegex = /(\\w+)[\\/|\\.|\\-](\\w+)[\\/|\\.|\\-](\\w+)/gi;\n const dateValueRegex = /(\\d+)[\\/|\\.|\\-](\\d+)[\\/|\\.|\\-](\\d+)/gi;\n let year: number;\n let month: number;\n let day: number;\n let date: Date = null;\n let isInvalidDate = true;\n if (Helpers.isEmpty(dateFormat)) {\n // Default to MM/dd/yyyy\n dateFormat = 'mm/dd/yyyy';\n } else {\n dateFormat = dateFormat.toLowerCase();\n }\n const dateFormatTokens: Array<string> = dateFormatRegex.exec(dateFormat);\n const dateValueTokens: Array<string> = dateValueRegex.exec(dateString);\n if (dateFormatTokens && dateFormatTokens.length === 4 && dateValueTokens && dateValueTokens.length === 4) {\n for (let i = 1; i < 4; i++) {\n if (dateFormatTokens[i].includes('m')) {\n month = parseInt(dateValueTokens[i], 10) - 1;\n } else if (dateFormatTokens[i].includes('d')) {\n day = parseInt(dateValueTokens[i], 10);\n } else {\n year = parseInt(dateValueTokens[i], 10);\n }\n }\n if (month >= 0 && month <= 11 && year > 1900 && day > 0 && day <= 31) {\n date = new Date(year, month, day);\n isInvalidDate = false;\n }\n } else if (dateFormatTokens && dateFormatTokens.length === 4 && dateString.length >= 1) {\n const twoTokens = /\\d{1,4}(\\/|\\.|\\-)(\\d{1,2})/.exec(dateString);\n const oneToken = /^(\\d{1,4})$/.exec(dateString);\n const delimiter = /\\w+(\\/|\\.|\\-)\\w+[\\/|\\.|\\-]\\w+/gi.exec(dateFormat);\n const dateStringWithDelimiter = dateString[dateString.length - 1].match(/\\/|\\.|\\-/);\n if ((twoTokens && twoTokens.length === 3 && this.isValidDatePart(twoTokens[2], dateFormatTokens[2]) && !dateStringWithDelimiter) ||\n (oneToken && oneToken.length === 2 && this.isValidDatePart(oneToken[1], dateFormatTokens[1]) && !dateStringWithDelimiter)) {\n dateString = `${dateString}${delimiter[1]}`;\n }\n }\n return [date, dateString, isInvalidDate];\n }\n\n parseTimeString(timeString: string, militaryTime: boolean): [Date, string] {\n const value: Date = new Date();\n let timeStringParts: Array<string>;\n let amFormat = this.labels.timeFormatAM;\n let pmFormat = this.labels.timeFormatPM;\n if (!(timeString?.includes(':'))) {\n return [value, timeString];\n }\n if (!militaryTime && amFormat && pmFormat) {\n let splits: Array<string> = [];\n let pm: boolean = false;\n amFormat = this.labels.timeFormatAM.toLowerCase();\n pmFormat = this.labels.timeFormatPM.toLowerCase();\n timeString = timeString.toLowerCase();\n if (timeString.includes(amFormat)) {\n splits = timeString.split(amFormat);\n } else if (timeString.includes(pmFormat)) {\n splits = timeString.split(pmFormat);\n pm = true;\n }\n if (splits?.length) {\n for (const item of splits) {\n if (item?.trim().includes(':')) {\n timeStringParts = item.trim().split(':');\n }\n }\n }\n if (timeStringParts?.length && timeStringParts.length === 2) {\n let hours: number = parseInt(timeStringParts[0], 10);\n if (hours === 12 && pm) {\n hours = 12;\n } else if (pm) {\n hours = hours + 12;\n } else if (hours === 12) {\n hours = 0;\n }\n value.setHours(hours);\n value.setMinutes(parseInt(timeStringParts[1], 10));\n value.setSeconds(0);\n }\n } else {\n timeStringParts = /(\\d{1,2}):(\\d{2})/.exec(timeString);\n if (timeStringParts?.length && timeStringParts.length === 3) {\n value.setHours(parseInt(timeStringParts[1], 10));\n value.setMinutes(parseInt(timeStringParts[2], 10));\n value.setSeconds(0);\n }\n }\n return [value, timeString];\n }\n\n parseString(dateTimeString: string, militaryTime: boolean, type: string): [Date, string, boolean?] {\n if (!(dateTimeString?.length)) {\n return null;\n }\n switch (type) {\n case 'datetime':\n const str = dateTimeString.replace(/-/g, '/');\n const parts = str.split(' ');\n const [dt, dts] = this.parseDateString(parts[0]);\n if (parts.length > 1) {\n const [tm, tms] = this.parseTimeString(parts[1], militaryTime);\n return [new Date(dt.setHours(tm.getHours(), tm.getMinutes())), `${dts} ${tms}`];\n }\n return [dt, dts];\n case 'date':\n return this.parseDateString(dateTimeString);\n case 'time':\n return this.parseTimeString(dateTimeString, militaryTime);\n default:\n return;\n }\n }\n\n convertTime12to24(time12h: string) {\n const pmFormat = this.labels.timeFormatPM.toUpperCase();\n\n const [time, modifier] = time12h.split(' ');\n // eslint-disable-next-line prefer-const\n let [hours, minutes] = time.split(':');\n if (hours === '12') {\n hours = '00';\n }\n if (['PM', pmFormat].includes(modifier)) {\n hours = `${parseInt(hours, 10) + 12}`.padStart(2, '0');\n }\n return `${hours}:${minutes}`;\n }\n\n isValidDatePart(value: string, formatString: string): boolean {\n const datePart = parseInt(value, 10);\n return ((formatString.includes('m') && (datePart >= 2 || value.length === 2)) ||\n (formatString.includes('d') && (datePart >= 4 || value.length === 2)) ||\n (formatString.includes('y') && datePart >= 1000));\n }\n}\n","import { Injectable } from '@angular/core';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface Global {}\n\nexport abstract class GlobalRef {\n abstract get nativeGlobal(): Global;\n abstract get nativeWindow(): Window;\n}\n\n@Injectable()\nexport class BrowserGlobalRef extends GlobalRef {\n get nativeGlobal(): Global {\n return window as Global;\n }\n get nativeWindow(): Window {\n return window;\n }\n}\nexport class NodeGlobalRef extends GlobalRef {\n get nativeGlobal(): Global {\n throw new Error('global doesn\\'t compile for some reason');\n }\n get nativeWindow(): Window {\n throw new Error('Node does not have a window object');\n }\n}\n","// NG2\nimport { HttpClient } from '@angular/common/http';\nimport { Injectable } from '@angular/core';\n// App\n\n@Injectable()\nexport class OptionsService {\n constructor() {}\n\n getOptionsConfig(http: HttpClient, field: any, config: { token?: string; restUrl?: string; military?: boolean }): any {\n return {\n field: 'value',\n format: '$label',\n options: (query) => {\n return new Promise((resolve, reject) => {\n if (query && query.length) {\n const exp = new RegExp('^(?:[a-z]+:)?//', 'i');\n let endpoint;\n if (exp.test(field.optionsUrl)) {\n const url = new URL(field.optionsUrl);\n url.searchParams.set('filter', query || '');\n endpoint = url.toString();\n } else {\n // Construct relative url (host will not be used but is required for construction)\n const url = new URL(`http://placeholder.com/${field.optionsUrl}`);\n url.searchParams.set('filter', query || '');\n endpoint = `${url.pathname}${url.search}`;\n }\n http.get(endpoint).subscribe(resolve, reject);\n } else {\n resolve([]);\n }\n });\n },\n };\n }\n}\n","// NG2\nimport { EventEmitter, Injectable } from '@angular/core';\nimport { Subscription } from 'rxjs';\n\n@Injectable({ providedIn: 'root' })\nexport class Security {\n credentials: string[] = [];\n change: EventEmitter<any> = new EventEmitter();\n\n grant(data: any[] | Object): void {\n const parsed = [];\n if (data instanceof Array) {\n for (const permission of data) {\n parsed.push(permission.replace(/\\s/gi, ''));\n }\n } else if (typeof data === 'object') {\n for (const key in data) {\n if (data[key] instanceof Array) {\n for (const permission of data[key]) {\n parsed.push(`${key}.${permission}`);\n }\n }\n }\n }\n this.credentials = [].concat(this.credentials, parsed);\n this.change.emit(this.credentials);\n }\n\n has(value: any): boolean {\n return this.credentials.indexOf(value) > -1;\n }\n\n revoke(value: any): void {\n const i: number = this.credentials.indexOf(value);\n this.credentials.splice(i, 1);\n this.change.emit(this.credentials);\n }\n\n clear(): void {\n this.credentials = [];\n this.change.emit(this.credentials);\n }\n\n subscribe(fn: any): Subscription {\n return this.change.subscribe(fn);\n }\n\n checkRoutes(\n routes: { entities?: any[]; permissions?: any[] | Function; path?: string; label?: string; canDisable?: Boolean }[],\n options: { entityType?: string },\n ): any {\n const filtered = [];\n for (const route of routes) {\n if (route.entities && ~route.entities.indexOf(options.entityType)) {\n if (route.permissions instanceof Function) {\n if (route.permissions(options, this)) {\n filtered.push(route);\n }\n } else if (route.permissions && route.permissions.length) {\n if (route.permissions.every((perm) => this.has(perm))) {\n filtered.push(route);\n }\n } else {\n filtered.push(route);\n }\n }\n }\n\n return filtered;\n }\n}\n","import { Injectable } from '@angular/core';\n\n@Injectable()\nexport class LocalStorageService {\n setItem(key: any, value: any): any {\n localStorage.setItem(key, value);\n }\n\n getItem(key: any): any {\n return localStorage.getItem(key);\n }\n\n removeItem(key: any): any {\n localStorage.removeItem(key);\n }\n}\n","// NG2\nimport { Injectable } from '@angular/core';\n\n@Injectable()\nexport class NovoTemplateService {\n templates: any = {\n default: {},\n custom: {},\n };\n constructor() {}\n\n getAll(): any {\n const templates: any = {};\n const customTemplateTypes: string[] = Object.keys(this.templates.custom);\n const defaultTemplateTypes: string[] = Object.keys(this.templates.default);\n defaultTemplateTypes.forEach((type: string) => {\n templates[type] = this.templates.default[type];\n });\n customTemplateTypes.forEach((type: string) => {\n templates[type] = this.templates.custom[type];\n });\n return templates;\n }\n\n addDefault(key: string, template: any): void {\n this.templates.default[key] = template;\n }\n\n addCustom(key: string, template: any): void {\n this.templates.custom[key] = template;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1.NovoLabelService"],"mappings":"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