UNPKG

949 kBSource Map (JSON)View Raw
1{"version":3,"sources":["../../node_modules/tslib/tslib.es6.js","ng://angular-slickgrid/app/modules/angular-slickgrid/models/caseType.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/delimiterType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/emitterType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/extensionName.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/fieldType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/fileType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/filterMultiplePassType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/gridStateType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/keyCode.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/operatorType.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/sortDirection.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/models/sortDirectionNumber.enum.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/angularUtil.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/backend-utilities.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/utilities.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/compareDateUtility.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/dateEuroShortSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/dateEuroSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/dateIsoSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/dateSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/dateUsShortSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/dateUsSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/numericSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/objectStringSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/stringSorter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/sorters/sorterUtilities.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/collection.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/export.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/constants.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/shared.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/extensionUtility.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/autoTooltipExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/cellExternalCopyManagerExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/checkboxSelectorExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/draggableGroupingExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/booleanFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/filterUtilities.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateEuroFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateEuroShortFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateIsoFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateUsFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateUsShortFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/dateUtcFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/collectionSearchFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/numberFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/stringFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/executeMappedCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/objectFilterCondition.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filter-conditions/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/autoCompleteFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/compoundDateFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/filter.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/grid.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/compoundInputFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/compoundInputNumberFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/compoundInputPasswordFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/compoundSliderFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/inputFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/inputMaskFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/inputNumberFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/inputPasswordFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/selectFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/multipleSelectFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/nativeSelectFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/singleSelectFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/sliderFilter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/global-grid-options.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/slickgrid-config.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/filters/filterFactory.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/sort.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/groupItemMetaProviderExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/headerButtonExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/headerMenuExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/rowDetailViewExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/rowMoveManagerExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/extensions/rowSelectionExtension.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/extension.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/graphqlQueryBuilder.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/graphql.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/odataQueryBuilder.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/grid-odata.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/gridEvent.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/gridState.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/groupingAndColspan.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/services/resizer.service.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/aggregators/avgAggregator.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/aggregators/minAggregator.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/aggregators/maxAggregator.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/aggregators/sumAggregator.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/aggregators/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/autoCompleteEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/checkboxEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/dateEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/floatEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/integerEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/longTextEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/selectEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/multipleSelectEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/singleSelectEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/sliderEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/textEditor.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/editors/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/formatterUtilities.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/arrayObjectToCsvFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/arrayToCsvFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/boldFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/checkboxFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/checkmarkFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/collectionFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/collectionEditorFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/complexObjectFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/decimalFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/deleteIconFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/dollarColoredBoldFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/dollarColoredFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/dollarFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/editIconFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/hyperlinkFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/iconFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/infoIconFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/italicFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/lowercaseFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/maskFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/multipleFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/percentFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/percentCompleteBarFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/percentCompleteFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/percentSymbolFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/progressBarFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/translateFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/translateBooleanFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/uppercaseFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/yesNoFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/formatters/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/avgTotalsPercentageFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/avgTotalsDollarFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/avgTotalsFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/minTotalsFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/maxTotalsFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsColoredFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsDollarColoredBoldFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsDollarColoredFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsDollarBoldFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsDollarFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/sumTotalsBoldFormatter.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/grouping-formatters/index.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/components/slick-pagination.component.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/components/angular-slickgrid.component.ts","ng://angular-slickgrid/app/modules/angular-slickgrid/modules/angular-slickgrid.module.ts"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__extends","__","this","constructor","prototype","create","CaseType","DelimiterType","EmitterType","ExtensionName","FieldType","FileType","FilterMultiplePassType","GridStateType","KeyCode","OperatorType","SortDirection","SortDirectionNumber","__assign","assign","t","s","i","n","arguments","length","call","apply","__decorate","decorators","target","key","desc","c","r","getOwnPropertyDescriptor","Reflect","decorate","defineProperty","__metadata","metadataKey","metadataValue","metadata","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","__generator","body","f","y","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","v","op","TypeError","pop","push","__values","o","m","__read","ar","error","__spread","concat","AngularUtilService","compFactoryResolver","appRef","injector","createAngularComponent","component","domElem","componentRef","resolveComponentFactory","attachView","hostView","viewRef","isArray","rootNodes","domElement","createAngularComponentAppendToDom","targetElement","clearTargetContent","componentOutput","appendChild","innerHTML","document","Injectable","ComponentFactoryResolver","ApplicationRef","Injector","executeBackendProcessesCallback","startTime","processResult","backendApi","gridOptions","endTime","Date","internalPostProcess","postProcess","statistics","executionTime","valueOf","itemCount","pagination","totalItems","totalItemCount","onBackendError","onError","moment","moment_","addToArrayWhenNotExists","inputArray","inputItem","findIndex","item","id","addWhiteSpaces","nbSpaces","htmlEncode","inputValue","entityMap","&","<",">","\"","'","replace","htmlEntityDecode","input","match","dec","String","fromCharCode","charArraysEqual","a","orderMatters","sort","castToPromise","fromServiceName","promise","Observable","pipe","first","toPromise","Error","findOrDefault","array","logic","defaultVal","find","decimalFormatted","minDecimal","maxDecimal","isNaN","minDec","undefined","maxDec","amount","Math","round","pow","indexOf","formatNumber","displayNegativeNumberWithParentheses","symbolPrefix","symbolSuffix","calculatedValue","parseFloat","absValue","abs","getDescendantProperty","obj","path","split","reduce","acc","part","getScrollBarWidth","$outer","$","css","visibility","width","overflow","appendTo","widthWithScroll","outerWidth","remove","ceil","mapMomentDateFormatWithFieldType","fieldType","map","dateTime","dateTimeIso","dateTimeShortIso","dateTimeIsoAmPm","dateTimeIsoAM_PM","dateEuro","dateEuroShort","dateTimeEuro","dateTimeShortEuro","dateTimeEuroAmPm","dateTimeEuroAM_PM","dateTimeEuroShort","dateTimeEuroShortAmPm","dateUs","dateUsShort","dateTimeUs","dateTimeShortUs","dateTimeUsAmPm","dateTimeUsAM_PM","dateTimeUsShort","dateTimeUsShortAmPm","dateUtc","date","dateIso","mapFlatpickrDateFormatWithFieldType","mapOperatorType","operator","lessThan","lessThanOrEqual","greaterThan","greaterThanOrEqual","notEqual","startsWith","endsWith","equal","in","notIn","notContains","contains","mapOperatorByFieldType","string","unknown","float","number","dateTimeEuroShortAM_PM","dateTimeUsShortAM_PM","parseBoolean","test","parseUtcDate","inputDateString","useUtc","dateString","decodeURIComponent","dateMoment","isValid","year","toString","utc","format","sanitizeHtmlToText","htmlString","temp","createElement","textContent","innerText","titleCase","inputStr","caseEveryWords","outputStr","charAt","toUpperCase","substr","toLowerCase","slice","toCamelCase","offset","uniqueArray","arr","filter","index","unsubscribeAllObservables","subscriptions","forEach","subscription","unsubscribe","compareDates","value1","value2","sortDirection","strict","diff","date1","date2","parseInt","FORMAT","dateEuroShortSorter","dateEuroSorter","dateIsoSorter","dateSorter","ISO_8601","dateUsShortSorter","dateUsSorter","numericSorter","x","objectStringSorter","sortColumn","dataKey","stringValue1","stringValue2","neutral","stringSorter","Sorters","numeric","objectString","sortByFieldType","sortResult","object","CollectionService","translate","filterCollection","collection","filterByOptions","filterResultBy","chain","filteredCollection","merge","filterByOptions_1","tslib_1.__values","filterByOptions_1_1","singleFilterCollection","filterBy","property","property_1","value_1","sortCollection","columnDef","sortByOptions","enableTranslateLabel","_this","sortedCollection","dataRow1","dataRow2","l","sortBy","sortDesc","asc","propertyName","instant","propertyName_1","sortDirection_1","fieldType_1","sortDirection_2","fieldType_2","TranslateService","ExportService","_lineCarriageReturn","_hasGroupedItems","onGridBeforeExportToFile","Subject","onGridAfterExportToFile","_gridOptions","datasetIdPropertyName","_grid","getOptions","init","grid","dataView","_dataView","exportToFile","options","_exportOptions","extend","exportOptions","dataOutput","getDataOutput","setTimeout","downloadOptions","filename","csvContent","useUtf8WithBom","startDownloadFile","columns","getColumns","delimiter","groupByColumnHeader","groupingColumnHeaderTitle","_exportQuoteWrapper","csv","outputDataString","grouping","getGrouping","_columnHeaders","getColumnHeaders","header","title","join","getAllGridRowData","lineCarriageReturn","outputDataStrings","lineCount","getLength","rowNumber","itemObj","getItem","datasetIdName","readRegularRowData","__groupTotals","readGroupedTitleRow","readGroupedTotalRow","columnHeaders","fieldName","headerKey","name","skippedField","excludeFromExport","field","row","idx","rowOutputStrings","exportQuoteWrapper","col","ln","fieldId","isEvaluatingFormatter","exportWithFormatter","exportCustomFormatter","itemData","formattedData","text","formatter","sanitizeDataExport","keepAsStringWrapper","exportCsvForceToKeepAsString","groupName","level","groupingAggregatorRowText","outputStrings","groupTotalsFormatter","navigator","appName","outputData","mimeType","TextEncoder","encode","blob","Blob","type","msSaveOrOpenBlob","link","csvUrl","URL","createObjectURL","href","setAttribute","style","click","removeChild","Constants","TEXT_CANCEL","TEXT_CLEAR_ALL_FILTERS","TEXT_CLEAR_ALL_SORTING","TEXT_COLUMNS","TEXT_COMMANDS","TEXT_EXPORT_IN_CSV_FORMAT","TEXT_EXPORT_IN_TEXT_FORMAT","TEXT_FORCE_FIT_COLUMNS","TEXT_HIDE_COLUMN","TEXT_REFRESH_DATASET","TEXT_REMOVE_FILTER","TEXT_REMOVE_SORT","TEXT_SAVE","TEXT_SYNCHRONOUS_RESIZE","TEXT_SORT_ASCENDING","TEXT_SORT_DESCENDING","TEXT_TOGGLE_FILTER_ROW","TEXT_TOGGLE_PRE_HEADER_ROW","VALIDATION_REQUIRED_FIELD","VALIDATION_EDITOR_VALID_NUMBER","VALIDATION_EDITOR_VALID_INTEGER","VALIDATION_EDITOR_INTEGER_BETWEEN","VALIDATION_EDITOR_INTEGER_MAX","VALIDATION_EDITOR_INTEGER_MIN","VALIDATION_EDITOR_NUMBER_BETWEEN","VALIDATION_EDITOR_NUMBER_MAX","VALIDATION_EDITOR_NUMBER_MIN","VALIDATION_EDITOR_DECIMAL_BETWEEN","SharedService","_allColumns","allColumns","_groupItemMetadataProvider","groupItemMetadataProvider","_visibleColumns","visibleColumns","ExtensionUtility","sharedService","arrayRemoveItemByIndex","el","loadExtensionDynamically","extensionName","autoTooltip","require","cellExternalCopyManager","checkboxSelector","columnPicker","draggableGrouping","gridMenu","groupItemMetaProvider","headerButton","headerMenu","rowSelection","rowDetailView","rowMoveManager","getPickerTitleOutputString","propName","pickerName","output","picker","enableTranslate","titleKey","sortItems","items","itemA","itemB","translateItems","inputKey","outputKey","items_1","items_1_1","AutoTooltipExtension","extensionUtility","dispose","_addon","destroy","register","Slick","AutoTooltips","autoTooltipOptions","registerPlugin","CellExternalCopyManagerExtension","_eventHandler","EventHandler","_addonOptions","_commandQueue","_undoRedoBuffer","unsubscribeAll","createUndoRedoBuffer","hookUndoShortcutKey","tslib_1.__assign","getDefaultOptions","excelCopyBufferOptions","setSelectionModel","CellSelectionModel","CellExternalCopyManager","onExtensionRegistered","subscribe","onCopyCells","args","onCopyCancelled","onPasteCells","commandCtr","queueAndExecuteCommand","editCommand","execute","undo","command","GlobalEditorLock","cancelCurrentEdit","redo","newRowIds","clipboardCommandHandler","dataItemColumnValueExtractor","editable","editor","formattedOutput","outputString","readOnlyMode","includeHeaderWhenCopying","newRowCreator","count","getData","addItem","addEventListener","keyCode","code","ctrlKey","metaKey","shiftKey","CheckboxSelectorExtension","columnDefinitions","CheckboxSelectColumn","selectionColumn","getColumnDefinition","excludeFromColumnPicker","excludeFromGridMenu","excludeFromQuery","excludeFromHeaderMenu","unshift","rowSelectionPlugin","getSelectionModel","RowSelectionModel","rowSelectionOptions","preselectedRows","selectRows","ColumnPickerExtension","columnTitle","forceFitTitle","syncResizeTitle","Controls","ColumnPicker","enableColumnPicker","onColumnsChanged","translateColumnPicker","emptyColumnPickerTitles","DraggableGroupingExtension","DraggableGrouping","onGroupChanged","booleanFilterCondition","searchTerm","searchTerms","cellValue","compareObjects","o1","o2","compareKey","testFilterCondition","includes","val","dateEuroFilterCondition","dateCell","dateSearch","dateEuroShortFilterCondition","dateFilterCondition","searchDateFormat","filterSearchType","dateIsoFilterCondition","dateUsFilterCondition","dateUsShortFilterCondition","dateUtcFilterCondition","collectionSearchFilterCondition","numberFilterCondition","stringFilterCondition","cellValueLastChar","executeMappedCondition","boolean","objectFilterCondition","FilterConditions","booleanFilter","collectionSearchFilter","dateEuroFilter","dateEuroShortFilter","dateFilter","dateIsoFilter","dateUtcFilter","dateUsFilter","dateUsShortFilter","numberFilter","stringFilter","testFilter","AutoCompleteFilter","collectionService","_clearFilterTriggered","_shouldTriggerQuery","isFilled","valueName","collectionOptions","customStructure","callback","columnFilter","collectionAsync","filterOptions","labelName","newCollection","renderDomElement","renderOptionsAsync","clear","shouldTriggerQuery","$filterElm","trigger","off","setValues","values","inputCollection","outputCollection","collectionFilterBy","filterCollectionBy","filterResultAfterEachPass","collectionSortBy","awaitedCollection","_a","renderDomElementFromCollectionAsync","createCollectionAsyncSubject","newCollectionAsync","collectionInObjectProperty","filterTemplate","buildTemplateHtmlString","createDomElement","on","enableWhiteSpaceTrim","enableFilterTrimWhiteSpace","enableTrimWhiteSpace","trim","clearFilterTriggered","removeClass","addClass","columnId","placeholder","defaultFilterPlaceholder","$headerElm","getHeaderRowColumn","empty","searchTermInput","autoCompleteOptions","select","event","ui","onSelect","autocomplete","minLength","source","attr","data","itemLabel","itemValue","timer","highlightTimerEnd","CompoundDateFilter","_operator","$filterInputElm","keyup","onTriggerEvent","$selectOperatorElm","change","flatInstance","setDate","buildDatePickerInput","inputFormat","outputFormat","outputType","currentLocale","currentLang","substring","pickerOptions","defaultDate","altInput","altFormat","dateFormat","wrap","closeOnSelect","locale","loadFlatpickrLocale","onChange","selectedDates","dateStr","instance","_currentValue","enableTime","CustomEvent","pickerMergedOptions","flatpickr","Flatpickr","buildSelectOperatorHtmlString","optionValues","getOptionValues","optionValueString","option","description","$filterContainerElm","$containerInputGroup","$operatorInputGroupAddon","append","params","flapickrLocale","localeDefault","default","selectedOperator","hide","close","show","open","CompoundInputFilter","_inputType","buildInputHtmlString","CompoundInputNumberFilter","_super","inputType","tslib_1.__extends","CompoundInputPasswordFilter","CompoundSliderFilter","_elementRangeInputId","_elementRangeOutputId","filterParams","hideSliderNumber","getElementById","clearedValue","sliderStartValue","$containerInputGroupElm","children","last","html","minValue","filterProperties","maxValue","defaultValue","valueStep","buildTemplateSliderTextHtmlString","$sliderTextInputAppendAddon","InputFilter","InputMaskFilter","mask","targetValue","unmaskedValue","unmaskValue","maskedValue","maskValue","preventDefault","inputMask","valueWithoutSymbols","maskWithoutSymbols","InputNumberFilter","InputPasswordFilter","DOMPurify","DOMPurify_","SelectFilter","isMultipleSelect","_isFilterFirstRender","autoAdjustDropHeight","autoAdjustDropPosition","autoAdjustDropWidthByTextSize","container","maxHeight","single","textTemplate","$elm","enableRenderHtml","onClose","selectedItems","multipleSelect","siblings","okButton","addTitle","countSelected","allSelected","selectAllText","selectAllDelimiter","defaultOptions","isFilterFirstRender","labelPrefixName","labelPrefix","labelSuffixName","labelSuffix","optionLabel","elementClassName","elementName","addBlankEntry","createBlankEntry","optionCollection","separatorBetweenLabels","separatorBetweenTextLabels","isRenderHtmlEnabled","sanitizedOptions","sanitizeHtmlOptions","every","selected","term","labelKey","labelText","prefixText","suffixText","optionText","sanitize","blankEntry","elementOptions","filterElmOptions","MultipleSelectFilter","NativeSelectFilter","textLabel","SingleSelectFilter","SliderFilter","Filters","autoComplete","compoundDate","compoundInput","compoundInputNumber","compoundInputPassword","compoundInputText","compoundSlider","inputNumber","inputPassword","inputText","singleSelect","slider","GlobalGridOptions","alwaysShowVerticalScroll","autoEdit","asyncEditorLoading","autoFitColumnsOnFirstLoad","autoResize","calculateAvailableSizeBy","bottomPadding","minHeight","minWidth","sidePadding","cellHighlightCssClass","cssClass","hideForceFitButton","hideSyncResizeButton","defaultFilter","enableAutoResize","enableAutoSizeColumns","enableCellNavigation","enableColumnReorder","enableExport","enableGridMenu","enableHeaderMenu","enableMouseHoverHighlightRow","enableSorting","enableTextSelectionOnCells","explicitInitialization","comma","forceFitColumns","hideClearAllFiltersCommand","hideClearAllSortingCommand","hideExportCsvCommand","hideExportTextDelimitedCommand","hideRefreshDatasetCommand","hideToggleFilterCommand","hideTogglePreHeaderCommand","iconCssClass","iconClearAllFiltersCommand","iconClearAllSortingCommand","iconExportCsvCommand","iconExportTextDelimitedCommand","iconRefreshDatasetCommand","iconToggleFilterCommand","iconTogglePreHeaderCommand","menuWidth","resizeOnShowHeaderRow","autoAlign","autoAlignOffset","iconClearFilterCommand","iconClearSortCommand","iconSortAscCommand","iconSortDescCommand","iconColumnHideCommand","hideColumnHideCommand","hideClearFilterCommand","hideClearSortCommand","hideSortCommands","headerRowHeight","multiColumnSort","numberedMultiColumnSort","tristateMultiColumnSort","sortColNumberInSeparateSpan","suppressActiveCellChangeOnEdit","pageSizes","pageSize","panelRows","keyPrefix","useRowClick","useSimpleViewportCalc","saveDetailViewOnScroll","process","viewComponent","rowHeight","topPanelHeight","FilterFactory","config","_options","createFilter","model","SlickgridConfig","isequal","isequal_","FilterService","filterFactory","_firstColumnIdRendered","_filtersMetadata","_columnFilters","onFilterChanged","onFilterCleared","_onSearchChange","Event","disposeColumnFilters","bindBackendOnFilter","onHeaderRowCellRendered","column","addFilterTemplateToHeaderRow","onBackendFilterChange","bind","bindLocalOnFilter","setFilterArgs","columnFilters","setFilter","customLocalFilter","refresh","emitFilterChanged","local","callbackSearchEvent","hasSearchTerms","termsCount","oldColumnFilters","colId","colFilter","eventData","isPropagationStopped","EventData","ENTER","notify","clearFilterByColumnId","emitter","backendServiceApi","remote","clearFilters","invalidate","callbackArgs","executeBackendCallback","_b","keys","_c","columnIndex","getColumnIndex","enableRowDetailView","metadataPrefix","queryFieldFilter","queryField","searchValues","fieldSearchValue","matches","lastValueChar","k","useFormatterOuputToFilter","rowIndex","getIdxById","service","processOnFilterChanged","query","isObservable","getColumnFilters","getFiltersMetadata","getCurrentLocalFilters","currentFilters","caller","backendService","getCurrentFilters","startTime_1","preProcess","debounceTypingDelay","filterTypingDebounce","clearTimeout","populateColumnFilterSearchTerms","presets","filters","filters_1","_columnDefinitions","columnPreset","presetFilter","filterable","newFilter_1","updateColumnFilters","filterArguments","filterExistIndex","SortService","_currentLocalSorters","_isBackendGrid","onSortChanged","onSortCleared","bindBackendOnSort","onSort","onBackendSortChanged","bindLocalOnSort","sortCols","sortCol","sortColumns","sortAsc","direction","ASC","DESC","onLocalSortChanged","emitSortChanged","clearSorting","triggerQueryEvent","setSortColumns","clearSorters","getCurrentLocalSorters","getCurrentColumnSorts","excludedColumnId","oldSortColumns","getSortColumns","cols","loadLocalGridPresets","sorters","presetSorting","gridColumn","processOnSortChanged","catch","forceReSort","reSort","sortComparer","render","columnSortObj","sortField","queryFieldSorter","sorter","customSortResult","sender","currentSorters","getCurrentSorters","GridMenuExtension","exportService","filterService","sortService","_areVisibleColumnDifferent","showGridMenu","_userOriginalGridMenu","getDefaultGridMenuOptions","customItems","addGridMenuCustomCommands","GridMenu","onBeforeMenuShow","onCommand","executeGridMenuInternalCustomCommands","onMenuClose","autosizeColumns","gridUid","getUID","refreshBackendDataset","buildQuery","translateGridMenu","emptyGridMenuTitles","gridMenuCustomItems","enableFiltering","disabled","positionOrder","showPreHeaderPanel","customTitle","tab","txt","showHeaderRow","setHeaderRowVisibility","showTopPanel","setTopPanelVisibility","setPreHeaderPanelVisibility","GroupItemMetaProviderExtension","HeaderButtonExtension","Plugins","HeaderButtons","HeaderMenuExtension","getDefaultHeaderMenuOptions","addHeaderMenuCustomCommands","HeaderMenu","executeHeaderMenuInternalCommands","headerMenuOptions","menu","columnHeaderMenuItems","sortable","divider","hideFilterCommands","hideColumn","setColumns","currentColumns","translateHeaderMenu","resetHeaderMenuTranslations","columnHeaderMenuItems_1","clearColumnFilter","clearColumnSort","allSortedCols","sortedColsWithoutCurrent","sortOutput","updatedSortColumns","isSortingAsc","newSortColumns","RowDetailViewExtension","angularUtilService","_views","_subscriptions","disposeAllViewComponents","compRef","disposeViewComponent","_userProcessFn","onProcessing","preTemplate","_preloadComponent","preloadComponent","postTemplate","_viewComponent","itemDetail","RowDetailView","selectActiveRow","onAsyncResponse","onAsyncEndUpdate","renderViewModel","onAfterRowDetailToggle","renderPreloadView","renderAllViewComponents","onBeforeRowDetailToggle","onRowBackToViewportRange","onRowOutOfViewportRange","onColumnsReordered","redrawAllViewComponents","expandedView","detachView","notifyTemplate","awaitedItemDetail","response","__collapsed","viewInfo","dataContext","foundViewIndex","view","splice","redrawViewComponent","createdView","containerElements","getElementsByClassName","viewObj","RowMoveManagerExtension","RowMoveManager","cancelEditOnDrag","onBeforeMoveRows","onMoveRows","RowSelectionExtension","ExtensionService","autoTooltipExtension","cellExternalCopyExtension","checkboxSelectorExtension","columnPickerExtension","draggableGroupingExtension","gridMenuExtension","groupItemMetaExtension","headerButtonExtension","headerMenuExtension","rowDetailViewExtension","rowMoveManagerExtension","rowSelectionExtension","_extensionList","class","getAllColumns","getVisibleColumns","getAllExtensions","getExtensionByName","getSlickgridAddonInstance","extension","addon","autoResizeColumns","bindDifferentExtensions","enableAutoTooltip","enableExcelCopyBuffer","enableCheckboxSelector","enableDraggableGrouping","enableGrouping","enableHeaderButton","enableRowMoveManager","enableRowSelection","registerPlugins","plugin","noname","createExtensionsBeforeGridCreation","getSetupColumnReorder","removeColumnByIndex","translateColumnHeaders","newColumnDefinitions","use","renderColumnHeaders","GraphqlQueryBuilder","queryFnName","aliasOrFilter","head","alias","prop","getGraphQLValue","searches","_i","searchKeys","parceFind","setAlias","ReferenceError","_levelA","currentValue","itemX","RangeError","propsAA","JSON","stringify","propS","objectToString","sourceA","DEFAULT_ITEMS_PER_PAGE","GraphqlService","_currentFilters","_currentSorters","defaultPaginationOptions","serviceOptions","datasetName","queryQb","QueryBuilder","datasetQb","dataQb","columnIds","columnDefinitions_1","columnDefinitions_1_1","fields","buildFilterQuery","isWithCursor","pageInfoQb","node","datasetFilters","enablePagination","paginationOptions","sortingOptions","orderBy","filteringOptions","addLocaleIntoQuery","i18n","extraQueryArguments","_d","queryArgument","trimDoubleQuotesOnEnumField","keepArgumentFieldDoubleQuotes","set","shift","updateOptions","getInitPaginationOptions","paginationFirst","getDatasetName","getCurrentPagination","_currentPagination","resetPaginationOptions","after","before","pageNumber","castFilterToColumnFilters","updateFilters","processOnPaginationChanged","updatePagination","newPage","updateSorters","isUpdatedByPreset","searchValue","searchByArray","columnFilter_1","this_1","presetSorters","graphqlSorters","tmpSorterArray","sortColumns_1","sortColumns_1_1","enumSearchWords","patternRegex","patternWordInQuotes","reg","RegExp","group1","group2","group3","removeDoubleQuotes","filtersArray","tmpFilter","OdataQueryBuilderService","_odataOptions","filterQueue","_defaultSortBy","queryTmpArray","top","skip","argument","_filterCount","filterStr","filterBySeparator","addToFilterQueueWhenNotExists","getFilterCount","removeColumnFilter","saveColumnFilter","search","caseType","pascalCase","GridOdataService","_odataService","mergedOptions","mapOdataOperator","terms","searchBy","bypassOdataQuery","bypassBackendQuery","encodeURIComponent","tmpSearchTerms","j","lnj","lnk","dateFormatted","odataSorters","columnFieldName","csvString","GridEventService","bindOnCellChange","onCellChange","cell","getDataItem","returnedArgs","bindOnClick","onClick","autoCommitEdit","setActiveCell","onCellClick","GridStateService","_columns","_currentColumns","onGridStateChanged","extensionService","subscribeToAllGridChanges","getCurrentGridState","gridState","getCurrentColumns","currentPagination","getAssociatedCurrentColumns","gridColumns","headerCssClass","getAssociatedGridColumns","currentColumn","resetColumns","newValues","resetRowSelection","setSelectedRows","bindExtensionAddonEventToGridStateChange","bindSlickGridEventToGridStateChange","eventName","slickEvent","slickGridEvent","GridServiceDeleteOptionDefaults","triggerEvent","GridServiceInsertOptionDefaults","highlightRow","resortGrid","selectRow","GridServiceUpdateOptionDefaults","GridService","gridStateService","onItemAdded","onItemDeleted","onItemUpdated","onItemUpserted","clearAllFiltersAndSorts","getColumnFromEventArguments","getDataItemByRowNumber","getItemRowMetadataToHighlight","previousItemMetadata","meta","cssClasses","_dirty","rowClass","fadeDelay","fadeOutDelay","highlightRowByMetadata","getItemMetadata","updateItem","renderGrid","getDataItemByRowIndex","getDataItemByRowIndexes","indexes","dataItems","getSelectedRows","getSelectedRowsDataItem","selectedRowIndexes","setSelectedRow","rowIndexes","resetGrid","originalColumns","addItemToDatagrid","shouldHighlightRow","shouldResortGrid","shouldTriggerEvent","shouldSelectRow","addItemsToDatagrid","addItems","insertItem","getRowById","scrollRowIntoView","rowNumbers","deleteDataGridItem","deleteItem","deleteDataGridItems","deleteItems","deleteDataGridItemById","itemId","deleteItemById","deleteDataGridItemByIds","itemIds","deleteItemByIds","updateDataGridItem","updateDataGridItems","updateItems","updateDataGridItemById","updateItemById","gridRowNumbers","updateRow","upsertItem","upsertItemById","upsertItems","GroupingAndColspanService","createPreHeaderPanel","createPreHeaderRowGroupingTitle","onColumnsResized","onRowCountChanged","$preHeaderPanel","getPreHeaderPanel","getHeadersWidth","parent","headerColumnWidthDiff","getHeaderColumnWidthDiff","lastColumnGroup","widthTotal","columnGroup","ResizerService","_resizePaused","onGridAfterResize","onGridBeforeResize","gridId","fixedDimensions","_fixedHeight","height","_fixedWidth","bindAutoResizeDataGrid","newSizes","gridDomElm","resizeGrid","window","_gridUid","calculateGridNewDimensions","autoResizeOptions","containerElm","containerId","gridContainerId","gridHeight","gridOffsetTop","innerHeight","coordOffsetTop","availableHeight","availableWidth","maxWidth","newHeight","newWidth","compensateHorizontalScroll","gridElm","scrollbarDimensions","getScrollbarDimensions","slickGridScrollbarWidth","calculatedScrollbarWidth","getLastResizeDimensions","_lastDimensions","pauseResizer","isResizePaused","delay","_timer","resizeGridCallback","lastDimensions","resizeGridWithDimensions","availableDimensions","gridContainerElm","autoHeight","exec","userAgent","resizeCanvas","heightWithPagination","AvgAggregator","_count","_field","_nonNullCount","_sum","accumulate","storeResult","groupTotals","avg","MinAggregator","_min","min","MaxAggregator","_max","max","SumAggregator","sum","Aggregators","Avg","Min","Max","Sum","AutoCompleteEditor","internalColumnEditor","columnEditor","validator","editorOptions","$input","_lastInputEvent","LEFT","RIGHT","stopImmediatePropagation","focus","getValue","setValue","loadValue","fieldNameFromComplexObject","_defaultTextValue","save","validation","validate","valid","hasAutoCommitEdit","getEditorLock","commitCurrentEdit","commitChanges","serializeValue","forceUserInput","applyValue","state","newValue","collectionItem","isValueChanged","lastEvent","alwaysSaveOnEnterKey","isRequired","required","elmValue","errorMsg","errorMessage","msg","CheckboxEditor","preClick","isChecked","DateEditor","getCurrentLocale","altInputClass","inputCssClasses","_$inputWithData","getColumnEditor","domValue","toDate","FloatEditor","getInputDecimalSteps","getDecimalPlaces","rtn","decimalPlaces","decimals","zeroString","decPlaces","toFixed","floatNumber","mapValidation","{{minValue}}","{{maxValue}}","{{minDecimal}}","{{maxDecimal}}","outputMsg","matched","IntegerEditor","intNumber","LongTextEditor","_translate","cancelText","saveText","$container","$wrapper","$textarea","cancel","handleKeyDown","position","which","ESCAPE","TAB","navigatePrev","navigateNext","cancelChanges","left","SelectEditor","_destroying","libOptions","onBlur","$editorElm","isIncludingPrefixSuffix","includePrefixSuffixToSelectedValues","itemFound","_collectionService","integer","loadMultipleValues","loadSingleValue","currentValues","currentStringValues_1","each","$e","editorTemplate","editorElmOptions","MultipleSelectEditor","SingleSelectEditor","SliderEditor","$sliderNumber","editorParams","TextEditor","Editors","checkbox","longText","getValueFromParamsOrGridOptions","optionName","formatterOptions","getAssociatedDateFormatter","defaultSeparator","defaultDateFormat","customSeparator","dateSeparator","isDateValid","outputDate","regex","arrayObjectToCsvFormatter","columnParams","propertyNames","parentObjectKeyName","dataContextProperty","outputStrings_1","strings","arrayToCsvFormatter","boldFormatter","checkboxFormatter","checkmarkFormatter","collectionFormatter","collectionEditorFormatter","complexObjectFormatter","complexFieldLabel","decimalFormatter","isNumber","minDecimalPlaces","maxDecimalPlaces","deleteIconFormatter","dollarColoredBoldFormatter","dollarColoredFormatter","dollarFormatter","editIconFormatter","hyperlinkFormatter","displayedText","hyperlinkText","outputLink","hyperlinkUrl","matchUrl","iconFormatter","icon","formatterIcon","infoIconFormatter","italicFormatter","lowercaseFormatter","maskFormatter","i_1","v_1","multipleFormatter","formatters","formatters_1","formatters_1_1","percentFormatter","percentCompleteBarFormatter","percentCompleteFormatter","colorStyle","formattedNumber","percentSymbolFormatter","progressBarFormatter","color","translateFormatter","translateBooleanFormatter","uppercaseFormatter","yesNoFormatter","Formatters","arrayObjectToCsv","arrayToCsv","bold","checkmark","complexObject","collectionEditor","deleteIcon","decimal","dollar","dollarColored","dollarColoredBold","editIcon","hyperlink","infoIcon","italic","lowercase","multiple","percent","percentComplete","percentCompleteBar","percentSymbol","progressBar","translateBoolean","uppercase","yesNo","avgTotalsPercentageFormatter","totals","prefix","groupFormatterPrefix","suffix","groupFormatterSuffix","avgTotalsDollarFormatter","avgTotalsFormatter","minTotalsFormatter","maxTotalsFormatter","sumTotalsColoredFormatter","sumTotalsDollarColoredBoldFormatter","sumTotalsDollarColoredFormatter","sumTotalsDollarBoldFormatter","sumTotalsDollarFormatter","sumTotalsFormatter","sumTotalsBoldFormatter","GroupTotalFormatters","avgTotals","avgTotalsDollar","avgTotalsPercentage","maxTotals","minTotals","sumTotals","sumTotalsBold","sumTotalsColored","sumTotalsDollar","sumTotalsDollarBold","sumTotalsDollarColored","sumTotalsDollarColoredBold","SlickPaginationComponent","gridService","_isFirstRender","onPaginationChanged","EventEmitter","dataFrom","dataTo","pageCount","paginationPageSizes","fromToParams","from","to","_gridPaginationOptions","gridPaginationOptions","refreshPagination","ngOnDestroy","ngAfterViewInit","_filterSubcription","onItemAddedOrRemoved","changeToFirstPage","onPageChanged","changeToLastPage","changeToNextPage","changeToPreviousPage","changeToCurrentPage","currentTarget","onChangeItemPerPage","itemsPerPage","isPageNumberReset","recalculateFromToIndexes","process_1","emit","isItemAdded","previousDataTo","itemCountWithDirection","tslib_1.__decorate","Output","Input","Component","selector","template","AngularSlickgridComponent","elm","gridEventService","groupingAndColspanService","resizer","forRootConfig","_hideHeaderRowAfterPageLoad","groupingDefinition","showPagination","isGridInitialized","onAngularGridCreated","onDataviewCreated","onGridCreated","onGridInitialized","onBeforeGridCreate","onBeforeGridDestroy","onAfterGridDestroyed","paramIndex","decorator","updateColumnDefinitionsList","getItems","dataset","_dataset","refreshGridData","ngOnInit","gridHeightString","gridWidthString","emptyDomElementContainer","initialization","mergeGridOptions","createBackendApiInternalPostProcessCallback","customDataView","Data","GroupItemMetadataProvider","DataView","swapInternalEditorToSlickGridFactoryEditor","Grid","bindDifferentHooks","beginUpdate","setItems","endUpdate","syncGridSelection","preserveHidden","preserveHiddenOnSelectionChange","executeAfterDataviewCreated","bindResizeHook","bindBackendCallbackFunctions","slickGrid","groupingService","resizerService","pluginService","commitEdit","activeNode_1","getActiveCellNode","isActive","backendApi_1","nodes","totalCount","onLangChange","checkboxColumn","dispatchCustomEvent","this_2","gridStateChange","onRowsChanged","rows","colspanCallback","isExecuteCommandOnInit","onInit","paginationChanged","isShowing","toggleHeaderRow","isBubbling","isCancelable","eventInit","bubbles","cancelable","detail","nativeElement","dispatchEvent","loadEditorCollectionAsync","resolvedCollection","updateEditorCollection","providers","tslib_1.__param","Inject","ElementRef","AngularSlickgridModule","forRoot","ngModule","AngularSlickgridModule_1","provide","useValue","NgModule","imports","CommonModule","TranslateModule","declarations","exports","entryComponents","encodedStr","parser","DOMParser","parseFromString","dom","buf","charCodeAt","Map","arr_1","arr_1_1","has"],"mappings":"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","sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\r\n t[p[i]] = s[p[i]];\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","export enum CaseType {\r\n /** For example: camelCase */\r\n camelCase,\r\n\r\n /** For example: PascalCase */\r\n pascalCase,\r\n\r\n /** For example: snake_case */\r\n snakeCase,\r\n\r\n /** For example: kebab-case */\r\n kebabCase,\r\n}\r\n","export enum DelimiterType {\r\n colon = ':',\r\n comma = ',',\r\n equalSign = '=',\r\n pipe = '|',\r\n semicolon = ';',\r\n space = ' ',\r\n tab = '\\t',\r\n\r\n doubleColon = '::',\r\n doublePipe = '||',\r\n doubleSemicolon = ';;',\r\n}\r\n\r\n","export enum EmitterType {\n local = 'local',\n remote = 'remote'\n}\n\n","/** List of available SlickGrid Extensions (Controls & Plugins) */\r\nexport enum ExtensionName {\r\n autoTooltip = 'autoTooltip',\r\n cellExternalCopyManager = 'cellExternalCopyManager',\r\n checkboxSelector = 'checkboxSelector',\r\n columnPicker = 'columnPicker',\r\n draggableGrouping = 'draggableGrouping',\r\n groupItemMetaProvider = 'groupItemMetaProvider',\r\n gridMenu = 'gridMenu',\r\n headerButton = 'headerButton',\r\n headerMenu = 'headerMenu',\r\n noname = 'noname',\r\n rowDetailView = 'rowDetailView',\r\n rowMoveManager = 'rowMoveManager',\r\n rowSelection = 'rowSelection',\r\n}\r\n","export enum FieldType {\r\n unknown,\r\n string,\r\n boolean,\r\n integer,\r\n float,\r\n\r\n /** number includes Integer and Float */\r\n number,\r\n\r\n /** new Date(), javascript Date object */\r\n date,\r\n\r\n /** Format: 'YYYY-MM-DD' => 2001-01-01 */\r\n dateIso,\r\n\r\n /** Format: 'YYYY-MM-DDTHH:mm:ss.SSSZ' => 2001-01-01T14:00:00.123Z */\r\n dateUtc,\r\n\r\n /** new Date(), javacript Date Object with Time */\r\n dateTime,\r\n\r\n /** Format: 'YYYY-MM-DD HH:mm:ss' => 2001-01-01 14:01:01 */\r\n dateTimeIso,\r\n\r\n /** Format: 'YYYY-MM-DD h:mm:ss a' => 2001-01-01 11:01:01 pm */\r\n dateTimeIsoAmPm,\r\n\r\n /** Format: 'YYYY-MM-DD h:mm:ss A' => 2001-01-01 11:01:01 PM */\r\n dateTimeIsoAM_PM,\r\n\r\n /** Format: 'YYYY-MM-DD HH:mm' => 2001-01-01 14:01 */\r\n dateTimeShortIso,\r\n\r\n /** Format (Euro): 'DD/MM/YYYY' => 02/28/2001 */\r\n dateEuro,\r\n\r\n /** Format (Euro): 'D/M/YY' => 2/28/12 */\r\n dateEuroShort,\r\n\r\n /** Format (Euro): 'DD/MM/YYYY HH:mm' => 02/28/2001 13:01 */\r\n dateTimeShortEuro,\r\n\r\n /** Format (Euro): 'DD/MM/YYYY HH:mm:ss' => 02/28/2001 13:01:01 */\r\n dateTimeEuro,\r\n\r\n /** Format (Euro): 'DD/MM/YYYY hh:mm:ss a' => 02/28/2001 11:01:01 pm */\r\n dateTimeEuroAmPm,\r\n\r\n /** Format (Euro): 'DD/MM/YYYY hh:mm:ss A' => 02/28/2001 11:01:01 PM */\r\n dateTimeEuroAM_PM,\r\n\r\n /** Format (Euro): 'D/M/YY H:m:s' => 2/28/14 14:1:2 */\r\n dateTimeEuroShort,\r\n\r\n /** Format (Euro): 'D/M/YY h:m:s a' => 2/28/14 1:2:10 pm */\r\n dateTimeEuroShortAmPm,\r\n\r\n /** Format (Euro): 'D/M/YY h:m:s A' => 2/28/14 14:1:1 PM */\r\n dateTimeEuroShortAM_PM,\r\n\r\n /** Format: 'MM/DD/YYYY' => 02/28/2001 */\r\n dateUs,\r\n\r\n /** Format: 'M/D/YY' => 2/28/12 */\r\n dateUsShort,\r\n\r\n /** Format: 'MM/DD/YYYY HH:mm' => 02/28/2001 13:01 */\r\n dateTimeShortUs,\r\n\r\n /** Format: 'MM/DD/YYYY HH:mm:ss' => 02/28/2001 13:01:01 */\r\n dateTimeUs,\r\n\r\n /** Format: 'MM/DD/YYYY hh:mm:ss a' => 02/28/2001 11:01:01 pm */\r\n dateTimeUsAmPm,\r\n\r\n /** Format: 'MM/DD/YYYY hh:mm:ss A' => 02/28/2001 11:01:01 PM */\r\n dateTimeUsAM_PM,\r\n\r\n /** Format: 'M/D/YY H:m:s' => 2/28/14 14:1:2 */\r\n dateTimeUsShort,\r\n\r\n /** Format: 'M/D/YY h:m:s a' => 2/28/14 1:2:10 pm */\r\n dateTimeUsShortAmPm,\r\n\r\n /** Format: 'M/D/YY h:m:s A' => 2/28/14 14:1:1 PM */\r\n dateTimeUsShortAM_PM,\r\n\r\n /** complex object with various properties */\r\n object,\r\n}\r\n","export enum FileType {\r\n csv = 'csv',\r\n doc = 'doc',\r\n docx = 'docx',\r\n pdf = 'pdf',\r\n txt = 'txt',\r\n xls = 'xls',\r\n xlsx = 'xlsx'\r\n}\r\n","export enum FilterMultiplePassType {\r\n merge = 'merge',\r\n chain = 'chain'\r\n}\r\n","export enum GridStateType {\r\n columns = 'columns',\r\n filter = 'filter',\r\n pagination = 'pagination',\r\n sorter = 'sorter'\r\n}\r\n","export enum KeyCode {\r\n BACKSPACE = 8,\r\n DELETE = 46,\r\n DOWN = 40,\r\n END = 35,\r\n ENTER = 13,\r\n ESCAPE = 27,\r\n HOME = 36,\r\n INSERT = 45,\r\n LEFT = 37,\r\n PAGE_DOWN = 34,\r\n PAGE_UP = 33,\r\n RIGHT = 39,\r\n TAB = 9,\r\n UP = 38\r\n}\r\n","export enum OperatorType {\r\n /** value is empty */\r\n empty = '',\r\n\r\n /** value contains x */\r\n contains = 'Contains',\r\n\r\n /** value not contains x (inversed of contains) */\r\n notContains = 'Not_Contains',\r\n\r\n /** value less than x */\r\n lessThan = 'LT',\r\n\r\n /** value less than or equal to x */\r\n lessThanOrEqual = 'LE',\r\n\r\n /** value greater than x */\r\n greaterThan = 'GT',\r\n\r\n /** value great than or equal to x */\r\n greaterThanOrEqual = 'GE',\r\n\r\n /** value not equal to x */\r\n notEqual = 'NE',\r\n\r\n /** value equal to x */\r\n equal = 'EQ',\r\n\r\n /** String ends with value */\r\n endsWith = 'EndsWith',\r\n\r\n /** String starts with value */\r\n startsWith = 'StartsWith',\r\n\r\n /** Find an equal match inside a collection */\r\n in = 'IN',\r\n\r\n /** Inverse (Not In) of an equal match inside a collection */\r\n notIn = 'NOT_IN',\r\n\r\n /**\r\n * Find a substring contained inside a collection\r\n * For example, this condition would return True with \"IN_CONTAINS\":: value='Task2,Task3', collection=['Task2','Task3']\r\n * This would have returned False with \"IN\" because 'Task2' does not equal 'Task2,Task3'. However 'Task2' is contained in 'Task2,Task3'\r\n */\r\n inContains = 'IN_CONTAINS',\r\n\r\n /** Inversed (Not In) of substring contained inside a collection */\r\n notInContains = 'NOT_IN_CONTAINS',\r\n}\r\n","export enum SortDirection {\r\n asc = 'asc',\r\n ASC = 'ASC',\r\n desc = 'desc',\r\n DESC = 'DESC'\r\n}\r\n","export enum SortDirectionNumber {\r\n asc = 1,\r\n desc = -1,\r\n neutral = 0,\r\n}\r\n","import { AngularComponentOutput } from '../models/angularComponentOutput.interface';\r\nimport { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector } from '@angular/core';\r\n\r\n@Injectable()\r\nexport class AngularUtilService {\r\n constructor(\r\n private compFactoryResolver: ComponentFactoryResolver,\r\n private appRef: ApplicationRef,\r\n private injector: Injector,\r\n ) { }\r\n\r\n // ref https://hackernoon.com/angular-pro-tip-how-to-dynamically-create-components-in-body-ba200cc289e6\r\n createAngularComponent(component: any): AngularComponentOutput {\r\n // Create a component reference from the component\r\n const componentRef = this.compFactoryResolver\r\n .resolveComponentFactory(component)\r\n .create(this.injector);\r\n\r\n // Attach component to the appRef so that it's inside the ng component tree\r\n this.appRef.attachView(componentRef.hostView);\r\n\r\n // Get DOM element from component\r\n let domElem;\r\n const viewRef = (componentRef.hostView as EmbeddedViewRef<any>);\r\n if (viewRef && Array.isArray(viewRef.rootNodes) && viewRef.rootNodes[0]) {\r\n domElem = viewRef.rootNodes[0] as HTMLElement;\r\n }\r\n\r\n return { componentRef, domElement: domElem };\r\n }\r\n\r\n // ref https://hackernoon.com/angular-pro-tip-how-to-dynamically-create-components-in-body-ba200cc289e6\r\n createAngularComponentAppendToDom(component: any, targetElement?: HTMLElement | Element, clearTargetContent = false): AngularComponentOutput {\r\n const componentOutput = this.createAngularComponent(component);\r\n\r\n // Append DOM element to the HTML element specified\r\n if (targetElement && targetElement.appendChild) {\r\n if (clearTargetContent && targetElement.innerHTML) {\r\n targetElement.innerHTML = '';\r\n }\r\n targetElement.appendChild(componentOutput.domElement);\r\n } else {\r\n document.body.appendChild(componentOutput.domElement); // when no target provided, we'll simply add it to the HTML Body\r\n }\r\n\r\n return componentOutput;\r\n }\r\n}\r\n","import { GraphqlResult } from '../models/graphqlResult.interface';\r\nimport { BackendServiceApi } from '../models/backendServiceApi.interface';\r\nimport { GridOption } from '../models';\r\n\r\n/** Execute the Backend Processes Callback, that could come from an Observable or a Promise callback */\r\nexport function executeBackendProcessesCallback(startTime: Date, processResult: GraphqlResult | any, backendApi: BackendServiceApi, gridOptions: GridOption): GraphqlResult | any {\r\n const endTime = new Date();\r\n\r\n // define what our internal Post Process callback, only available for GraphQL Service for now\r\n // it will basically refresh the Dataset & Pagination without having the user to create his own PostProcess every time\r\n if (processResult && backendApi && backendApi.internalPostProcess) {\r\n backendApi.internalPostProcess(processResult);\r\n }\r\n\r\n // send the response process to the postProcess callback\r\n if (backendApi.postProcess) {\r\n if (processResult instanceof Object) {\r\n processResult.statistics = {\r\n startTime,\r\n endTime,\r\n executionTime: endTime.valueOf() - startTime.valueOf(),\r\n itemCount: gridOptions && gridOptions.pagination && gridOptions.pagination.totalItems,\r\n totalItemCount: gridOptions && gridOptions.pagination && gridOptions.pagination.totalItems\r\n };\r\n }\r\n backendApi.postProcess(processResult);\r\n }\r\n}\r\n\r\n/** On a backend service api error, we will run the \"onError\" if there is 1 provided or just throw back the error when nothing is provided */\r\nexport function onBackendError(e: any, backendApi: BackendServiceApi) {\r\n if (backendApi && backendApi.onError) {\r\n backendApi.onError(e);\r\n } else {\r\n throw e;\r\n }\r\n}\r\n","import { FieldType, OperatorType } from '../models/index';\r\nimport { Observable, Subscription } from 'rxjs';\r\nimport { first, take } from 'rxjs/operators';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/**\r\n * Add an item to an array only when the item does not exists, when the item is an object we will be using their \"id\" to compare\r\n * @param inputArray\r\n * @param inputItem\r\n */\r\nexport function addToArrayWhenNotExists(inputArray: any[], inputItem: any) {\r\n let arrayRowIndex = -1;\r\n if (typeof inputItem === 'object' && inputItem.hasOwnProperty('id')) {\r\n arrayRowIndex = inputArray.findIndex((item) => item.id === inputItem.id);\r\n } else {\r\n arrayRowIndex = inputArray.findIndex((item) => item === inputItem);\r\n }\r\n\r\n if (arrayRowIndex < 0) {\r\n inputArray.push(inputItem);\r\n }\r\n}\r\n\r\n/**\r\n * Simple function to which will loop and create as demanded the number of white spaces,\r\n * this is used in the CSV export\r\n * @param int nbSpaces: number of white spaces to create\r\n */\r\nexport function addWhiteSpaces(nbSpaces: number): string {\r\n let result = '';\r\n\r\n for (let i = 0; i < nbSpaces; i++) {\r\n result += ' ';\r\n }\r\n return result;\r\n}\r\n\r\n/** HTML decode using jQuery with a <div>\r\n * Create a in-memory div, set it's inner text(which jQuery automatically encodes)\r\n * then grab the encoded contents back out. The div never exists on the page.\r\n*/\r\nexport function htmlDecode(encodedStr: string): string {\r\n const parser = DOMParser && new DOMParser;\r\n if (parser && parser.parseFromString) {\r\n const dom = parser.parseFromString(\r\n '<!doctype html><body>' + encodedStr,\r\n 'text/html');\r\n return dom && dom.body && dom.body.textContent;\r\n } else {\r\n // for some browsers that might not support DOMParser, use jQuery instead\r\n return $('<div/>').html(encodedStr).text();\r\n }\r\n}\r\n\r\n/** HTML encode using jQuery with a <div>\r\n * Create a in-memory div, set it's inner text(which jQuery automatically encodes)\r\n * then grab the encoded contents back out. The div never exists on the page.\r\n*/\r\nexport function htmlEncode(inputValue: string): string {\r\n const entityMap = {\r\n '&': '&amp;',\r\n '<': '&lt;',\r\n '>': '&gt;',\r\n '\"': '&quot;',\r\n '\\'': '&#39;',\r\n // '/': '&#x2F;',\r\n // '`': '&#x60;',\r\n // '=': '&#x3D;'\r\n };\r\n // all symbols:: /[&<>\"'`=\\/]/g\r\n return inputValue.replace(/[&<>\"']/g, (s) => {\r\n return entityMap[s];\r\n });\r\n}\r\n\r\n/** decode text into html entity\r\n * @param string text: input text\r\n * @param string text: output text\r\n */\r\nexport function htmlEntityDecode(input: string): string {\r\n return input.replace(/&#(\\d+);/g, function (match, dec) {\r\n return String.fromCharCode(dec);\r\n });\r\n}\r\n\r\n/** decode text into html entity\r\n * @param string text: input text\r\n * @param string text: output text\r\n */\r\nexport function htmlEntityEncode(input: any): string {\r\n const buf = [];\r\n for (let i = input.length - 1; i >= 0; i--) {\r\n buf.unshift(['&#', input[i].charCodeAt(), ';'].join(''));\r\n }\r\n return buf.join('');\r\n}\r\n\r\n/**\r\n * Compares two arrays of characters to determine if all the items are equal\r\n * @param a first array\r\n * @param b second array to compare with a\r\n * @param [orderMatters=false] flag if the order matters, if not arrays will be sorted before comparison\r\n * @return boolean true if equal, else false\r\n */\r\nexport function charArraysEqual(a: any[], b: any[], orderMatters: boolean = false): boolean {\r\n if (!Array.isArray(a) || !Array.isArray(a)) {\r\n return false;\r\n }\r\n\r\n if (a.length !== b.length) {\r\n return false;\r\n }\r\n\r\n if (!orderMatters) {\r\n a.sort();\r\n b.sort();\r\n }\r\n\r\n for (let i = 0; i < a.length; ++i) {\r\n if (a[i] !== b[i]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Try casting an input of type Promise | Observable into a Promise type.\r\n * @param object which could be of type Promise or Observable\r\n * @param fromServiceName string representing the caller service name and will be used if we throw a casting problem error\r\n */\r\nexport function castToPromise<T>(input: Promise<T> | Observable<T>, fromServiceName: string = ''): Promise<T> {\r\n let promise: any = input;\r\n\r\n if (input instanceof Promise) {\r\n // if it's already a Promise then return it\r\n return input;\r\n } else if (input instanceof Observable) {\r\n promise = input.pipe(first()).toPromise();\r\n }\r\n\r\n if (!(promise instanceof Promise)) {\r\n throw new Error(\r\n `Something went wrong, Angular-Slickgrid ${fromServiceName} is not able to convert the Observable into a Promise.\r\n If you are using Angular HttpClient, you could try converting your http call to a Promise with \".toPromise()\"\r\n for example:: this.http.post('graphql', { query: graphqlQuery }).toPromise()\r\n `);\r\n }\r\n\r\n return promise;\r\n}\r\n\r\n/**\r\n * Uses the logic function to find an item in an array or returns the default\r\n * value provided (empty object by default)\r\n * @param any[] array the array to filter\r\n * @param function logic the logic to find the item\r\n * @param any [defaultVal={}] the default value to return\r\n * @return object the found object or default value\r\n */\r\nexport function findOrDefault(array: any[], logic: (item: any) => boolean, defaultVal = {}): any {\r\n return array.find(logic) || defaultVal;\r\n}\r\n\r\n/**\r\n * Take a number (or a string) and display it as a formatted decimal string with defined minimum and maximum decimals\r\n * @param input\r\n * @param minDecimal\r\n * @param maxDecimal\r\n */\r\nexport function decimalFormatted(input: number | string, minDecimal?: number, maxDecimal?: number): string {\r\n if (isNaN(+input)) {\r\n return input as string;\r\n }\r\n\r\n const minDec = (minDecimal === undefined) ? 2 : minDecimal;\r\n const maxDec = (maxDecimal === undefined) ? 2 : maxDecimal;\r\n let amount = String(Math.round(+input * Math.pow(10, maxDec)) / Math.pow(10, maxDec));\r\n\r\n if ((amount.indexOf('.') < 0) && (minDec > 0)) {\r\n amount += '.';\r\n }\r\n while ((amount.length - amount.indexOf('.')) <= minDec) {\r\n amount += '0';\r\n }\r\n return amount;\r\n}\r\n\r\nexport function formatNumber(input: number | string, minDecimal?: number, maxDecimal?: number, displayNegativeNumberWithParentheses?: boolean, symbolPrefix = '', symbolSuffix = ''): string {\r\n if (isNaN(+input)) {\r\n return input as string;\r\n }\r\n\r\n const calculatedValue = ((Math.round(parseFloat(input as string) * 1000000) / 1000000));\r\n\r\n if (calculatedValue < 0) {\r\n const absValue = Math.abs(calculatedValue);\r\n if (displayNegativeNumberWithParentheses) {\r\n if (!isNaN(minDecimal) || !isNaN(maxDecimal)) {\r\n return `(${symbolPrefix}${decimalFormatted(absValue, minDecimal, maxDecimal)}${symbolSuffix})`;\r\n }\r\n return `(${symbolPrefix}${absValue}${symbolSuffix})`;\r\n } else {\r\n if (!isNaN(minDecimal) || !isNaN(maxDecimal)) {\r\n return `-${symbolPrefix}${decimalFormatted(absValue, minDecimal, maxDecimal)}${symbolSuffix}`;\r\n }\r\n return `-${symbolPrefix}${absValue}${symbolSuffix}`;\r\n }\r\n } else {\r\n if (!isNaN(minDecimal) || !isNaN(maxDecimal)) {\r\n return `${symbolPrefix}${decimalFormatted(input, minDecimal, maxDecimal)}${symbolSuffix}`;\r\n }\r\n return `${symbolPrefix}${input}${symbolSuffix}`;\r\n }\r\n}\r\n\r\n/** From a dot (.) notation find and return a property within an object given a path */\r\nexport function getDescendantProperty(obj: any, path: string): any {\r\n return path.split('.').reduce((acc, part) => acc && acc[part], obj);\r\n}\r\n\r\n/** Get the browser's scrollbar width, this is different to each browser */\r\nexport function getScrollBarWidth(): number {\r\n const $outer = $('<div>').css({ visibility: 'hidden', width: 100, overflow: 'scroll' }).appendTo('body');\r\n const widthWithScroll = $('<div>').css({ width: '100%' }).appendTo($outer).outerWidth();\r\n $outer.remove();\r\n return Math.ceil(100 - widthWithScroll);\r\n}\r\n\r\n/**\r\n * From a Date FieldType, return it's equivalent moment.js format\r\n * refer to moment.js for the format standard used: https://momentjs.com/docs/#/parsing/string-format/\r\n * @param fieldType\r\n */\r\nexport function mapMomentDateFormatWithFieldType(fieldType: FieldType): string {\r\n let map: string;\r\n switch (fieldType) {\r\n case FieldType.dateTime:\r\n case FieldType.dateTimeIso:\r\n map = 'YYYY-MM-DD HH:mm:ss';\r\n break;\r\n case FieldType.dateTimeShortIso:\r\n map = 'YYYY-MM-DD HH:mm';\r\n break;\r\n case FieldType.dateTimeIsoAmPm:\r\n map = 'YYYY-MM-DD hh:mm:ss a';\r\n break;\r\n case FieldType.dateTimeIsoAM_PM:\r\n map = 'YYYY-MM-DD hh:mm:ss A';\r\n break;\r\n // all Euro Formats (date/month/year)\r\n case FieldType.dateEuro:\r\n map = 'DD/MM/YYYY';\r\n break;\r\n case FieldType.dateEuroShort:\r\n map = 'D/M/YY';\r\n break;\r\n case FieldType.dateTimeEuro:\r\n map = 'DD/MM/YYYY HH:mm:ss';\r\n break;\r\n case FieldType.dateTimeShortEuro:\r\n map = 'DD/MM/YYYY HH:mm';\r\n break;\r\n case FieldType.dateTimeEuroAmPm:\r\n map = 'DD/MM/YYYY hh:mm:ss a';\r\n break;\r\n case FieldType.dateTimeEuroAM_PM:\r\n map = 'DD/MM/YYYY hh:mm:ss A';\r\n break;\r\n case FieldType.dateTimeEuroShort:\r\n map = 'D/M/YY H:m:s';\r\n break;\r\n case FieldType.dateTimeEuroShortAmPm:\r\n map = 'D/M/YY h:m:s a';\r\n break;\r\n // all US Formats (month/date/year)\r\n case FieldType.dateUs:\r\n map = 'MM/DD/YYYY';\r\n break;\r\n case FieldType.dateUsShort:\r\n map = 'M/D/YY';\r\n break;\r\n case FieldType.dateTimeUs:\r\n map = 'MM/DD/YYYY HH:mm:ss';\r\n break;\r\n case FieldType.dateTimeShortUs:\r\n map = 'MM/DD/YYYY HH:mm';\r\n break;\r\n case FieldType.dateTimeUsAmPm:\r\n map = 'MM/DD/YYYY hh:mm:ss a';\r\n break;\r\n case FieldType.dateTimeUsAM_PM:\r\n map = 'MM/DD/YYYY hh:mm:ss A';\r\n break;\r\n case FieldType.dateTimeUsShort:\r\n map = 'M/D/YY H:m:s';\r\n break;\r\n case FieldType.dateTimeUsShortAmPm:\r\n map = 'M/D/YY h:m:s a';\r\n break;\r\n case FieldType.dateUtc:\r\n map = 'YYYY-MM-DDTHH:mm:ss.SSSZ';\r\n break;\r\n case FieldType.date:\r\n case FieldType.dateIso:\r\n default:\r\n map = 'YYYY-MM-DD';\r\n break;\r\n }\r\n return map;\r\n}\r\n\r\n/**\r\n * From a Date FieldType, return it's equivalent Flatpickr format\r\n * refer to Flatpickr for the format standard used: https://chmln.github.io/flatpickr/formatting/#date-formatting-tokens\r\n * also note that they seem very similar to PHP format (except for am/pm): http://php.net/manual/en/function.date.php\r\n * @param fieldType\r\n */\r\nexport function mapFlatpickrDateFormatWithFieldType(fieldType: FieldType): string {\r\n /*\r\n d: Day of the month, 2 digits with leading zeros\t01 to 31\r\n D: A textual representation of a day\tMon through Sun\r\n l: (lowercase 'L')\tA full textual representation of the day of the week\tSunday through Saturday\r\n j: Day of the month without leading zeros\t1 to 31\r\n J: Day of the month without leading zeros and ordinal suffix\t1st, 2nd, to 31st\r\n w: Numeric representation of the day of the week\t0 (for Sunday) through 6 (for Saturday)\r\n F: A full textual representation of a month\tJanuary through December\r\n m: Numeric representation of a month, with leading zero\t01 through 12\r\n n: Numeric representation of a month, without leading zeros\t1 through 12\r\n M: A short textual representation of a month\tJan through Dec\r\n U: The number of seconds since the Unix Epoch\t1413704993\r\n y: A two digit representation of a year\t99 or 03\r\n Y: A full numeric representation of a year, 4 digits\t1999 or 2003\r\n H: Hours (24 hours)\t00 to 23\r\n h: Hours\t1 to 12\r\n i: Minutes\t00 to 59\r\n S: Seconds, 2 digits\t00 to 59\r\n s: Seconds\t0, 1 to 59\r\n K: AM/PM\tAM or PM\r\n */\r\n let map: string;\r\n switch (fieldType) {\r\n case FieldType.dateTime:\r\n case FieldType.dateTimeIso:\r\n map = 'Y-m-d H:i:S';\r\n break;\r\n case FieldType.dateTimeShortIso:\r\n map = 'Y-m-d H:i';\r\n break;\r\n case FieldType.dateTimeIsoAmPm:\r\n case FieldType.dateTimeIsoAM_PM:\r\n map = 'Y-m-d h:i:S K'; // there is no lowercase in Flatpickr :(\r\n break;\r\n // all Euro Formats (date/month/year)\r\n case FieldType.dateEuro:\r\n map = 'd/m/Y';\r\n break;\r\n case FieldType.dateEuroShort:\r\n map = 'd/m/y';\r\n break;\r\n case FieldType.dateTimeEuro:\r\n map = 'd/m/Y H:i:S';\r\n break;\r\n case FieldType.dateTimeShortEuro:\r\n map = 'd/m/y H:i';\r\n break;\r\n case FieldType.dateTimeEuroAmPm:\r\n map = 'd/m/Y h:i:S K'; // there is no lowercase in Flatpickr :(\r\n break;\r\n case FieldType.dateTimeEuroAM_PM:\r\n map = 'd/m/Y h:i:s K';\r\n break;\r\n case FieldType.dateTimeEuroShort:\r\n map = 'd/m/y H:i:s';\r\n break;\r\n case FieldType.dateTimeEuroShortAmPm:\r\n map = 'd/m/y h:i:s K'; // there is no lowercase in Flatpickr :(\r\n break;\r\n // all US Formats (month/date/year)\r\n case FieldType.dateUs:\r\n map = 'm/d/Y';\r\n break;\r\n case FieldType.dateUsShort:\r\n map = 'm/d/y';\r\n break;\r\n case FieldType.dateTimeUs:\r\n map = 'm/d/Y H:i:S';\r\n break;\r\n case FieldType.dateTimeShortUs:\r\n map = 'm/d/y H:i';\r\n break;\r\n case FieldType.dateTimeUsAmPm:\r\n map = 'm/d/Y h:i:S K'; // there is no lowercase in Flatpickr :(\r\n break;\r\n case FieldType.dateTimeUsAM_PM:\r\n map = 'm/d/Y h:i:s K';\r\n break;\r\n case FieldType.dateTimeUsShort:\r\n map = 'm/d/y H:i:s';\r\n break;\r\n case FieldType.dateTimeUsShortAmPm:\r\n map = 'm/d/y h:i:s K'; // there is no lowercase in Flatpickr :(\r\n break;\r\n case FieldType.dateUtc:\r\n map = 'Z';\r\n break;\r\n case FieldType.date:\r\n case FieldType.dateIso:\r\n default:\r\n map = 'Y-m-d';\r\n break;\r\n }\r\n return map;\r\n}\r\n\r\n/**\r\n * Mapper for query operators (ex.: <= is \"le\", > is \"gt\")\r\n * @param string operator\r\n * @returns string map\r\n */\r\nexport function mapOperatorType(operator: string): OperatorType {\r\n let map: OperatorType;\r\n\r\n switch (operator) {\r\n case '<':\r\n map = OperatorType.lessThan;\r\n break;\r\n case '<=':\r\n map = OperatorType.lessThanOrEqual;\r\n break;\r\n case '>':\r\n map = OperatorType.greaterThan;\r\n break;\r\n case '>=':\r\n map = OperatorType.greaterThanOrEqual;\r\n break;\r\n case '<>':\r\n case '!=':\r\n case 'neq':\r\n case 'NEQ':\r\n map = OperatorType.notEqual;\r\n break;\r\n case '*':\r\n case '.*':\r\n case 'a*':\r\n case 'startsWith':\r\n case 'StartsWith':\r\n map = OperatorType.startsWith;\r\n break;\r\n case '*.':\r\n case '*z':\r\n case 'endsWith':\r\n case 'EndsWith':\r\n map = OperatorType.endsWith;\r\n break;\r\n case '=':\r\n case '==':\r\n case 'eq':\r\n case 'EQ':\r\n map = OperatorType.equal;\r\n break;\r\n case 'in':\r\n case 'IN':\r\n map = OperatorType.in;\r\n break;\r\n case 'notIn':\r\n case 'NIN':\r\n case 'NOT_IN':\r\n map = OperatorType.notIn;\r\n break;\r\n case 'not_contains':\r\n case 'Not_Contains':\r\n case 'notContains':\r\n case 'NotContains':\r\n case 'NOT_CONTAINS':\r\n map = OperatorType.notContains;\r\n break;\r\n case 'Contains':\r\n default:\r\n map = OperatorType.contains;\r\n break;\r\n }\r\n\r\n return map;\r\n}\r\n\r\n/**\r\n * Mapper for query operator by a Filter Type\r\n * For example a multiple-select typically uses 'IN' operator\r\n * @param operator\r\n * @returns string map\r\n */\r\nexport function mapOperatorByFieldType(fieldType: FieldType | string): OperatorType {\r\n let map: OperatorType;\r\n\r\n switch (fieldType) {\r\n case FieldType.string:\r\n case FieldType.unknown:\r\n map = OperatorType.contains;\r\n break;\r\n case FieldType.float:\r\n case FieldType.number:\r\n case FieldType.date:\r\n case FieldType.dateIso:\r\n case FieldType.date:\r\n case FieldType.dateUtc:\r\n case FieldType.dateTime:\r\n case FieldType.dateTimeIso:\r\n case FieldType.dateTimeIsoAmPm:\r\n case FieldType.dateTimeIsoAM_PM:\r\n case FieldType.dateEuro:\r\n case FieldType.dateEuroShort:\r\n case FieldType.dateTimeEuro:\r\n case FieldType.dateTimeEuroAmPm:\r\n case FieldType.dateTimeEuroAM_PM:\r\n case FieldType.dateTimeEuroShort:\r\n case FieldType.dateTimeEuroShortAmPm:\r\n case FieldType.dateTimeEuroShortAM_PM:\r\n case FieldType.dateUs:\r\n case FieldType.dateUsShort:\r\n case FieldType.dateTimeUs:\r\n case FieldType.dateTimeUsAmPm:\r\n case FieldType.dateTimeUsAM_PM:\r\n case FieldType.dateTimeUsShort:\r\n case FieldType.dateTimeUsShortAmPm:\r\n case FieldType.dateTimeUsShortAM_PM:\r\n default:\r\n map = OperatorType.equal;\r\n break;\r\n }\r\n\r\n return map;\r\n}\r\n\r\n/** Parse any input (bool, number, string) and return a boolean or False when not possible */\r\nexport function parseBoolean(input: boolean | number | string): boolean {\r\n return /(true|1)/i.test(input + '');\r\n}\r\n\r\n/**\r\n * Parse a date passed as a string (Date only, without time) and return a Date object (if valid)\r\n * @param inputDateString\r\n * @returns string date formatted\r\n */\r\nexport function parseUtcDate(inputDateString: string, useUtc?: boolean): string | null {\r\n let date = null;\r\n\r\n if (/^[0-9\\-\\/]*$/.test(inputDateString)) {\r\n // get the UTC datetime with moment.js but we need to decode the value so that it's valid text\r\n const dateString = decodeURIComponent(inputDateString);\r\n const dateMoment = moment(new Date(dateString));\r\n if (dateMoment.isValid() && dateMoment.year().toString().length === 4) {\r\n date = (useUtc) ? dateMoment.utc().format() : dateMoment.format();\r\n }\r\n }\r\n\r\n return date;\r\n}\r\n\r\n/**\r\n * Sanitize, return only the text without HTML tags\r\n * @input htmlString\r\n * @return text\r\n */\r\nexport function sanitizeHtmlToText(htmlString: string) {\r\n const temp = document.createElement('div');\r\n temp.innerHTML = htmlString;\r\n return temp.textContent || temp.innerText || '';\r\n}\r\n\r\n/**\r\n * Title case (or capitalize) first char of a string\r\n * Optionall title case the complete sentence (upper case first char of each word while changing everything else to lower case)\r\n * @param inputStr\r\n * @returns string\r\n */\r\nexport function titleCase(inputStr: string, caseEveryWords = false): string {\r\n if (typeof inputStr === 'string') {\r\n if (caseEveryWords) {\r\n return inputStr.replace(/\\w\\S*/g, (outputStr) => {\r\n return outputStr.charAt(0).toUpperCase() + outputStr.substr(1).toLowerCase();\r\n });\r\n }\r\n return inputStr.charAt(0).toUpperCase() + inputStr.slice(1);\r\n }\r\n return inputStr;\r\n}\r\n\r\n/**\r\n * Converts a string to camel case (camelCase)\r\n * @param inputStr the string to convert\r\n * @return the string in camel case\r\n */\r\nexport function toCamelCase(inputStr: string): string {\r\n if (typeof inputStr === 'string') {\r\n return inputStr.replace(/(?:^\\w|[A-Z]|\\b\\w|[\\s+\\-_\\/])/g, (match: string, offset: number) => {\r\n // remove white space or hypens or underscores\r\n if (/[\\s+\\-_\\/]/.test(match)) {\r\n return '';\r\n }\r\n\r\n return offset === 0 ? match.toLowerCase() : match.toUpperCase();\r\n });\r\n }\r\n return inputStr;\r\n}\r\n\r\n/**\r\n * Converts a string to kebab (hypen) case\r\n * @param str the string to convert\r\n * @return the string in kebab case\r\n */\r\nexport function toKebabCase(inputStr: string): string {\r\n if (typeof inputStr === 'string') {\r\n return toCamelCase(inputStr).replace(/([A-Z])/g, '-$1').toLowerCase();\r\n }\r\n return inputStr;\r\n}\r\n\r\n/**\r\n * Converts a string from camelCase to snake_case (underscore) case\r\n * @param str the string to convert\r\n * @return the string in kebab case\r\n */\r\nexport function toSnakeCase(inputStr: string): string {\r\n if (typeof inputStr === 'string') {\r\n return toCamelCase(inputStr).replace(/([A-Z])/g, '_$1').toLowerCase();\r\n }\r\n return inputStr;\r\n}\r\n\r\n/**\r\n * Takes an input array and makes sure the array has unique values by removing duplicates\r\n * @param array input with possible duplicates\r\n * @param objectProperty optionally provide an object property to compare (example: 'id')\r\n * @return array output without duplicates\r\n */\r\nexport function uniqueArray(arr: any[]): any[] {\r\n if (Array.isArray(arr) && arr.length > 0) {\r\n return arr.filter((item: any, index: number) => {\r\n return arr.indexOf(item) >= index;\r\n });\r\n }\r\n return arr;\r\n}\r\n\r\n/**\r\n * Takes an input array of objects and makes sure the array has unique object values by removing duplicates\r\n * it will loop through the array using a property name (or \"id\" when is not provided) to compare uniqueness\r\n * @param array input with possible duplicates\r\n * @param propertyName defaults to \"id\"\r\n * @return array output without duplicates\r\n */\r\nexport function uniqueObjectArray(arr: any[], propertyName = 'id'): any[] {\r\n if (Array.isArray(arr) && arr.length > 0) {\r\n const result = [];\r\n const map = new Map();\r\n\r\n for (const item of arr) {\r\n if (!map.has(item[propertyName])) {\r\n map.set(item[propertyName], true); // set any value to Map\r\n result.push({\r\n id: item[propertyName],\r\n name: item.name\r\n });\r\n }\r\n }\r\n return result;\r\n }\r\n return arr;\r\n}\r\n\r\n/**\r\n * Unsubscribe all Observables Subscriptions\r\n * It will return an empty array if it all went well\r\n * @param subscriptions\r\n */\r\nexport function unsubscribeAllObservables(subscriptions: Subscription[]): Subscription[] {\r\n if (Array.isArray(subscriptions)) {\r\n subscriptions.forEach((subscription: Subscription) => {\r\n if (subscription && subscription.unsubscribe) {\r\n subscription.unsubscribe();\r\n }\r\n });\r\n subscriptions = [];\r\n }\r\n\r\n return subscriptions;\r\n}\r\n","import * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\n\r\nexport function compareDates(value1, value2, format, sortDirection, strict?: boolean) {\r\n let diff = 0;\r\n\r\n if (value1 === null || value1 === '' || !moment(value1, format, strict).isValid()) {\r\n diff = -1;\r\n } else if (value2 === null || value2 === '' || !moment(value2, format, strict).isValid()) {\r\n diff = 1;\r\n } else {\r\n const date1 = moment(value1, format, strict);\r\n const date2 = moment(value2, format, strict);\r\n diff = parseInt(date1.format('X'), 10) - parseInt(date2.format('X'), 10);\r\n }\r\n\r\n return sortDirection * (diff === 0 ? 0 : (diff > 0 ? 1 : -1));\r\n}\r\n","import { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { FieldType, Sorter } from './../models/index';\r\nimport { compareDates } from './compareDateUtility';\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateEuroShort);\r\n\r\nexport const dateEuroShortSorter: Sorter = (value1, value2, sortDirection) => {\r\n return compareDates(value1, value2, FORMAT, sortDirection, true);\r\n};\r\n","import { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { FieldType, Sorter } from './../models/index';\r\nimport { compareDates } from './compareDateUtility';\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateEuro);\r\n\r\nexport const dateEuroSorter: Sorter = (value1, value2, sortDirection) => {\r\n return compareDates(value1, value2, FORMAT, sortDirection, true);\r\n};\r\n","import { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { FieldType, Sorter } from './../models/index';\r\nimport { compareDates } from './compareDateUtility';\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateIso);\r\n\r\nexport const dateIsoSorter: Sorter = (value1, value2, sortDirection) => {\r\n return compareDates(value1, value2, FORMAT, sortDirection, true);\r\n};\r\n","import { Sorter } from './../models/index';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\nimport { compareDates } from './compareDateUtility';\r\n\r\nexport const dateSorter: Sorter = (value1, value2, sortDirection) => {\r\n return compareDates(value1, value2, moment.ISO_8601, sortDirection);\r\n};\r\n","import { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { FieldType, Sorter } from './../models/index';\r\nimport { compareDates } from './compareDateUtility';\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateUsShort);\r\n\r\nexport const dateUsShortSorter: Sorter = (value1, value2, sortDirection) => {\r\n return compareDates(value1, value2, FORMAT, sortDirection, true);\r\n};\r\n","import { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { FieldType, Sorter } from './../models/index';\r\nimport { compareDates } from './compareDateUtility';\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateUs);\r\n\r\nexport const dateUsSorter: Sorter = (value1, value2, sortDirection) => {\r\n return compareDates(value1, value2, FORMAT, sortDirection, true);\r\n};\r\n","import { Sorter } from './../models/index';\r\n\r\nexport const numericSorter: Sorter = (value1, value2, sortDirection) => {\r\n const x = (isNaN(value1) || value1 === '' || value1 === null) ? -99e+10 : parseFloat(value1);\r\n const y = (isNaN(value2) || value2 === '' || value2 === null) ? -99e+10 : parseFloat(value2);\r\n return sortDirection * (x === y ? 0 : (x > y ? 1 : -1));\r\n};\r\n","import { Column, Sorter, SortDirectionNumber } from './../models/index';\r\n\r\nexport const objectStringSorter: Sorter = (value1: any, value2: any, sortDirection: number | SortDirectionNumber, sortColumn: Column) => {\r\n if (!sortColumn || !sortColumn.dataKey) {\r\n throw new Error('Sorting a \"FieldType.object\" requires you to provide the \"dataKey\" (object property name) of the object so that we can use it to sort correctly');\r\n }\r\n\r\n const stringValue1 = value1.hasOwnProperty(sortColumn.dataKey) ? value1[sortColumn.dataKey] : value1;\r\n const stringValue2 = value2.hasOwnProperty(sortColumn.dataKey) ? value2[sortColumn.dataKey] : value2;\r\n if (sortDirection === undefined || sortDirection === null) {\r\n sortDirection = SortDirectionNumber.neutral;\r\n }\r\n\r\n let position = 0;\r\n if (typeof value1 !== 'object') {\r\n position = -99e+10;\r\n } else if (typeof value2 !== 'object') {\r\n position = 99e+10;\r\n } else if (!stringValue1) {\r\n position = -1;\r\n } else if (!stringValue2) {\r\n position = 1;\r\n } else if (stringValue1 === stringValue2) {\r\n position = 0;\r\n } else if (sortDirection) {\r\n position = stringValue1 < stringValue2 ? -1 : 1;\r\n } else {\r\n position = stringValue1 < stringValue2 ? 1 : -1;\r\n }\r\n\r\n return sortDirection * position;\r\n};\r\n","import { Sorter, SortDirectionNumber } from './../models/index';\r\n\r\nexport const stringSorter: Sorter = (value1: any, value2: any, sortDirection: number | SortDirectionNumber) => {\r\n if (sortDirection === undefined || sortDirection === null) {\r\n sortDirection = SortDirectionNumber.neutral;\r\n }\r\n let position = 0;\r\n\r\n if (value1 === null) {\r\n position = -1;\r\n } else if (value2 === null) {\r\n position = 1;\r\n } else if (value1 === value2) {\r\n position = 0;\r\n } else if (sortDirection) {\r\n position = value1 < value2 ? -1 : 1;\r\n } else {\r\n position = value1 < value2 ? 1 : -1;\r\n }\r\n return sortDirection * position;\r\n};\r\n","import { SortDirectionNumber } from './../models/sortDirectionNumber.enum';\r\nimport { dateEuroShortSorter } from './dateEuroShortSorter';\r\nimport { dateEuroSorter } from './dateEuroSorter';\r\nimport { dateIsoSorter } from './dateIsoSorter';\r\nimport { dateSorter } from './dateSorter';\r\nimport { dateUsShortSorter } from './dateUsShortSorter';\r\nimport { dateUsSorter } from './dateUsSorter';\r\nimport { numericSorter } from './numericSorter';\r\nimport { objectStringSorter } from './objectStringSorter';\r\nimport { stringSorter } from './stringSorter';\r\n\r\nexport const Sorters = {\r\n /** Sorter method to sort values by Date object type (uses Moment.js ISO_8601 standard format, optionally include time) */\r\n date: dateSorter,\r\n\r\n /**\r\n * Sorter method to sort values by Date formatted as ISO date (excluding time),\r\n * If you wish to optionally include time simply use the \"Sorters.date\" which work with/without time\r\n */\r\n dateIso: dateIsoSorter,\r\n\r\n /** Sorter method to sort values by Date formatted as Euro date (dd/mm/yyyy) */\r\n dateEuro: dateEuroSorter,\r\n\r\n /** Sorter method to sort values by Date formatted as Euro short date (d/m/yy) */\r\n dateEuroShort: dateEuroShortSorter,\r\n\r\n /** Sorter method to sort values by Date formatted as US date (mm/dd/yyyy) */\r\n dateUs: dateUsSorter,\r\n\r\n /** Sorter method to sort values by Date formatted as US short date (m/d/yy) */\r\n dateUsShort: dateUsShortSorter,\r\n\r\n /** Sorter method to sort values as numeric fields */\r\n numeric: numericSorter,\r\n\r\n /**\r\n * Sorter method to sort object values with a \"dataKey\" provided in your column definition, it's data content must be of type string\r\n * Example:\r\n * columnDef = { id='user', field: 'user', ..., dataKey: 'firstName', sorter: Sorters.objectString }\r\n * collection = [{ firstName: 'John', lastName: 'Doe' }, { firstName: 'Bob', lastName: 'Cash' }]\r\n */\r\n objectString: objectStringSorter,\r\n\r\n /** Sorter method to sort values as regular strings */\r\n string: stringSorter\r\n};\r\n","import { SortDirectionNumber } from './../models/sortDirectionNumber.enum';\r\nimport { Column, FieldType } from './../models/index';\r\nimport { Sorters } from './index';\r\n\r\nexport function sortByFieldType(value1: any, value2: any, fieldType: FieldType, sortDirection: number | SortDirectionNumber, sortColumn: Column) {\r\n let sortResult = 0;\r\n\r\n switch (fieldType) {\r\n case FieldType.number:\r\n sortResult = Sorters.numeric(value1, value2, sortDirection);\r\n break;\r\n case FieldType.date:\r\n sortResult = Sorters.date(value1, value2, sortDirection);\r\n break;\r\n case FieldType.dateIso:\r\n sortResult = Sorters.dateIso(value1, value2, sortDirection);\r\n break;\r\n // all Euro Formats (date/month/year)\r\n case FieldType.dateEuro:\r\n sortResult = Sorters.dateEuro(value1, value2, sortDirection);\r\n break;\r\n case FieldType.dateEuroShort:\r\n sortResult = Sorters.dateEuroShort(value1, value2, sortDirection);\r\n break;\r\n // all US Formats (month/date/year)\r\n case FieldType.dateUs:\r\n sortResult = Sorters.dateUs(value1, value2, sortDirection);\r\n break;\r\n case FieldType.dateUsShort:\r\n sortResult = Sorters.dateUsShort(value1, value2, sortDirection);\r\n break;\r\n case FieldType.object:\r\n sortResult = Sorters.objectString(value1, value2, sortDirection, sortColumn);\r\n break;\r\n default:\r\n sortResult = Sorters.string(value1, value2, sortDirection);\r\n break;\r\n }\r\n\r\n return sortResult;\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport {\r\n CollectionFilterBy,\r\n CollectionSortBy,\r\n Column,\r\n FilterMultiplePassType,\r\n FilterMultiplePassTypeString,\r\n FieldType,\r\n OperatorType,\r\n SortDirectionNumber,\r\n} from './../models/index';\r\nimport { sortByFieldType } from '../sorters/sorterUtilities';\r\nimport { uniqueArray } from './utilities';\r\n\r\n@Injectable()\r\nexport class CollectionService {\r\n constructor(private translate: TranslateService) { }\r\n\r\n /**\r\n * Filter 1 or more items from a collection\r\n * @param collection\r\n * @param filterByOptions\r\n */\r\n filterCollection(collection: any[], filterByOptions: CollectionFilterBy | CollectionFilterBy[], filterResultBy: FilterMultiplePassType | FilterMultiplePassTypeString | null = FilterMultiplePassType.chain): any[] {\r\n let filteredCollection: any[] = [];\r\n\r\n // when it's array, we will use the new filtered collection after every pass\r\n // basically if input collection has 10 items on 1st pass and 1 item is filtered out, then on 2nd pass the input collection will be 9 items\r\n if (Array.isArray(filterByOptions)) {\r\n filteredCollection = (filterResultBy === FilterMultiplePassType.merge) ? [] : collection;\r\n\r\n for (const filter of filterByOptions) {\r\n if (filterResultBy === FilterMultiplePassType.merge) {\r\n const filteredPass = this.singleFilterCollection(collection, filter);\r\n filteredCollection = uniqueArray([...filteredCollection, ...filteredPass]);\r\n } else {\r\n filteredCollection = this.singleFilterCollection(filteredCollection, filter);\r\n }\r\n }\r\n } else {\r\n filteredCollection = this.singleFilterCollection(collection, filterByOptions);\r\n }\r\n\r\n return filteredCollection;\r\n }\r\n\r\n /**\r\n * Filter an item from a collection\r\n * @param collection\r\n * @param filterBy\r\n */\r\n singleFilterCollection(collection: any[], filterBy: CollectionFilterBy): any[] {\r\n let filteredCollection: any[] = [];\r\n\r\n if (filterBy && filterBy.property) {\r\n const property = filterBy.property;\r\n const operator = filterBy.operator || OperatorType.equal;\r\n // just check for undefined since the filter value could be null, 0, '', false etc\r\n const value = typeof filterBy.value === 'undefined' ? '' : filterBy.value;\r\n\r\n switch (operator) {\r\n case OperatorType.equal:\r\n filteredCollection = collection.filter((item) => item[property] === value);\r\n break;\r\n case OperatorType.contains:\r\n filteredCollection = collection.filter((item) => item[property].toString().indexOf(value.toString()) !== -1);\r\n break;\r\n case OperatorType.notContains:\r\n filteredCollection = collection.filter((item) => item[property].toString().indexOf(value.toString()) === -1);\r\n break;\r\n case OperatorType.notEqual:\r\n default:\r\n filteredCollection = collection.filter((item) => item[property] !== value);\r\n }\r\n }\r\n\r\n return filteredCollection;\r\n }\r\n\r\n /**\r\n * Sort 1 or more items in a collection\r\n * @param column definition\r\n * @param collection\r\n * @param sortByOptions\r\n * @param enableTranslateLabel\r\n */\r\n sortCollection(columnDef: Column, collection: any[], sortByOptions: CollectionSortBy | CollectionSortBy[], enableTranslateLabel?: boolean): any[] {\r\n let sortedCollection: any[] = [];\r\n\r\n if (sortByOptions) {\r\n if (Array.isArray(sortByOptions)) {\r\n // multi-sort\r\n sortedCollection = collection.sort((dataRow1: any, dataRow2: any) => {\r\n for (let i = 0, l = sortByOptions.length; i < l; i++) {\r\n const sortBy = sortByOptions[i];\r\n\r\n if (sortBy && sortBy.property) {\r\n const sortDirection = sortBy.sortDesc ? SortDirectionNumber.desc : SortDirectionNumber.asc;\r\n const propertyName = sortBy.property;\r\n const fieldType = sortBy.fieldType || FieldType.string;\r\n const value1 = (enableTranslateLabel) ? this.translate.instant(dataRow1[propertyName] || ' ') : dataRow1[propertyName];\r\n const value2 = (enableTranslateLabel) ? this.translate.instant(dataRow2[propertyName] || ' ') : dataRow2[propertyName];\r\n\r\n const sortResult = sortByFieldType(value1, value2, fieldType, sortDirection, columnDef);\r\n if (sortResult !== SortDirectionNumber.neutral) {\r\n return sortResult;\r\n }\r\n }\r\n }\r\n return SortDirectionNumber.neutral;\r\n });\r\n } else if (sortByOptions && sortByOptions.property) {\r\n // single sort\r\n const propertyName = sortByOptions.property;\r\n const sortDirection = sortByOptions.sortDesc ? SortDirectionNumber.desc : SortDirectionNumber.asc;\r\n const fieldType = sortByOptions.fieldType || FieldType.string;\r\n\r\n sortedCollection = collection.sort((dataRow1: any, dataRow2: any) => {\r\n const value1 = (enableTranslateLabel) ? this.translate.instant(dataRow1[propertyName] || ' ') : dataRow1[propertyName];\r\n const value2 = (enableTranslateLabel) ? this.translate.instant(dataRow2[propertyName] || ' ') : dataRow2[propertyName];\r\n const sortResult = sortByFieldType(value1, value2, fieldType, sortDirection, columnDef);\r\n if (sortResult !== SortDirectionNumber.neutral) {\r\n return sortResult;\r\n }\r\n return SortDirectionNumber.neutral;\r\n });\r\n } else if (sortByOptions && !sortByOptions.property) {\r\n const sortDirection = sortByOptions.sortDesc ? SortDirectionNumber.desc : SortDirectionNumber.asc;\r\n const fieldType = sortByOptions.fieldType || FieldType.string;\r\n\r\n sortedCollection = collection.sort((dataRow1: any, dataRow2: any) => {\r\n const value1 = (enableTranslateLabel) ? this.translate.instant(dataRow1 || ' ') : dataRow1;\r\n const value2 = (enableTranslateLabel) ? this.translate.instant(dataRow2 || ' ') : dataRow2;\r\n const sortResult = sortByFieldType(value1, value2, fieldType, sortDirection, columnDef);\r\n if (sortResult !== SortDirectionNumber.neutral) {\r\n return sortResult;\r\n }\r\n return SortDirectionNumber.neutral;\r\n });\r\n }\r\n }\r\n\r\n return sortedCollection;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport {\r\n Column,\r\n ExportOption,\r\n FileType,\r\n Formatter,\r\n GridOption\r\n} from './../models/index';\r\nimport { addWhiteSpaces, htmlEntityDecode, sanitizeHtmlToText } from './../services/utilities';\r\nimport { Subject } from 'rxjs';\r\nimport { TextEncoder } from 'text-encoding-utf-8';\r\n\r\n// using external non-typed js libraries\r\ndeclare let $: any;\r\n\r\nexport interface ExportColumnHeader {\r\n key: string;\r\n title: string;\r\n}\r\n\r\n@Injectable()\r\nexport class ExportService {\r\n private _lineCarriageReturn = '\\n';\r\n private _dataView: any;\r\n private _grid: any;\r\n private _exportQuoteWrapper: string;\r\n private _columnHeaders: ExportColumnHeader[];\r\n private _groupedHeaders: ExportColumnHeader[];\r\n private _hasGroupedItems = false;\r\n private _exportOptions: ExportOption;\r\n onGridBeforeExportToFile = new Subject<boolean>();\r\n onGridAfterExportToFile = new Subject<{ options: any }>();\r\n\r\n constructor(private translate: TranslateService) { }\r\n\r\n private get datasetIdName(): string {\r\n return this._gridOptions && this._gridOptions.datasetIdPropertyName || 'id';\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n /**\r\n * Initialize the Export Service\r\n * @param grid\r\n * @param gridOptions\r\n * @param dataView\r\n */\r\n init(grid: any, dataView: any): void {\r\n this._grid = grid;\r\n this._dataView = dataView;\r\n }\r\n\r\n /**\r\n * Function to export the Grid result to an Excel CSV format using javascript for it to produce the CSV file.\r\n * This is a WYSIWYG export to file output (What You See is What You Get)\r\n *\r\n * NOTES: The column position needs to match perfectly the JSON Object position because of the way we are pulling the data,\r\n * which means that if any column(s) got moved in the UI, it has to be reflected in the JSON array output as well\r\n *\r\n * Example: exportToFile({ format: FileType.csv, delimiter: DelimiterType.comma })\r\n */\r\n exportToFile(options: ExportOption) {\r\n this.onGridBeforeExportToFile.next(true);\r\n this._exportOptions = $.extend(true, {}, this._gridOptions.exportOptions, options);\r\n\r\n // get the CSV output from the grid data\r\n const dataOutput = this.getDataOutput();\r\n\r\n // trigger a download file\r\n // wrap it into a setTimeout so that the EventAggregator has enough time to start a pre-process like showing a spinner\r\n setTimeout(() => {\r\n const downloadOptions = {\r\n filename: `${this._exportOptions.filename}.${this._exportOptions.format}`,\r\n csvContent: dataOutput,\r\n format: this._exportOptions.format,\r\n useUtf8WithBom: this._exportOptions.useUtf8WithBom\r\n };\r\n this.startDownloadFile(downloadOptions);\r\n this.onGridAfterExportToFile.next({ options: downloadOptions });\r\n }, 0);\r\n }\r\n\r\n // -----------------------\r\n // Private functions\r\n // -----------------------\r\n\r\n getDataOutput(): string {\r\n const columns = this._grid.getColumns() || [];\r\n const delimiter = this._exportOptions.delimiter || '';\r\n const format = this._exportOptions.format || '';\r\n const groupByColumnHeader = this._exportOptions.groupingColumnHeaderTitle || this.translate.instant('GROUP_BY');\r\n\r\n // a CSV needs double quotes wrapper, the other types do not need any wrapper\r\n this._exportQuoteWrapper = (format === FileType.csv) ? '\"' : '';\r\n\r\n // data variable which will hold all the fields data of a row\r\n let outputDataString = '';\r\n\r\n // get grouped column titles and if found, we will add a \"Group by\" column at the first column index\r\n const grouping = this._dataView.getGrouping();\r\n if (grouping && Array.isArray(grouping) && grouping.length > 0) {\r\n this._hasGroupedItems = true;\r\n outputDataString += `${groupByColumnHeader}` + delimiter;\r\n } else {\r\n this._hasGroupedItems = false;\r\n }\r\n\r\n // get all column headers\r\n this._columnHeaders = this.getColumnHeaders(columns) || [];\r\n if (this._columnHeaders && Array.isArray(this._columnHeaders) && this._columnHeaders.length > 0) {\r\n // add the header row + add a new line at the end of the row\r\n const outputHeaderTitles = this._columnHeaders.map((header) => {\r\n return this._exportQuoteWrapper + header.title + this._exportQuoteWrapper;\r\n });\r\n outputDataString += (outputHeaderTitles.join(delimiter) + this._lineCarriageReturn);\r\n }\r\n\r\n // Populate the rest of the Grid Data\r\n outputDataString += this.getAllGridRowData(columns, this._lineCarriageReturn);\r\n\r\n return outputDataString;\r\n }\r\n\r\n /**\r\n * Get all the grid row data and return that as an output string\r\n */\r\n getAllGridRowData(columns: Column[], lineCarriageReturn: string): string {\r\n const outputDataStrings = [];\r\n const lineCount = this._dataView.getLength();\r\n\r\n // loop through all the grid rows of data\r\n for (let rowNumber = 0; rowNumber < lineCount; rowNumber++) {\r\n const itemObj = this._dataView.getItem(rowNumber);\r\n\r\n if (itemObj != null) {\r\n // Normal row (not grouped by anything) would have an ID which was predefined in the Grid Columns definition\r\n if (itemObj[this.datasetIdName] != null) {\r\n // get regular row item data\r\n outputDataStrings.push(this.readRegularRowData(columns, rowNumber, itemObj));\r\n } else if (this._hasGroupedItems && itemObj.__groupTotals === undefined) {\r\n // get the group row\r\n outputDataStrings.push(this.readGroupedTitleRow(itemObj));\r\n } else if (itemObj.__groupTotals) {\r\n // else if the row is a Group By and we have agreggators, then a property of '__groupTotals' would exist under that object\r\n outputDataStrings.push(this.readGroupedTotalRow(columns, itemObj));\r\n }\r\n }\r\n }\r\n\r\n return outputDataStrings.join(this._lineCarriageReturn);\r\n }\r\n\r\n /**\r\n * Get all header titles and their keys, translate the title when required.\r\n * @param columns of the grid\r\n */\r\n getColumnHeaders(columns: Column[]): ExportColumnHeader[] {\r\n if (!columns || !Array.isArray(columns) || columns.length === 0) {\r\n return null;\r\n }\r\n const columnHeaders = [];\r\n\r\n // Populate the Column Header, pull the name defined\r\n columns.forEach((columnDef) => {\r\n const fieldName = (columnDef.headerKey) ? this.translate.instant(columnDef.headerKey) : columnDef.name;\r\n const skippedField = columnDef.excludeFromExport || false;\r\n\r\n // if column width is 0 then it's not evaluated since that field is considered hidden should not be part of the export\r\n if ((columnDef.width === undefined || columnDef.width > 0) && !skippedField) {\r\n columnHeaders.push({\r\n key: columnDef.field || columnDef.id,\r\n title: fieldName\r\n });\r\n }\r\n });\r\n\r\n return columnHeaders;\r\n }\r\n\r\n /**\r\n * Get the data of a regular row (a row without grouping)\r\n * @param row\r\n * @param itemObj\r\n */\r\n readRegularRowData(columns: Column[], row: number, itemObj: any) {\r\n let idx = 0;\r\n const rowOutputStrings = [];\r\n const delimiter = this._exportOptions.delimiter;\r\n const format = this._exportOptions.format;\r\n const exportQuoteWrapper = this._exportQuoteWrapper || '';\r\n\r\n for (let col = 0, ln = columns.length; col < ln; col++) {\r\n const columnDef = columns[col];\r\n const fieldId = columnDef.field || columnDef.id || '';\r\n\r\n // skip excluded column\r\n if (columnDef.excludeFromExport) {\r\n continue;\r\n }\r\n\r\n // if we are grouping and are on 1st column index, we need to skip this column since it will be used later by the grouping text:: Group by [columnX]\r\n if (this._hasGroupedItems && idx === 0) {\r\n rowOutputStrings.push(`\"\"`);\r\n }\r\n\r\n // does the user want to evaluate current column Formatter?\r\n const isEvaluatingFormatter = (columnDef.exportWithFormatter !== undefined) ? columnDef.exportWithFormatter : this._exportOptions.exportWithFormatter;\r\n\r\n // did the user provide a Custom Formatter for the export\r\n const exportCustomFormatter: Formatter | undefined = (columnDef.exportCustomFormatter !== undefined) ? columnDef.exportCustomFormatter : undefined;\r\n\r\n let itemData = '';\r\n\r\n if (itemObj && itemObj[fieldId] && exportCustomFormatter !== undefined && exportCustomFormatter !== null) {\r\n const formattedData = exportCustomFormatter(row, col, itemObj[fieldId], columnDef, itemObj, this._grid);\r\n itemData = formattedData as string;\r\n if (formattedData && typeof formattedData === 'object' && formattedData.hasOwnProperty('text')) {\r\n itemData = formattedData.text;\r\n }\r\n if (itemData === null) {\r\n itemData = '';\r\n }\r\n } else if (isEvaluatingFormatter && columnDef.formatter !== undefined && columnDef.formatter !== null) {\r\n const formattedData = columnDef.formatter(row, col, itemObj[fieldId], columnDef, itemObj, this._grid);\r\n itemData = formattedData as string;\r\n if (formattedData && typeof formattedData === 'object' && formattedData.hasOwnProperty('text')) {\r\n itemData = formattedData.text;\r\n }\r\n if (itemData === null) {\r\n itemData = '';\r\n }\r\n } else {\r\n itemData = (itemObj[fieldId] === null || itemObj[fieldId] === undefined) ? '' : itemObj[fieldId];\r\n if (itemData === null) {\r\n itemData = '';\r\n }\r\n }\r\n\r\n // does the user want to sanitize the output data (remove HTML tags)?\r\n if (columnDef.sanitizeDataExport || this._exportOptions.sanitizeDataExport) {\r\n itemData = sanitizeHtmlToText(itemData);\r\n }\r\n\r\n // when CSV we also need to escape double quotes twice, so \" becomes \"\"\r\n if (format === FileType.csv && itemData) {\r\n itemData = itemData.toString().replace(/\"/gi, `\"\"`);\r\n }\r\n\r\n // do we have a wrapper to keep as a string? in certain cases like \"1E06\", we don't want excel to transform it into exponential (1.0E06)\r\n // to cancel that effect we can had = in front, ex: =\"1E06\"\r\n const keepAsStringWrapper = (columnDef && columnDef.exportCsvForceToKeepAsString) ? '=' : '';\r\n\r\n rowOutputStrings.push(keepAsStringWrapper + exportQuoteWrapper + itemData + exportQuoteWrapper);\r\n idx++;\r\n }\r\n\r\n return rowOutputStrings.join(delimiter);\r\n }\r\n\r\n /**\r\n * Get the grouped title(s), for example if we grouped by salesRep, the returned result would be:: 'Sales Rep'\r\n * @param itemObj\r\n */\r\n readGroupedTitleRow(itemObj: any) {\r\n let groupName = sanitizeHtmlToText(itemObj.title);\r\n const exportQuoteWrapper = this._exportQuoteWrapper || '';\r\n const format = this._exportOptions.format;\r\n\r\n groupName = addWhiteSpaces(5 * itemObj.level) + groupName;\r\n\r\n if (format === FileType.csv) {\r\n // when CSV we also need to escape double quotes twice, so \" becomes \"\"\r\n groupName = groupName.toString().replace(/\"/gi, `\"\"`);\r\n }\r\n return exportQuoteWrapper + ' ' + groupName + exportQuoteWrapper;\r\n }\r\n\r\n /**\r\n * Get the grouped totals, these are set by Slick Aggregators.\r\n * For example if we grouped by \"salesRep\" and we have a Sum Aggregator on \"sales\", then the returned output would be:: [\"Sum 123$\"]\r\n * @param itemObj\r\n */\r\n readGroupedTotalRow(columns: Column[], itemObj: any) {\r\n const delimiter = this._exportOptions.delimiter;\r\n const format = this._exportOptions.format;\r\n const groupingAggregatorRowText = this._exportOptions.groupingAggregatorRowText || '';\r\n const exportQuoteWrapper = this._exportQuoteWrapper || '';\r\n const outputStrings = [`${exportQuoteWrapper}${groupingAggregatorRowText}${exportQuoteWrapper}`];\r\n\r\n columns.forEach((columnDef) => {\r\n let itemData = '';\r\n\r\n // if there's a groupTotalsFormatter, we will re-run it to get the exact same output as what is shown in UI\r\n if (columnDef.groupTotalsFormatter) {\r\n itemData = columnDef.groupTotalsFormatter(itemObj, columnDef);\r\n }\r\n\r\n // does the user want to sanitize the output data (remove HTML tags)?\r\n if (columnDef.sanitizeDataExport || this._exportOptions.sanitizeDataExport) {\r\n itemData = sanitizeHtmlToText(itemData);\r\n }\r\n\r\n if (format === FileType.csv) {\r\n // when CSV we also need to escape double quotes twice, so a double quote \" becomes 2x double quotes \"\"\r\n itemData = itemData.toString().replace(/\"/gi, `\"\"`);\r\n }\r\n outputStrings.push(exportQuoteWrapper + itemData + exportQuoteWrapper);\r\n });\r\n\r\n return outputStrings.join(delimiter);\r\n }\r\n\r\n /**\r\n * Triggers download file with file format.\r\n * IE(6-10) are not supported\r\n * All other browsers will use plain javascript on client side to produce a file download.\r\n * @param options\r\n */\r\n startDownloadFile(options: { filename: string, csvContent: any, format: FileType | string, useUtf8WithBom: boolean }): void {\r\n // IE(6-10) don't support javascript download and our service doesn't support either so throw an error, we have to make a round trip to the Web Server for exporting\r\n if (navigator.appName === 'Microsoft Internet Explorer') {\r\n throw new Error('Microsoft Internet Explorer 6 to 10 do not support javascript export to CSV. Please upgrade your browser.');\r\n }\r\n\r\n // set the correct MIME type\r\n const mimeType = (options.format === FileType.csv) ? 'text/csv' : 'text/plain';\r\n\r\n // make sure no html entities exist in the data\r\n const csvContent = htmlEntityDecode(options.csvContent);\r\n\r\n // dealing with Excel CSV export and UTF-8 is a little tricky.. We will use Option #2 to cover older Excel versions\r\n // Option #1: we need to make Excel knowing that it's dealing with an UTF-8, A correctly formatted UTF8 file can have a Byte Order Mark as its first three octets\r\n // reference: http://stackoverflow.com/questions/155097/microsoft-excel-mangles-diacritics-in-csv-files\r\n // Option#2: use a 3rd party extension to javascript encode into UTF-16\r\n let outputData: Uint8Array | string;\r\n if (options.format === FileType.csv) {\r\n outputData = new TextEncoder('utf-8').encode(csvContent);\r\n } else {\r\n outputData = csvContent;\r\n }\r\n\r\n // create a Blob object for the download\r\n const blob = new Blob([options.useUtf8WithBom ? '\\uFEFF' : '', outputData], {\r\n type: `${mimeType};charset=utf-8;`\r\n });\r\n\r\n // when using IE/Edge, then use different download call\r\n if (typeof navigator.msSaveOrOpenBlob === 'function') {\r\n navigator.msSaveOrOpenBlob(blob, options.filename);\r\n } else {\r\n // this trick will generate a temp <a /> tag\r\n // the code will then trigger a hidden click for it to start downloading\r\n const link = document.createElement('a');\r\n const csvUrl = URL.createObjectURL(blob);\r\n\r\n link.textContent = 'download';\r\n link.href = csvUrl;\r\n link.setAttribute('download', options.filename);\r\n\r\n // set the visibility to hidden so there is no effect on your web-layout\r\n link.style.visibility = 'hidden';\r\n\r\n // this part will append the anchor tag, trigger a click (for download to start) and finally remove the tag once completed\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n }\r\n }\r\n}\r\n","export class Constants {\r\n static TEXT_CANCEL = 'Cancel';\r\n static TEXT_CLEAR_ALL_FILTERS = 'Clear All Filters';\r\n static TEXT_CLEAR_ALL_SORTING = 'Clear All Sorting';\r\n static TEXT_COLUMNS = 'Columns';\r\n static TEXT_COMMANDS = 'Commands';\r\n static TEXT_EXPORT_IN_CSV_FORMAT = 'Export in CSV format';\r\n static TEXT_EXPORT_IN_TEXT_FORMAT = 'Export in Text format (Tab delimited)';\r\n static TEXT_FORCE_FIT_COLUMNS = 'Force fit columns';\r\n static TEXT_HIDE_COLUMN = 'Hide Column';\r\n static TEXT_REFRESH_DATASET = 'Refresh Dataset';\r\n static TEXT_REMOVE_FILTER = 'Remove Filter';\r\n static TEXT_REMOVE_SORT = 'Remove Sort';\r\n static TEXT_SAVE = 'Save';\r\n static TEXT_SYNCHRONOUS_RESIZE = 'Synchronous resize';\r\n static TEXT_SORT_ASCENDING = 'Sort Ascending';\r\n static TEXT_SORT_DESCENDING = 'Sort Descending';\r\n static TEXT_TOGGLE_FILTER_ROW = 'Toggle Filter Row';\r\n static TEXT_TOGGLE_PRE_HEADER_ROW = 'Toggle Pre-Header Row';\r\n static VALIDATION_REQUIRED_FIELD = 'Field is required';\r\n static VALIDATION_EDITOR_VALID_NUMBER = 'Please enter a valid number';\r\n static VALIDATION_EDITOR_VALID_INTEGER = 'Please enter a valid integer number';\r\n static VALIDATION_EDITOR_INTEGER_BETWEEN = 'Please enter a valid integer number between {{minValue}} and {{maxValue}}';\r\n static VALIDATION_EDITOR_INTEGER_MAX = 'Please enter a valid integer number that is lower than {{maxValue}}';\r\n static VALIDATION_EDITOR_INTEGER_MIN = 'Please enter a valid integer number that is greater than {{minValue}}';\r\n static VALIDATION_EDITOR_NUMBER_BETWEEN = 'Please enter a valid number between {{minValue}} and {{maxValue}}';\r\n static VALIDATION_EDITOR_NUMBER_MAX = 'Please enter a valid number that is lower than {{maxValue}}';\r\n static VALIDATION_EDITOR_NUMBER_MIN = 'Please enter a valid number that is greater than {{minValue}}';\r\n static VALIDATION_EDITOR_DECIMAL_BETWEEN = 'Please enter a valid number with a maximum of {{maxDecimal}} decimals';\r\n}\r\n","import { Column, GridOption } from '../models';\r\n\r\nexport class SharedService {\r\n private _allColumns: Column[];\r\n private _dataView: any;\r\n private _groupItemMetadataProvider: any;\r\n private _grid: any;\r\n private _gridOptions: GridOption;\r\n private _visibleColumns: Column[];\r\n\r\n // --\r\n // public\r\n\r\n /** Getter for All Columns in the grid (hidden/visible) */\r\n get allColumns(): Column[] {\r\n return this._allColumns;\r\n }\r\n /** Setter for All Columns in the grid (hidden/visible) */\r\n set allColumns(allColumns: Column[]) {\r\n this._allColumns = allColumns;\r\n }\r\n\r\n /** Getter for the Column Definitions pulled through the Grid Object */\r\n get columnDefinitions(): Column[] {\r\n return (this._grid && this._grid.getColumns) ? this._grid.getColumns() : [];\r\n }\r\n\r\n /** Getter for SlickGrid DataView object */\r\n get dataView(): any {\r\n return this._dataView;\r\n }\r\n /** Setter for SlickGrid DataView object */\r\n set dataView(dataView: any) {\r\n this._dataView = dataView;\r\n }\r\n\r\n /** Getter for SlickGrid Grid object */\r\n get grid(): any {\r\n return this._grid;\r\n }\r\n /** Setter for SlickGrid Grid object */\r\n set grid(grid: any) {\r\n this._grid = grid;\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n get gridOptions(): GridOption {\r\n return this._gridOptions || this._grid && this._grid.getOptions && this._grid.getOptions() || {};\r\n }\r\n\r\n /** Setter for the Grid Options pulled through the Grid Object */\r\n set gridOptions(gridOptions: GridOption) {\r\n this._gridOptions = gridOptions;\r\n }\r\n\r\n /** Getter for the Grid Options */\r\n get groupItemMetadataProvider(): any {\r\n return this._groupItemMetadataProvider;\r\n }\r\n /** Setter for the Grid Options */\r\n set groupItemMetadataProvider(groupItemMetadataProvider: any) {\r\n this._groupItemMetadataProvider = groupItemMetadataProvider;\r\n }\r\n\r\n /** Getter for the Visible Columns in the grid */\r\n get visibleColumns(): Column[] {\r\n return this._visibleColumns;\r\n }\r\n /** Setter for the Visible Columns in the grid */\r\n set visibleColumns(visibleColumns: Column[]) {\r\n this._visibleColumns = visibleColumns;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport { Constants } from '../constants';\r\nimport { ExtensionName } from '../models/index';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\ndeclare function require(name: string);\r\n\r\n@Injectable()\r\nexport class ExtensionUtility {\r\n constructor(private sharedService: SharedService, private translate: TranslateService) { }\r\n\r\n /**\r\n * Remove a column from the grid by it's index in the grid\r\n * @param array input\r\n * @param index\r\n */\r\n arrayRemoveItemByIndex(array: any[], index: number) {\r\n return array.filter((el: any, i: number) => index !== i);\r\n }\r\n\r\n /**\r\n * Load SlickGrid Extension (Control/Plugin) dynamically (on demand)\r\n * This will basically only load the extension when user enables the feature\r\n * @param extensionName\r\n */\r\n loadExtensionDynamically(extensionName: ExtensionName): any {\r\n try {\r\n switch (extensionName) {\r\n case ExtensionName.autoTooltip:\r\n require('slickgrid/plugins/slick.autotooltips');\r\n break;\r\n case ExtensionName.cellExternalCopyManager:\r\n require('slickgrid/plugins/slick.cellexternalcopymanager');\r\n break;\r\n case ExtensionName.checkboxSelector:\r\n require('slickgrid/plugins/slick.checkboxselectcolumn');\r\n break;\r\n case ExtensionName.columnPicker:\r\n require('slickgrid/controls/slick.columnpicker');\r\n break;\r\n case ExtensionName.draggableGrouping:\r\n require('slickgrid/plugins/slick.draggablegrouping');\r\n break;\r\n case ExtensionName.gridMenu:\r\n require('slickgrid/controls/slick.gridmenu');\r\n break;\r\n case ExtensionName.groupItemMetaProvider:\r\n require('slickgrid/slick.groupitemmetadataprovider');\r\n break;\r\n case ExtensionName.headerButton:\r\n require('slickgrid/plugins/slick.headerbuttons');\r\n break;\r\n case ExtensionName.headerMenu:\r\n require('slickgrid/plugins/slick.headermenu');\r\n break;\r\n case ExtensionName.rowSelection:\r\n require('slickgrid/plugins/slick.rowselectionmodel');\r\n break;\r\n case ExtensionName.rowDetailView:\r\n require('slickgrid/plugins/slick.rowdetailview');\r\n break;\r\n case ExtensionName.rowMoveManager:\r\n require('slickgrid/plugins/slick.rowmovemanager');\r\n break;\r\n }\r\n } catch (e) {\r\n // do nothing, we fall here when using Angular and RequireJS\r\n }\r\n }\r\n\r\n /**\r\n * From a Grid Menu object property name, we will return the correct title output string following this order\r\n * 1- if user provided a title, use it as the output title\r\n * 2- else if user provided a title key, use it to translate the output title\r\n * 3- else if nothing is provided use\r\n */\r\n getPickerTitleOutputString(propName: string, pickerName: 'gridMenu' | 'columnPicker') {\r\n let output = '';\r\n const picker = this.sharedService.gridOptions && this.sharedService.gridOptions[pickerName] || {};\r\n const enableTranslate = this.sharedService.gridOptions && this.sharedService.gridOptions.enableTranslate || false;\r\n\r\n const title = picker && picker[propName];\r\n const titleKey = picker && picker[`${propName}Key`];\r\n\r\n if (titleKey) {\r\n output = this.translate.instant(titleKey || ' ');\r\n } else {\r\n switch (propName) {\r\n case 'customTitle':\r\n output = title || (enableTranslate ? this.translate.instant('COMMANDS') : Constants.TEXT_COMMANDS);\r\n break;\r\n case 'columnTitle':\r\n output = title || (enableTranslate ? this.translate.instant('COLUMNS') : Constants.TEXT_COLUMNS);\r\n break;\r\n case 'forceFitTitle':\r\n output = title || (enableTranslate ? this.translate.instant('FORCE_FIT_COLUMNS') : Constants.TEXT_FORCE_FIT_COLUMNS);\r\n break;\r\n case 'syncResizeTitle':\r\n output = title || (enableTranslate ? this.translate.instant('SYNCHRONOUS_RESIZE') : Constants.TEXT_SYNCHRONOUS_RESIZE);\r\n break;\r\n default:\r\n output = title;\r\n break;\r\n }\r\n }\r\n return output;\r\n }\r\n\r\n /**\r\n * Sort items (by pointers) in an array by a property name\r\n * @params items array\r\n * @param property name to sort with\r\n */\r\n sortItems(items: any[], propertyName: string) {\r\n // sort the custom items by their position in the list\r\n items.sort((itemA: any, itemB: any) => {\r\n if (itemA && itemB && itemA.hasOwnProperty(propertyName) && itemB.hasOwnProperty(propertyName)) {\r\n return itemA[propertyName] - itemB[propertyName];\r\n }\r\n return -1;\r\n });\r\n }\r\n\r\n /** Translate the an array of items from an input key and assign to the output key */\r\n translateItems(items: any[], inputKey: string, outputKey: string) {\r\n if (Array.isArray(items)) {\r\n for (const item of items) {\r\n if (item[inputKey]) {\r\n item[outputKey] = this.translate.instant(item[inputKey]);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Extension, ExtensionName } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class AutoTooltipExtension implements Extension {\r\n private _addon: any;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) { }\r\n\r\n dispose() {\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.autoTooltip);\r\n this._addon = new Slick.AutoTooltips(this.sharedService.gridOptions.autoTooltipOptions || {});\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport {\r\n Column,\r\n EditCommand,\r\n EditUndoRedoBuffer,\r\n ExcelCopyBufferOption,\r\n Extension,\r\n ExtensionName,\r\n SelectedRange,\r\n SlickEventHandler,\r\n} from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { sanitizeHtmlToText } from '../services/utilities';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\ndeclare var $: any;\r\n\r\n@Injectable()\r\nexport class CellExternalCopyManagerExtension implements Extension {\r\n private _addon: any;\r\n private _addonOptions: ExcelCopyBufferOption;\r\n private _eventHandler: SlickEventHandler;\r\n private _commandQueue: EditCommand[];\r\n private _undoRedoBuffer: EditUndoRedoBuffer;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get addonOptions(): ExcelCopyBufferOption {\r\n return this._addonOptions;\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n get commandQueue(): EditCommand[] {\r\n return this._commandQueue;\r\n }\r\n\r\n get undoRedoBuffer(): EditUndoRedoBuffer {\r\n return this._undoRedoBuffer;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.cellExternalCopyManager);\r\n this.createUndoRedoBuffer();\r\n this.hookUndoShortcutKey();\r\n\r\n this._addonOptions = { ...this.getDefaultOptions(), ...this.sharedService.gridOptions.excelCopyBufferOptions } as ExcelCopyBufferOption;\r\n this.sharedService.grid.setSelectionModel(new Slick.CellSelectionModel());\r\n this._addon = new Slick.CellExternalCopyManager(this._addonOptions);\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // hook to all possible events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.excelCopyBufferOptions) {\r\n if (this.sharedService.gridOptions.excelCopyBufferOptions.onExtensionRegistered) {\r\n this.sharedService.gridOptions.excelCopyBufferOptions.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onCopyCells, (e: any, args: { ranges: SelectedRange[] }) => {\r\n if (this.sharedService.gridOptions.excelCopyBufferOptions && typeof this.sharedService.gridOptions.excelCopyBufferOptions.onCopyCells === 'function') {\r\n this.sharedService.gridOptions.excelCopyBufferOptions.onCopyCells(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onCopyCancelled, (e: any, args: { ranges: SelectedRange[] }) => {\r\n if (this.sharedService.gridOptions.excelCopyBufferOptions && typeof this.sharedService.gridOptions.excelCopyBufferOptions.onCopyCancelled === 'function') {\r\n this.sharedService.gridOptions.excelCopyBufferOptions.onCopyCancelled(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onPasteCells, (e: any, args: { ranges: SelectedRange[] }) => {\r\n if (this.sharedService.gridOptions.excelCopyBufferOptions && typeof this.sharedService.gridOptions.excelCopyBufferOptions.onPasteCells === 'function') {\r\n this.sharedService.gridOptions.excelCopyBufferOptions.onPasteCells(e, args);\r\n }\r\n });\r\n }\r\n\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n /** Create an undo redo buffer used by the Excel like copy */\r\n private createUndoRedoBuffer() {\r\n let commandCtr = 0;\r\n this._commandQueue = [];\r\n\r\n this._undoRedoBuffer = {\r\n queueAndExecuteCommand: (editCommand: EditCommand) => {\r\n this._commandQueue[commandCtr] = editCommand;\r\n commandCtr++;\r\n editCommand.execute();\r\n },\r\n undo: () => {\r\n if (commandCtr === 0) {\r\n return;\r\n }\r\n commandCtr--;\r\n const command = this._commandQueue[commandCtr];\r\n if (command && Slick.GlobalEditorLock.cancelCurrentEdit()) {\r\n command.undo();\r\n }\r\n },\r\n redo: () => {\r\n if (commandCtr >= this._commandQueue.length) {\r\n return;\r\n }\r\n const command = this._commandQueue[commandCtr];\r\n commandCtr++;\r\n if (command && Slick.GlobalEditorLock.cancelCurrentEdit()) {\r\n command.execute();\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** @return default plugin (addon) options */\r\n private getDefaultOptions(): ExcelCopyBufferOption {\r\n let newRowIds = 0;\r\n\r\n return {\r\n clipboardCommandHandler: (editCommand: any) => {\r\n this._undoRedoBuffer.queueAndExecuteCommand.call(this._undoRedoBuffer, editCommand);\r\n },\r\n dataItemColumnValueExtractor: (item: any, columnDef: Column) => {\r\n // when grid or cell is not editable, we will possibly evaluate the Formatter if it was passed\r\n // to decide if we evaluate the Formatter, we will use the same flag from Export which is \"exportWithFormatter\"\r\n if (!this.sharedService.gridOptions.editable || !columnDef.editor) {\r\n const isEvaluatingFormatter = (columnDef.exportWithFormatter !== undefined) ? columnDef.exportWithFormatter : (this.sharedService.gridOptions.exportOptions && this.sharedService.gridOptions.exportOptions.exportWithFormatter);\r\n if (columnDef.formatter && isEvaluatingFormatter) {\r\n const formattedOutput = columnDef.formatter(0, 0, item[columnDef.field], columnDef, item, this.sharedService.grid);\r\n if (columnDef.sanitizeDataExport || (this.sharedService.gridOptions.exportOptions && this.sharedService.gridOptions.exportOptions.sanitizeDataExport)) {\r\n let outputString = formattedOutput as string;\r\n if (formattedOutput && typeof formattedOutput === 'object' && formattedOutput.hasOwnProperty('text')) {\r\n outputString = formattedOutput.text;\r\n }\r\n if (outputString === null) {\r\n outputString = '';\r\n }\r\n return sanitizeHtmlToText(outputString);\r\n }\r\n return formattedOutput;\r\n }\r\n }\r\n // else use the default \"dataItemColumnValueExtractor\" from the plugin itself\r\n // we can do that by setting back the getter with null\r\n return null;\r\n },\r\n readOnlyMode: false,\r\n includeHeaderWhenCopying: false,\r\n newRowCreator: (count: number) => {\r\n for (let i = 0; i < count; i++) {\r\n const item = {\r\n id: 'newRow_' + newRowIds++\r\n };\r\n this.sharedService.grid.getData().addItem(item);\r\n }\r\n }\r\n };\r\n }\r\n\r\n /** Hook an undo shortcut key hook that will redo/undo the copy buffer using Ctrl+(Shift)+Z keyboard events */\r\n private hookUndoShortcutKey() {\r\n document.addEventListener('keydown', (e: KeyboardEvent) => {\r\n const keyCode = e.keyCode || e.code;\r\n if (keyCode === 90 && (e.ctrlKey || e.metaKey)) {\r\n if (e.shiftKey) {\r\n this._undoRedoBuffer.redo(); // Ctrl + Shift + Z\r\n } else {\r\n this._undoRedoBuffer.undo(); // Ctrl + Z\r\n }\r\n }\r\n });\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Column, Extension, ExtensionName, GridOption } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class CheckboxSelectorExtension implements Extension {\r\n private _addon: any;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) { }\r\n\r\n dispose() {\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n /**\r\n * Create the plugin before the Grid creation, else it will behave oddly.\r\n * Mostly because the column definitions might change after the grid creation\r\n */\r\n create(columnDefinitions: Column[], gridOptions: GridOption) {\r\n if (Array.isArray(columnDefinitions) && gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.checkboxSelector);\r\n if (!this._addon) {\r\n this._addon = new Slick.CheckboxSelectColumn(gridOptions.checkboxSelector || {});\r\n }\r\n const selectionColumn: Column = this._addon.getColumnDefinition();\r\n if (typeof selectionColumn === 'object') {\r\n selectionColumn.excludeFromExport = true;\r\n selectionColumn.excludeFromColumnPicker = true;\r\n selectionColumn.excludeFromGridMenu = true;\r\n selectionColumn.excludeFromQuery = true;\r\n selectionColumn.excludeFromHeaderMenu = true;\r\n columnDefinitions.unshift(selectionColumn);\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n register(rowSelectionPlugin?: any) {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // the plugin has to be created BEFORE the grid (else it behaves oddly), but we can only watch grid events AFTER the grid is created\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // this also requires the Row Selection Model to be registered as well\r\n if (!rowSelectionPlugin || !this.sharedService.grid.getSelectionModel()) {\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.rowSelection);\r\n rowSelectionPlugin = new Slick.RowSelectionModel(this.sharedService.gridOptions.rowSelectionOptions || {});\r\n this.sharedService.grid.setSelectionModel(rowSelectionPlugin);\r\n }\r\n\r\n // user might want to pre-select some rows\r\n // the setTimeout is because of timing issue with styling (row selection happen but rows aren't highlighted properly)\r\n if (this.sharedService.gridOptions.preselectedRows && rowSelectionPlugin && this.sharedService.grid.getSelectionModel()) {\r\n setTimeout(() => this._addon.selectRows(this.sharedService.gridOptions.preselectedRows), 0);\r\n }\r\n\r\n return rowSelectionPlugin;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { CellArgs, Extension, ExtensionName, SlickEventHandler } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class ColumnPickerExtension implements Extension {\r\n private _eventHandler: SlickEventHandler;\r\n private _addon: any;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.columnPicker);\r\n\r\n // localization support for the picker\r\n const columnTitle = this.extensionUtility.getPickerTitleOutputString('columnTitle', 'columnPicker');\r\n const forceFitTitle = this.extensionUtility.getPickerTitleOutputString('forceFitTitle', 'columnPicker');\r\n const syncResizeTitle = this.extensionUtility.getPickerTitleOutputString('syncResizeTitle', 'columnPicker');\r\n\r\n this.sharedService.gridOptions.columnPicker = this.sharedService.gridOptions.columnPicker || {};\r\n this.sharedService.gridOptions.columnPicker.columnTitle = this.sharedService.gridOptions.columnPicker.columnTitle || columnTitle;\r\n this.sharedService.gridOptions.columnPicker.forceFitTitle = this.sharedService.gridOptions.columnPicker.forceFitTitle || forceFitTitle;\r\n this.sharedService.gridOptions.columnPicker.syncResizeTitle = this.sharedService.gridOptions.columnPicker.syncResizeTitle || syncResizeTitle;\r\n this._addon = new Slick.Controls.ColumnPicker(this.sharedService.columnDefinitions, this.sharedService.grid, this.sharedService.gridOptions);\r\n\r\n if (this.sharedService.grid && this.sharedService.gridOptions.enableColumnPicker) {\r\n if (this.sharedService.gridOptions.columnPicker.onExtensionRegistered) {\r\n this.sharedService.gridOptions.columnPicker.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onColumnsChanged, (e: any, args: CellArgs) => {\r\n if (this.sharedService.gridOptions.columnPicker && typeof this.sharedService.gridOptions.columnPicker.onColumnsChanged === 'function') {\r\n this.sharedService.gridOptions.columnPicker.onColumnsChanged(e, args);\r\n }\r\n });\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n /** Translate the Column Picker headers and also the last 2 checkboxes */\r\n translateColumnPicker() {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // update the properties by pointers, that is the only way to get Column Picker Control to see the new values\r\n if (this.sharedService.gridOptions.columnPicker) {\r\n this.emptyColumnPickerTitles();\r\n this.sharedService.gridOptions.columnPicker.columnTitle = this.extensionUtility.getPickerTitleOutputString('columnTitle', 'columnPicker');\r\n this.sharedService.gridOptions.columnPicker.forceFitTitle = this.extensionUtility.getPickerTitleOutputString('forceFitTitle', 'columnPicker');\r\n this.sharedService.gridOptions.columnPicker.syncResizeTitle = this.extensionUtility.getPickerTitleOutputString('syncResizeTitle', 'columnPicker');\r\n }\r\n\r\n // translate all columns (including hidden columns)\r\n this.extensionUtility.translateItems(this.sharedService.allColumns, 'headerKey', 'name');\r\n\r\n // re-initialize the Column Picker, that will recreate all the list\r\n // doing an \"init()\" won't drop any existing command attached\r\n if (this._addon.init) {\r\n this._addon.init(this.sharedService.grid);\r\n }\r\n }\r\n }\r\n\r\n private emptyColumnPickerTitles() {\r\n if (this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.columnPicker) {\r\n this.sharedService.gridOptions.columnPicker.columnTitle = '';\r\n this.sharedService.gridOptions.columnPicker.forceFitTitle = '';\r\n this.sharedService.gridOptions.columnPicker.syncResizeTitle = '';\r\n }\r\n }\r\n}\r\n","\r\nimport { SharedService } from '../services/shared.service';\r\nimport { Extension, ExtensionName, GridOption, Grouping, SlickEventHandler } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { Injectable } from '@angular/core';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class DraggableGroupingExtension implements Extension {\r\n private _eventHandler: SlickEventHandler;\r\n private _addon: any;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n /**\r\n * Bind/Create different plugins before the Grid creation.\r\n * For example the multi-select have to be added to the column definition before the grid is created to work properly\r\n */\r\n create(gridOptions: GridOption) {\r\n if (gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.draggableGrouping);\r\n\r\n if (!this._addon) {\r\n this._addon = new Slick.DraggableGrouping(gridOptions.draggableGrouping || {});\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // Events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.draggableGrouping) {\r\n if (this.sharedService.gridOptions.draggableGrouping.onExtensionRegistered) {\r\n this.sharedService.gridOptions.draggableGrouping.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onGroupChanged, (e: any, args: { caller?: string; groupColumns: Grouping[] }) => {\r\n if (this.sharedService.gridOptions.draggableGrouping && typeof this.sharedService.gridOptions.draggableGrouping.onGroupChanged === 'function') {\r\n this.sharedService.gridOptions.draggableGrouping.onGroupChanged(e, args);\r\n }\r\n });\r\n }\r\n\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { FilterCondition, FilterConditionOption } from './../models/index';\r\nimport { parseBoolean } from '../services/utilities';\r\n\r\nexport const booleanFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n return parseBoolean(options.cellValue) === parseBoolean(searchTerm);\r\n};\r\n","import { OperatorString } from '../models';\n\n/**\n * Compare 2 objects,\n * we will loop through all properties of the object to compare the entire content of both objects\n * Optionally we can compare by a property key, when that is provided we will compare the object content\n * @param o1\n * @param o2\n * @param compareKey optional\n */\nexport const compareObjects = (o1: any, o2: any, compareKey?: string) => {\n // if user provided an object compare key then compare directly both objects by that key\n if (compareKey && (o1.hasOwnProperty(compareKey) || o2.hasOwnProperty(compareKey))) {\n return o1[compareKey] === o2 || o1 === o2[compareKey] || o1[compareKey] === o2[compareKey];\n }\n\n // loop through all object properties to compare the full content of the object\n // we'll return false as soon as a difference is detected\n for (const p in o1) {\n if (o1.hasOwnProperty(p)) {\n if (o1[p] !== o2[p]) {\n return false;\n }\n }\n }\n return true;\n};\n\nexport const testFilterCondition = (operator: OperatorString, value1: any, value2: any): boolean => {\n switch (operator) {\n case '<':\n case 'LT': return (value1 < value2);\n case '<=':\n case 'LE': return (value1 <= value2);\n case '>':\n case 'GT': return (value1 > value2);\n case '>=':\n case 'GE': return (value1 >= value2);\n case '!=':\n case '<>':\n case 'NE': return (value1 !== value2);\n case '=':\n case '==':\n case 'EQ': return (value1 === value2);\n case 'IN': return ((value2 && value2.includes) ? (value2.includes(value1)) : false);\n case 'NIN':\n case 'NOT_IN':\n return ((value2 && value2.includes) ? (!value2.includes(value1)) : false);\n case 'IN_CONTAINS':\n if (value2 && Array.isArray(value2) && value2.findIndex) {\n return ((value2.findIndex((val) => value1.indexOf(val) > -1)) > -1);\n }\n return false;\n case 'NIN_CONTAINS':\n case 'NOT_IN_CONTAINS':\n if (value2 && Array.isArray(value2) && value2.findIndex) {\n return !((value2.findIndex((val) => value1.indexOf(val) > -1)) > -1);\n }\n return false;\n }\n return true;\n};\n","import { FieldType, FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { testFilterCondition } from './filterUtilities';\r\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateEuro);\r\n\r\nexport const dateEuroFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n if (searchTerm === null || searchTerm === '' || !moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerm, FORMAT, true).isValid()) {\r\n return false;\r\n }\r\n const dateCell = moment(options.cellValue, FORMAT, true);\r\n const dateSearch = moment(searchTerm, FORMAT, true);\r\n\r\n // run the filter condition with date in Unix Timestamp format\r\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\r\n};\r\n","import { FieldType, FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { testFilterCondition } from './filterUtilities';\r\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateEuroShort);\r\n\r\nexport const dateEuroShortFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n if (searchTerm === null || searchTerm === '' || !moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerm, FORMAT, true).isValid()) {\r\n return false;\r\n }\r\n const dateCell = moment(options.cellValue, FORMAT, true);\r\n const dateSearch = moment(searchTerm, FORMAT, true);\r\n\r\n // run the filter condition with date in Unix Timestamp format\r\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\r\n};\r\n","import { FieldType, FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { testFilterCondition } from './filterUtilities';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\n\r\nexport const dateFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n const filterSearchType = options.filterSearchType || FieldType.dateIso;\r\n const searchDateFormat = mapMomentDateFormatWithFieldType(filterSearchType);\r\n if (searchTerm === null || searchTerm === '' || !moment(options.cellValue, moment.ISO_8601).isValid() || !moment(searchTerm, searchDateFormat, true).isValid()) {\r\n return false;\r\n }\r\n const dateCell = moment(options.cellValue);\r\n const dateSearch = moment(searchTerm);\r\n\r\n // run the filter condition with date in Unix Timestamp format\r\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\r\n};\r\n","import { FieldType, FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { testFilterCondition } from './filterUtilities';\r\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateIso);\r\n\r\nexport const dateIsoFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n if (searchTerm === null || searchTerm === '' || !moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerm, FORMAT, true).isValid()) {\r\n return false;\r\n }\r\n const dateCell = moment(options.cellValue, FORMAT, true);\r\n const dateSearch = moment(searchTerm, FORMAT, true);\r\n\r\n // run the filter condition with date in Unix Timestamp format\r\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\r\n};\r\n","import { FieldType, FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { testFilterCondition } from './filterUtilities';\r\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateUs);\r\n\r\nexport const dateUsFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n if (searchTerm === null || searchTerm === '' || !moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerm, FORMAT, true).isValid()) {\r\n return false;\r\n }\r\n const dateCell = moment(options.cellValue, FORMAT, true);\r\n const dateSearch = moment(searchTerm, FORMAT, true);\r\n\r\n // run the filter condition with date in Unix Timestamp format\r\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\r\n};\r\n","import { FieldType, FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { testFilterCondition } from './filterUtilities';\r\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\nconst FORMAT = mapMomentDateFormatWithFieldType(FieldType.dateUsShort);\r\n\r\nexport const dateUsShortFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\r\n if (searchTerm === null || searchTerm === '' || !moment(options.cellValue, FORMAT, true).isValid() || !moment(searchTerm, FORMAT, true).isValid()) {\r\n return false;\r\n }\r\n const dateCell = moment(options.cellValue, FORMAT, true);\r\n const dateSearch = moment(searchTerm, FORMAT, true);\r\n\r\n // run the filter condition with date in Unix Timestamp format\r\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\r\n};\r\n","import { FilterCondition, FilterConditionOption } from '../models/index';\nimport { mapMomentDateFormatWithFieldType } from './../services/utilities';\nimport { testFilterCondition } from './filterUtilities';\nimport * as moment_ from 'moment-mini';\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\n\nexport const dateUtcFilterCondition: FilterCondition = (options: FilterConditionOption) => {\n const searchTerm = Array.isArray(options.searchTerms) && options.searchTerms[0] || '';\n const searchDateFormat = mapMomentDateFormatWithFieldType(options.filterSearchType || options.fieldType);\n if (!moment(options.cellValue, moment.ISO_8601).isValid() || !moment(searchTerm, searchDateFormat, true).isValid()) {\n return false;\n }\n const dateCell = moment(options.cellValue, moment.ISO_8601, true);\n const dateSearch = moment(searchTerm, searchDateFormat, true);\n\n // run the filter condition with date in Unix Timestamp format\n return testFilterCondition(options.operator || '==', parseInt(dateCell.format('X'), 10), parseInt(dateSearch.format('X'), 10));\n};\n","import { FilterCondition, FilterConditionOption } from '../models/index';\r\nimport { testFilterCondition } from './filterUtilities';\r\n\r\nexport const collectionSearchFilterCondition: FilterCondition = (options: FilterConditionOption) => {\r\n // multiple-select will always return text, so we should make our cell values text as well\r\n const cellValue = options.cellValue + '';\r\n\r\n return testFilterCondition(options.operator || 'IN', cellValue, options.searchTerms || []);\r\n};\r\n","import { FilterCondition, FilterConditionOption } from '../models/index';\nimport { testFilterCondition } from './filterUtilities';\n\nexport const numberFilterCondition: FilterCondition = (options: FilterConditionOption) => {\n const cellValue = parseFloat(options.cellValue);\n let searchTerm = (Array.isArray(options.searchTerms) && options.searchTerms[0]) || 0;\n if (typeof searchTerm === 'string') {\n searchTerm = parseFloat(searchTerm);\n }\n\n if (!searchTerm && !options.operator) {\n return true;\n }\n return testFilterCondition(options.operator || '==', cellValue, searchTerm);\n};\n","import { FilterCondition, FilterConditionOption } from '../models/index';\nimport { testFilterCondition } from './filterUtilities';\n\nexport const stringFilterCondition: FilterCondition = (options: FilterConditionOption) => {\n // make sure the cell value is a string by casting it when possible\n options.cellValue = (options.cellValue === undefined || options.cellValue === null) ? '' : options.cellValue.toString();\n\n // make both the cell value and search value lower for case insensitive comparison\n const cellValue = options.cellValue.toLowerCase();\n let searchTerm = (Array.isArray(options.searchTerms) && options.searchTerms[0]) || '';\n if (typeof searchTerm === 'string') {\n searchTerm = searchTerm.toLowerCase();\n }\n\n if (options.operator === '*' || options.operator === 'EndsWith') {\n return cellValue.endsWith(searchTerm);\n } else if ((options.operator === '' && options.cellValueLastChar === '*') || options.operator === 'StartsWith') {\n return cellValue.startsWith(searchTerm);\n } else if (options.operator === '') {\n return cellValue.includes(searchTerm);\n }\n return testFilterCondition(options.operator || '==', cellValue, searchTerm);\n};\n","import { booleanFilterCondition } from './booleanFilterCondition';\r\nimport { dateEuroShortFilterCondition } from './dateEuroShortFilterCondition';\r\nimport { dateEuroFilterCondition } from './dateEuroFilterCondition';\r\nimport { dateFilterCondition } from './dateFilterCondition';\r\nimport { dateIsoFilterCondition } from './dateIsoFilterCondition';\r\nimport { dateUsShortFilterCondition } from './dateUsShortFilterCondition';\r\nimport { dateUsFilterCondition } from './dateUsFilterCondition';\r\nimport { dateUtcFilterCondition } from './dateUtcFilterCondition';\r\nimport { FilterConditionOption } from './../models/filterConditionOption.interface';\r\nimport { FilterCondition } from '../models/filterCondition.interface';\r\nimport { collectionSearchFilterCondition } from './collectionSearchFilterCondition';\r\nimport { numberFilterCondition } from './numberFilterCondition';\r\nimport { objectFilterCondition } from './objectFilterCondition';\r\nimport { stringFilterCondition } from './stringFilterCondition';\r\nimport { FieldType } from '../models/index';\r\n\r\nexport const executeMappedCondition: FilterCondition = (options: FilterConditionOption) => {\r\n // when using a multi-select ('IN' operator) we will not use the field type but instead go directly with a collection search\r\n const operator = options && options.operator && options.operator.toUpperCase();\r\n if (operator === 'IN' || operator === 'NIN' || operator === 'IN_CONTAINS' || operator === 'NIN_CONTAINS') {\r\n return collectionSearchFilterCondition(options);\r\n }\r\n\r\n // execute the mapped type, or default to String condition check\r\n switch (options.fieldType) {\r\n case FieldType.boolean:\r\n return booleanFilterCondition(options);\r\n case FieldType.date:\r\n return dateFilterCondition(options);\r\n case FieldType.dateUtc:\r\n return dateUtcFilterCondition(options);\r\n case FieldType.dateIso:\r\n return dateIsoFilterCondition(options);\r\n // all Euro Formats (date/month/year)\r\n case FieldType.dateEuro:\r\n return dateEuroFilterCondition(options);\r\n case FieldType.dateEuroShort:\r\n return dateEuroShortFilterCondition(options);\r\n // all US Formats (month/date/year)\r\n case FieldType.dateUs:\r\n case FieldType.dateTimeUs:\r\n return dateUsFilterCondition(options);\r\n case FieldType.dateUsShort:\r\n case FieldType.dateTimeUsShort:\r\n return dateUsShortFilterCondition(options);\r\n case FieldType.number:\r\n return numberFilterCondition(options);\r\n case FieldType.object:\r\n return objectFilterCondition(options);\r\n case FieldType.string:\r\n default:\r\n return stringFilterCondition(options);\r\n }\r\n};\r\n","import { FilterCondition, FilterConditionOption } from '../models/index';\nimport { compareObjects } from './filterUtilities';\n\nexport const objectFilterCondition: FilterCondition = (options: FilterConditionOption) => {\n const searchTerm = (Array.isArray(options.searchTerms) && options.searchTerms[0] || '');\n\n if (!searchTerm && !options.operator) {\n return true;\n }\n\n switch (options.operator) {\n case '!=':\n case '<>':\n case 'NE':\n return !compareObjects(options.cellValue, searchTerm, options.dataKey);\n case '=':\n case '==':\n case 'EQ':\n default:\n return compareObjects(options.cellValue, searchTerm, options.dataKey);\n }\n};\n","import { FilterConditionOption } from './../models/filterConditionOption.interface';\r\nimport { booleanFilterCondition } from './booleanFilterCondition';\r\nimport { dateEuroFilterCondition } from './dateEuroFilterCondition';\r\nimport { dateEuroShortFilterCondition } from './dateEuroShortFilterCondition';\r\nimport { dateFilterCondition } from './dateFilterCondition';\r\nimport { dateIsoFilterCondition } from './dateIsoFilterCondition';\r\nimport { dateUsFilterCondition } from './dateUsFilterCondition';\r\nimport { dateUsShortFilterCondition } from './dateUsShortFilterCondition';\r\nimport { dateUtcFilterCondition } from './dateUtcFilterCondition';\r\nimport { executeMappedCondition } from './executeMappedCondition';\r\nimport { collectionSearchFilterCondition } from './collectionSearchFilterCondition';\r\nimport { numberFilterCondition } from './numberFilterCondition';\r\nimport { stringFilterCondition } from './stringFilterCondition';\r\nimport { testFilterCondition } from './filterUtilities';\r\n\r\nexport const FilterConditions = {\r\n executeMappedCondition,\r\n booleanFilter: booleanFilterCondition,\r\n collectionSearchFilter: collectionSearchFilterCondition,\r\n dateEuroFilter: dateEuroFilterCondition,\r\n dateEuroShortFilter: dateEuroShortFilterCondition,\r\n dateFilter: dateFilterCondition,\r\n dateIsoFilter: dateIsoFilterCondition,\r\n dateUtcFilter: dateUtcFilterCondition,\r\n dateUsFilter: dateUsFilterCondition,\r\n dateUsShortFilter: dateUsShortFilterCondition,\r\n numberFilter: numberFilterCondition,\r\n stringFilter: stringFilterCondition,\r\n testFilter: testFilterCondition\r\n};\r\n","import { Injectable } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport {\n CollectionCustomStructure,\n CollectionOption,\n Column,\n ColumnFilter,\n Filter,\n FilterArguments,\n FilterCallback,\n GridOption,\n OperatorType,\n OperatorString,\n SearchTerm\n} from './../models/index';\nimport { CollectionService } from '../services/collection.service';\nimport { getDescendantProperty, castToPromise } from '../services/utilities';\nimport { Subscription, Subject, Observable } from 'rxjs';\n\n// using external non-typed js libraries\ndeclare var $: any;\n\n@Injectable()\nexport class AutoCompleteFilter implements Filter {\n private _clearFilterTriggered = false;\n private _shouldTriggerQuery = true;\n\n /** DOM Element Name, useful for auto-detecting positioning (dropup / dropdown) */\n elementName: string;\n\n /** The JQuery DOM element */\n $filterElm: any;\n\n grid: any;\n searchTerms: SearchTerm[];\n columnDef: Column;\n callback: FilterCallback;\n isFilled = false;\n\n /** The property name for labels in the collection */\n labelName: string;\n\n /** The property name for values in the collection */\n optionLabel: string;\n\n /** The property name for values in the collection */\n valueName = 'label';\n\n enableTranslateLabel = false;\n subscriptions: Subscription[] = [];\n\n /**\n * Initialize the Filter\n */\n constructor(protected translate: TranslateService, protected collectionService: CollectionService) { }\n\n /** Getter for the Collection Options */\n protected get collectionOptions(): CollectionOption {\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.collectionOptions || {};\n }\n\n /** Getter for the Column Filter */\n get columnFilter(): ColumnFilter {\n return this.columnDef && this.columnDef.filter || {};\n }\n\n /** Getter for the Custom Structure if exist */\n get customStructure(): CollectionCustomStructure | undefined {\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.customStructure;\n }\n\n /** Getter for the Grid Options pulled through the Grid Object */\n get gridOptions(): GridOption {\n return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {};\n }\n\n /** Getter of the Operator to use when doing the filter comparing */\n get operator(): OperatorType | OperatorString {\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.operator || OperatorType.equal;\n }\n\n /**\n * Initialize the filter template\n */\n init(args: FilterArguments) {\n if (!args) {\n throw new Error('[Angular-SlickGrid] A filter must always have an \"init()\" with valid arguments.');\n }\n this.grid = args.grid;\n this.callback = args.callback;\n this.columnDef = args.columnDef;\n this.searchTerms = args.searchTerms || [];\n\n if (!this.grid || !this.columnDef || !this.columnFilter || (!this.columnFilter.collection && !this.columnFilter.collectionAsync && !this.columnFilter.filterOptions)) {\n throw new Error(`[Angular-SlickGrid] You need to pass a \"collection\" (or \"collectionAsync\") for the AutoComplete Filter to work correctly. Also each option should include a value/label pair (or value/labelKey when using Locale). For example:: { filter: model: Filters.autoComplete, collection: [{ value: true, label: 'True' }, { value: false, label: 'False'}] }`);\n }\n\n this.enableTranslateLabel = this.columnFilter && this.columnFilter.enableTranslateLabel || false;\n this.labelName = this.customStructure && this.customStructure.label || 'label';\n this.valueName = this.customStructure && this.customStructure.value || 'value';\n\n // always render the DOM element, even if user passed a \"collectionAsync\",\n const newCollection = this.columnFilter.collection || [];\n this.renderDomElement(newCollection);\n\n // on every Filter which have a \"collection\" or a \"collectionAsync\"\n // we will add (or replace) a Subject to the \"collectionAsync\" property so that user has possibility to change the collection\n // if \"collectionAsync\" is already set by the user, it will resolve it first then after it will replace it with a Subject\n const collectionAsync = this.columnFilter && this.columnFilter.collectionAsync;\n if (collectionAsync) {\n this.renderOptionsAsync(collectionAsync); // create Subject after resolve (createCollectionAsyncSubject)\n }\n }\n\n /**\n * Clear the filter value\n */\n clear(shouldTriggerQuery = true) {\n if (this.$filterElm) {\n this._clearFilterTriggered = true;\n this._shouldTriggerQuery = shouldTriggerQuery;\n this.searchTerms = [];\n this.$filterElm.val('');\n this.$filterElm.trigger('keyup');\n }\n }\n\n /**\n * destroy the filter\n */\n destroy() {\n if (this.$filterElm) {\n this.$filterElm.off('keyup input change').remove();\n }\n }\n\n /**\n * Set value(s) on the DOM element\n */\n setValues(values: SearchTerm | SearchTerm[]) {\n if (values) {\n this.$filterElm.val(values);\n }\n }\n\n //\n // protected functions\n // ------------------\n\n /**\n * user might want to filter certain items of the collection\n * @param inputCollection\n * @return outputCollection filtered and/or sorted collection\n */\n protected filterCollection(inputCollection: any[]): any[] {\n let outputCollection = inputCollection;\n\n // user might want to filter certain items of the collection\n if (this.columnFilter && this.columnFilter.collectionFilterBy) {\n const filterBy = this.columnFilter.collectionFilterBy;\n const filterCollectionBy = this.columnFilter.collectionOptions && this.columnFilter.collectionOptions.filterResultAfterEachPass || null;\n outputCollection = this.collectionService.filterCollection(outputCollection, filterBy, filterCollectionBy);\n }\n\n return outputCollection;\n }\n\n /**\n * user might want to sort the collection in a certain way\n * @param inputCollection\n * @return outputCollection filtered and/or sorted collection\n */\n protected sortCollection(inputCollection: any[]): any[] {\n let outputCollection = inputCollection;\n\n // user might want to sort the collection\n if (this.columnFilter && this.columnFilter.collectionSortBy) {\n const sortBy = this.columnFilter.collectionSortBy;\n outputCollection = this.collectionService.sortCollection(this.columnDef, outputCollection, sortBy, this.enableTranslateLabel);\n }\n\n return outputCollection;\n }\n\n protected async renderOptionsAsync(collectionAsync: Promise<any> | Observable<any> | Subject<any>) {\n let awaitedCollection: any = [];\n\n if (collectionAsync) {\n awaitedCollection = await castToPromise(collectionAsync);\n this.renderDomElementFromCollectionAsync(awaitedCollection);\n\n // because we accept Promises & HttpClient Observable only execute once\n // we will re-create an RxJs Subject which will replace the \"collectionAsync\" which got executed once anyway\n // doing this provide the user a way to call a \"collectionAsync.next()\"\n this.createCollectionAsyncSubject();\n }\n }\n\n /** Create or recreate an Observable Subject and reassign it to the \"collectionAsync\" object so user can call a \"collectionAsync.next()\" on it */\n protected createCollectionAsyncSubject() {\n const newCollectionAsync = new Subject<any>();\n this.columnFilter.collectionAsync = newCollectionAsync;\n this.subscriptions.push(\n newCollectionAsync.subscribe(collection => this.renderDomElementFromCollectionAsync(collection))\n );\n }\n\n /**\n * When user use a CollectionAsync we will use the returned collection to render the filter DOM element\n * and reinitialize filter collection with this new collection\n */\n protected renderDomElementFromCollectionAsync(collection) {\n if (this.collectionOptions && this.collectionOptions.collectionInObjectProperty) {\n collection = getDescendantProperty(collection, this.collectionOptions.collectionInObjectProperty);\n }\n if (!Array.isArray(collection)) {\n throw new Error('Something went wrong while trying to pull the collection from the \"collectionAsync\" call in the AutoComplete Filter, the collection is not a valid array.');\n }\n\n // copy over the array received from the async call to the \"collection\" as the new collection to use\n // this has to be BEFORE the `collectionObserver().subscribe` to avoid going into an infinite loop\n this.columnFilter.collection = collection;\n\n // recreate Filter DOM element after getting async collection\n this.renderDomElement(collection);\n }\n\n protected renderDomElement(collection: any[]) {\n if (!Array.isArray(collection) && this.collectionOptions && this.collectionOptions.collectionInObjectProperty) {\n collection = getDescendantProperty(collection, this.collectionOptions.collectionInObjectProperty);\n }\n if (!Array.isArray(collection)) {\n throw new Error('The \"collection\" passed to the Autocomplete Filter is not a valid array');\n }\n\n // assign the collection to a temp variable before filtering/sorting the collection\n let newCollection = collection;\n\n // user might want to filter and/or sort certain items of the collection\n newCollection = this.filterCollection(newCollection);\n newCollection = this.sortCollection(newCollection);\n\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\n\n // step 1, create HTML string template\n const filterTemplate = this.buildTemplateHtmlString();\n\n // step 2, create the DOM Element of the filter & pre-load search term\n // also subscribe to the onClose event\n this.$filterElm = this.createDomElement(filterTemplate, newCollection, searchTerm);\n\n // step 3, subscribe to the keyup event and run the callback when that happens\n // also add/remove \"filled\" class for styling purposes\n this.$filterElm.on('keyup input change', (e: any) => {\n let value = e && e.target && e.target.value || '';\n const enableWhiteSpaceTrim = this.gridOptions.enableFilterTrimWhiteSpace || this.columnFilter.enableTrimWhiteSpace;\n if (typeof value === 'string' && enableWhiteSpaceTrim) {\n value = value.trim();\n }\n\n if (this._clearFilterTriggered) {\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\n this.$filterElm.removeClass('filled');\n } else {\n if (value === '') {\n this.$filterElm.removeClass('filled');\n this.callback(e, { columnDef: this.columnDef, operator: this.operator, searchTerms: [value], shouldTriggerQuery: this._shouldTriggerQuery });\n } else {\n this.$filterElm.addClass('filled');\n }\n }\n // reset both flags for next use\n this._clearFilterTriggered = false;\n this._shouldTriggerQuery = true;\n });\n }\n\n /**\n * Create the HTML template as a string\n */\n private buildTemplateHtmlString() {\n const columnId = this.columnDef && this.columnDef.id;\n let placeholder = (this.gridOptions) ? (this.gridOptions.defaultFilterPlaceholder || '') : '';\n if (this.columnFilter && this.columnFilter.placeholder) {\n placeholder = this.columnFilter.placeholder;\n }\n return `<input type=\"text\" role=\"presentation\" autocomplete=\"off\" class=\"form-control autocomplete search-filter filter-${columnId}\" placeholder=\"${placeholder}\">`;\n }\n\n /**\n * From the html template string, create a DOM element\n * @param filterTemplate\n */\n private createDomElement(filterTemplate: string, collection: any[], searchTerm?: SearchTerm) {\n const columnId = this.columnDef && this.columnDef.id;\n const $headerElm = this.grid.getHeaderRowColumn(columnId);\n $($headerElm).empty();\n\n // create the DOM element & add an ID and filter class\n const $filterElm = $(filterTemplate) as any;\n const searchTermInput = searchTerm as string;\n\n // user might provide his own custom structure\n // jQuery UI autocomplete requires a label/value pair, so we must remap them when user provide different ones\n if (Array.isArray(collection) && this.customStructure) {\n collection = collection.map((item) => {\n return { label: item[this.labelName], value: item[this.valueName] };\n });\n }\n\n // user might pass his own autocomplete options\n const autoCompleteOptions = this.columnFilter.filterOptions;\n\n // when user passes it's own autocomplete options\n // we still need to provide our own \"select\" callback implementation\n if (autoCompleteOptions) {\n autoCompleteOptions.select = (event: Event, ui: any) => this.onSelect(event, ui);\n $filterElm.autocomplete(autoCompleteOptions);\n } else {\n if (!Array.isArray(collection)) {\n throw new Error('AutoComplete default implementation requires a \"collection\" or \"collectionAsync\" to be provided for the filter to work properly');\n }\n\n $filterElm.autocomplete({\n minLength: 0,\n source: collection,\n select: (event: Event, ui: any) => this.onSelect(event, ui),\n });\n }\n\n $filterElm.val(searchTermInput);\n $filterElm.attr('id', `filter-${columnId}`);\n $filterElm.data('columnId', columnId);\n\n // if there's a search term, we will add the \"filled\" class for styling purposes\n if (searchTerm) {\n $filterElm.addClass('filled');\n }\n\n // append the new DOM element to the header row\n if ($filterElm && typeof $filterElm.appendTo === 'function') {\n $filterElm.appendTo($headerElm);\n }\n\n return $filterElm;\n }\n\n //\n // private functions\n // ------------------\n\n private onSelect(event: Event, ui: any) {\n if (ui && ui.item) {\n const itemLabel = typeof ui.item === 'string' ? ui.item : ui.item.label;\n const itemValue = typeof ui.item === 'string' ? ui.item : ui.item.value;\n this.$filterElm.val(itemLabel);\n this.callback(event, { columnDef: this.columnDef, operator: this.operator, searchTerms: [itemValue], shouldTriggerQuery: this._shouldTriggerQuery });\n // reset both flags for next use\n this._clearFilterTriggered = false;\n this._shouldTriggerQuery = true;\n }\n return false;\n }\n}\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { mapFlatpickrDateFormatWithFieldType } from '../services/utilities';\r\nimport {\r\n Column,\r\n ColumnFilter,\r\n Filter,\r\n FilterArguments,\r\n FilterCallback,\r\n FieldType,\r\n GridOption,\r\n OperatorString,\r\n OperatorType,\r\n SearchTerm,\r\n} from './../models/index';\r\nimport Flatpickr from 'flatpickr';\r\n\r\n// use Flatpickr from import or 'require', whichever works first\r\ndeclare function require(name: string): any;\r\nrequire('flatpickr');\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nexport class CompoundDateFilter implements Filter {\r\n private _clearFilterTriggered = false;\r\n private _shouldTriggerQuery = true;\r\n private $filterElm: any;\r\n private $filterInputElm: any;\r\n private $selectOperatorElm: any;\r\n private _currentValue: string;\r\n private _operator: OperatorType | OperatorString;\r\n flatInstance: any;\r\n grid: any;\r\n searchTerms: SearchTerm[];\r\n columnDef: Column;\r\n callback: FilterCallback;\r\n\r\n constructor(private translate: TranslateService) { }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get gridOptions(): GridOption {\r\n return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {};\r\n }\r\n\r\n /** Getter for the Column Filter */\r\n get columnFilter(): ColumnFilter {\r\n return this.columnDef && this.columnDef.filter || {};\r\n }\r\n\r\n /** Setter for the Filter Operator */\r\n set operator(op: OperatorType | OperatorString) {\r\n this._operator = op;\r\n }\r\n\r\n /** Getter for the Filter Operator */\r\n get operator(): OperatorType | OperatorString {\r\n return this._operator || OperatorType.empty;\r\n }\r\n\r\n /**\r\n * Initialize the Filter\r\n */\r\n init(args: FilterArguments) {\r\n if (args) {\r\n this.grid = args.grid;\r\n this.callback = args.callback;\r\n this.columnDef = args.columnDef;\r\n this.operator = args.operator || '';\r\n this.searchTerms = args.searchTerms || [];\r\n\r\n // date input can only have 1 search term, so we will use the 1st array index if it exist\r\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\r\n\r\n // step 1, create the DOM Element of the filter which contain the compound Operator+Input\r\n // and initialize it if searchTerm is filled\r\n this.$filterElm = this.createDomElement(searchTerm);\r\n\r\n // step 3, subscribe to the keyup event and run the callback when that happens\r\n // also add/remove \"filled\" class for styling purposes\r\n this.$filterInputElm.keyup((e: any) => {\r\n this.onTriggerEvent(e);\r\n });\r\n this.$selectOperatorElm.change((e: any) => {\r\n this.onTriggerEvent(e);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Clear the filter value\r\n */\r\n clear(shouldTriggerQuery = true) {\r\n if (this.flatInstance && this.$selectOperatorElm) {\r\n this._clearFilterTriggered = true;\r\n this._shouldTriggerQuery = shouldTriggerQuery;\r\n this.searchTerms = [];\r\n this.$selectOperatorElm.val(0);\r\n this.flatInstance.clear();\r\n }\r\n }\r\n\r\n /**\r\n * destroy the filter\r\n */\r\n destroy() {\r\n if (this.$filterElm) {\r\n this.$filterElm.off('keyup').remove();\r\n }\r\n }\r\n\r\n /**\r\n * Set value(s) on the DOM element\r\n */\r\n setValues(values: SearchTerm[]) {\r\n if (this.flatInstance && values && Array.isArray(values)) {\r\n this.flatInstance.setDate(values[0]);\r\n }\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n private buildDatePickerInput(searchTerm?: SearchTerm) {\r\n const inputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.type || FieldType.dateIso);\r\n const outputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.outputType || this.columnDef.type || FieldType.dateUtc);\r\n let currentLocale = this.translate.currentLang || 'en';\r\n if (currentLocale.length > 2) {\r\n currentLocale = currentLocale.substring(0, 2);\r\n }\r\n\r\n const pickerOptions: any = {\r\n defaultDate: searchTerm || '',\r\n altInput: true,\r\n altFormat: outputFormat,\r\n dateFormat: inputFormat,\r\n wrap: true,\r\n closeOnSelect: true,\r\n locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en',\r\n onChange: (selectedDates: any[] | any, dateStr: string, instance: any) => {\r\n this._currentValue = dateStr;\r\n\r\n // when using the time picker, we can simulate a keyup event to avoid multiple backend request\r\n // since backend request are only executed after user start typing, changing the time should be treated the same way\r\n if (pickerOptions.enableTime) {\r\n this.onTriggerEvent(new CustomEvent('keyup'));\r\n } else {\r\n this.onTriggerEvent(undefined);\r\n }\r\n }\r\n };\r\n\r\n\r\n // add the time picker when format is UTC (Z) or has the 'h' (meaning hours)\r\n if (outputFormat && (outputFormat === 'Z' || outputFormat.toLowerCase().includes('h'))) {\r\n pickerOptions.enableTime = true;\r\n }\r\n\r\n // merge options with optional user's custom options\r\n const pickerMergedOptions = { ...pickerOptions, ...this.columnFilter.filterOptions };\r\n\r\n let placeholder = (this.gridOptions) ? (this.gridOptions.defaultFilterPlaceholder || '') : '';\r\n if (this.columnFilter && this.columnFilter.placeholder) {\r\n placeholder = this.columnFilter.placeholder;\r\n }\r\n const $filterInputElm: any = $(`<div class=\"flatpickr\"><input type=\"text\" class=\"form-control\" data-input placeholder=\"${placeholder}\"></div>`);\r\n this.flatInstance = ($filterInputElm[0] && typeof $filterInputElm[0].flatpickr === 'function') ? $filterInputElm[0].flatpickr(pickerMergedOptions) : Flatpickr($filterInputElm, pickerMergedOptions);\r\n return $filterInputElm;\r\n }\r\n\r\n private buildSelectOperatorHtmlString() {\r\n const optionValues = this.getOptionValues();\r\n let optionValueString = '';\r\n optionValues.forEach((option) => {\r\n optionValueString += `<option value=\"${option.operator}\" title=\"${option.description}\">${option.operator}</option>`;\r\n });\r\n\r\n return `<select class=\"form-control\">${optionValueString}</select>`;\r\n }\r\n\r\n private getOptionValues(): { operator: OperatorString, description: string }[] {\r\n return [\r\n { operator: '' as OperatorString, description: '' },\r\n { operator: '=' as OperatorString, description: '' },\r\n { operator: '<' as OperatorString, description: '' },\r\n { operator: '<=' as OperatorString, description: '' },\r\n { operator: '>' as OperatorString, description: '' },\r\n { operator: '>=' as OperatorString, description: '' },\r\n { operator: '<>' as OperatorString, description: '' }\r\n ];\r\n }\r\n\r\n /**\r\n * Create the DOM element\r\n */\r\n private createDomElement(searchTerm?: SearchTerm) {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const $headerElm = this.grid.getHeaderRowColumn(fieldId);\r\n $($headerElm).empty();\r\n\r\n // create the DOM Select dropdown for the Operator\r\n this.$selectOperatorElm = $(this.buildSelectOperatorHtmlString());\r\n this.$filterInputElm = this.buildDatePickerInput(searchTerm);\r\n const $filterContainerElm = $(`<div class=\"form-group search-filter filter-${fieldId}\"></div>`);\r\n const $containerInputGroup = $(`<div class=\"input-group flatpickr\"></div>`);\r\n const $operatorInputGroupAddon = $(`<div class=\"input-group-addon input-group-prepend operator\"></div>`);\r\n\r\n /* the DOM element final structure will be\r\n <div class=\"input-group\">\r\n <div class=\"input-group-addon input-group-prepend operator\">\r\n <select class=\"form-control\"></select>\r\n </div>\r\n <div class=flatpickr>\r\n <input type=\"text\" class=\"form-control\" data-input>\r\n </div>\r\n </div>\r\n */\r\n $operatorInputGroupAddon.append(this.$selectOperatorElm);\r\n $containerInputGroup.append($operatorInputGroupAddon);\r\n $containerInputGroup.append(this.$filterInputElm);\r\n\r\n // create the DOM element & add an ID and filter class\r\n $filterContainerElm.append($containerInputGroup);\r\n $filterContainerElm.attr('id', `filter-${fieldId}`);\r\n this.$filterInputElm.data('columnId', fieldId);\r\n\r\n if (this.operator) {\r\n this.$selectOperatorElm.val(this.operator);\r\n }\r\n\r\n // if there's a search term, we will add the \"filled\" class for styling purposes\r\n if (searchTerm) {\r\n $filterContainerElm.addClass('filled');\r\n this._currentValue = searchTerm as string;\r\n }\r\n\r\n // append the new DOM element to the header row\r\n if ($filterContainerElm && typeof $filterContainerElm.appendTo === 'function') {\r\n $filterContainerElm.appendTo($headerElm);\r\n }\r\n\r\n return $filterContainerElm;\r\n }\r\n\r\n private loadFlatpickrLocale(locale: string) {\r\n // change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/\r\n if (this.gridOptions && this.gridOptions.params && this.gridOptions.params.flapickrLocale) {\r\n return this.gridOptions.params.flapickrLocale;\r\n } else if (locale !== 'en') {\r\n const localeDefault: any = require(`flatpickr/dist/l10n/${locale}.js`).default;\r\n return (localeDefault && localeDefault[locale]) ? localeDefault[locale] : 'en';\r\n }\r\n return 'en';\r\n }\r\n\r\n private onTriggerEvent(e: Event | undefined) {\r\n if (this._clearFilterTriggered) {\r\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\r\n this.$filterElm.removeClass('filled');\r\n } else {\r\n const selectedOperator = this.$selectOperatorElm.find('option:selected').text();\r\n (this._currentValue) ? this.$filterElm.addClass('filled') : this.$filterElm.removeClass('filled');\r\n this.callback(e, { columnDef: this.columnDef, searchTerms: (this._currentValue ? [this._currentValue] : null), operator: selectedOperator || '', shouldTriggerQuery: this._shouldTriggerQuery });\r\n }\r\n // reset both flags for next use\r\n this._clearFilterTriggered = false;\r\n this._shouldTriggerQuery = true;\r\n }\r\n\r\n private hide() {\r\n if (this.flatInstance && typeof this.flatInstance.close === 'function') {\r\n this.flatInstance.close();\r\n }\r\n }\r\n\r\n private show() {\r\n if (this.flatInstance && typeof this.flatInstance.open === 'function') {\r\n this.flatInstance.open();\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\nimport {\n BackendServiceApi,\n Column,\n ColumnFilter,\n ColumnFilters,\n CurrentFilter,\n EmitterType,\n FieldType,\n Filter,\n FilterArguments,\n FilterCallbackArg,\n GraphqlResult,\n GridOption,\n KeyCode,\n OperatorString,\n OperatorType,\n SearchTerm,\n SlickEvent,\n SlickEventHandler,\n} from './../models/index';\nimport { executeBackendProcessesCallback, onBackendError } from './backend-utilities';\nimport { getDescendantProperty } from './utilities';\nimport { FilterConditions } from './../filter-conditions';\nimport { FilterFactory } from '../filters/filterFactory';\nimport { isObservable, Subject } from 'rxjs';\nimport * as isequal_ from 'lodash.isequal';\nconst isequal = isequal_; // patch to fix rollup to work\n\n// using external non-typed js libraries\ndeclare var Slick: any;\ndeclare var $: any;\n\n// timer for keeping track of user typing waits\nlet timer: any;\nconst DEFAULT_FILTER_TYPING_DEBOUNCE = 500;\n\n@Injectable()\nexport class FilterService {\n private _eventHandler: SlickEventHandler;\n private _isFilterFirstRender = true;\n private _firstColumnIdRendered = '';\n private _filtersMetadata: any[] = [];\n private _columnFilters: ColumnFilters = {};\n private _dataView: any;\n private _grid: any;\n private _onSearchChange: SlickEvent;\n onFilterChanged = new Subject<CurrentFilter[]>();\n onFilterCleared = new Subject<boolean>();\n\n constructor(private filterFactory: FilterFactory) {\n this._eventHandler = new Slick.EventHandler();\n this._onSearchChange = new Slick.Event();\n }\n\n /** Getter of the SlickGrid Event Handler */\n get eventHandler(): SlickEventHandler {\n return this._eventHandler;\n }\n\n /** Getter to know if the filter was already rendered or if it was its first time render */\n get isFilterFirstRender(): boolean {\n return this._isFilterFirstRender;\n }\n\n /** Getter of the SlickGrid Event Handler */\n get onSearchChange(): SlickEvent {\n return this._onSearchChange;\n }\n\n /** Getter for the Grid Options pulled through the Grid Object */\n private get _gridOptions(): GridOption {\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\n }\n\n /** Getter for the Column Definitions pulled through the Grid Object */\n private get _columnDefinitions(): Column[] {\n return (this._grid && this._grid.getColumns) ? this._grid.getColumns() : [];\n }\n\n init(grid: any): void {\n this._grid = grid;\n }\n\n dispose() {\n this.disposeColumnFilters();\n\n // unsubscribe all SlickGrid events\n if (this._eventHandler && this._eventHandler.unsubscribeAll) {\n this._eventHandler.unsubscribeAll();\n }\n }\n\n /**\n * Dispose of the filters, since it's a singleton, we don't want to affect other grids with same columns\n */\n disposeColumnFilters() {\n // we need to loop through all columnFilters and delete them 1 by 1\n // only trying to make columnFilter an empty (without looping) would not trigger a dataset change\n if (typeof this._columnFilters === 'object') {\n for (const columnId in this._columnFilters) {\n if (columnId && this._columnFilters[columnId]) {\n delete this._columnFilters[columnId];\n }\n }\n }\n\n // also destroy each Filter instances\n if (Array.isArray(this._filtersMetadata)) {\n this._filtersMetadata.forEach((filter) => {\n if (filter && filter.destroy) {\n filter.destroy(true);\n }\n });\n }\n }\n\n /**\n * Bind a backend filter hook to the grid\n * @param grid SlickGrid Grid object\n */\n bindBackendOnFilter(grid: any, dataView: any) {\n this._dataView = dataView;\n this._filtersMetadata = [];\n\n // subscribe to SlickGrid onHeaderRowCellRendered event to create filter template\n this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: KeyboardEvent, args: any) => {\n // firstColumnIdRendered is null at first, so if it changes to being filled and equal, then we would know that it was already rendered\n // this is to avoid rendering the filter twice (only the Select Filter for now), rendering it again also clears the filter which has unwanted side effect\n if (args.column.id === this._firstColumnIdRendered) {\n this._isFilterFirstRender = false;\n }\n this.addFilterTemplateToHeaderRow(args, this._isFilterFirstRender);\n if (this._firstColumnIdRendered === '') {\n this._firstColumnIdRendered = args.column.id;\n }\n });\n\n // subscribe to the SlickGrid event and call the backend execution\n this._eventHandler.subscribe(this._onSearchChange, this.onBackendFilterChange.bind(this));\n }\n\n /**\n * Bind a local filter hook to the grid\n * @param grid SlickGrid Grid object\n * @param dataView\n */\n bindLocalOnFilter(grid: any, dataView: any) {\n this._filtersMetadata = [];\n this._dataView = dataView;\n\n dataView.setFilterArgs({ columnFilters: this._columnFilters, grid: this._grid });\n dataView.setFilter(this.customLocalFilter.bind(this, dataView));\n\n this._eventHandler.subscribe(this._onSearchChange, (e: KeyboardEvent, args: any) => {\n const columnId = args.columnId;\n if (columnId != null) {\n dataView.refresh();\n }\n // emit an onFilterChanged event when it's not called by a clear filter\n if (args && !args.clearFilterTriggered) {\n this.emitFilterChanged(EmitterType.local);\n }\n });\n\n // subscribe to SlickGrid onHeaderRowCellRendered event to create filter template\n this._eventHandler.subscribe(grid.onHeaderRowCellRendered, (e: KeyboardEvent, args: any) => {\n this.addFilterTemplateToHeaderRow(args);\n });\n }\n\n callbackSearchEvent(event: any, args: FilterCallbackArg) {\n if (args) {\n const searchTerm = ((event && event.target) ? (event.target as HTMLInputElement).value : undefined);\n const searchTerms = (args.searchTerms && Array.isArray(args.searchTerms)) ? args.searchTerms : (searchTerm ? [searchTerm] : undefined);\n const columnDef = args.columnDef || null;\n const columnId = columnDef ? (columnDef.id || '') : '';\n const operator = args.operator || undefined;\n const hasSearchTerms = searchTerms && Array.isArray(searchTerms);\n const termsCount = hasSearchTerms && searchTerms.length;\n const oldColumnFilters = { ...this._columnFilters };\n\n if (!hasSearchTerms || termsCount === 0 || (termsCount === 1 && searchTerms[0] === '')) {\n // delete the property from the columnFilters when it becomes empty\n // without doing this, it would leave an incorrect state of the previous column filters when filtering on another column\n delete this._columnFilters[columnId];\n } else {\n const colId = '' + columnId as string;\n const colFilter: ColumnFilter = {\n columnId: colId,\n columnDef,\n searchTerms,\n };\n if (operator) {\n colFilter.operator = operator;\n }\n this._columnFilters[colId] = colFilter;\n }\n\n // event might have been created as a CustomEvent (e.g. CompoundDateFilter), without being a valid Slick.EventData,\n // if so we will create a new Slick.EventData and merge it with that CustomEvent to avoid having SlickGrid errors\n const eventData = (event && typeof event.isPropagationStopped !== 'function') ? $.extend({}, new Slick.EventData(), event) : event;\n\n // trigger an event only if Filters changed or if ENTER key was pressed\n const eventKeyCode = event && event.keyCode;\n if (eventKeyCode === KeyCode.ENTER || !isequal(oldColumnFilters, this._columnFilters)) {\n this._onSearchChange.notify({\n clearFilterTriggered: args.clearFilterTriggered,\n shouldTriggerQuery: args.shouldTriggerQuery,\n columnId,\n columnDef: args.columnDef || null,\n columnFilters: this._columnFilters,\n operator,\n searchTerms,\n grid: this._grid\n }, eventData);\n }\n }\n }\n\n clearFilterByColumnId(event: Event, columnId: number | string) {\n const colFilter: Filter = this._filtersMetadata.find((filter: Filter) => filter.columnDef.id === columnId);\n if (colFilter && colFilter.clear) {\n colFilter.clear(true);\n }\n\n // we need to loop through all columnFilters and delete the filter found\n // only trying to clear columnFilter (without looping through) would not trigger a dataset change\n for (const colId in this._columnFilters) {\n if (colId === columnId && this._columnFilters[colId]) {\n delete this._columnFilters[colId];\n }\n }\n\n let emitter: EmitterType = EmitterType.local;\n const isBackendApi = this._gridOptions && this._gridOptions.backendServiceApi || false;\n\n // when using a backend service, we need to manually trigger a filter change\n if (isBackendApi) {\n emitter = EmitterType.remote;\n this.onBackendFilterChange(event as KeyboardEvent, { grid: this._grid, columnFilters: this._columnFilters });\n }\n\n // emit an event when filter is cleared\n this.emitFilterChanged(emitter);\n }\n\n /** Clear the search filters (below the column titles) */\n clearFilters() {\n this._filtersMetadata.forEach((filter: Filter) => {\n if (filter && filter.clear) {\n // clear element and trigger a change\n filter.clear(false);\n }\n });\n\n // we need to loop through all columnFilters and delete them 1 by 1\n // only trying to clear columnFilter (without looping through) would not trigger a dataset change\n for (const columnId in this._columnFilters) {\n if (columnId && this._columnFilters[columnId]) {\n delete this._columnFilters[columnId];\n }\n }\n\n // we also need to refresh the dataView and optionally the grid (it's optional since we use DataView)\n if (this._dataView && this._grid) {\n this._dataView.refresh();\n this._grid.invalidate();\n }\n\n // when using backend service, we need to query only once so it's better to do it here\n if (this._gridOptions && this._gridOptions.backendServiceApi) {\n const callbackArgs = { clearFilterTriggered: true, shouldTriggerQuery: true, grid: this._grid, columnFilters: this._columnFilters };\n this.executeBackendCallback(undefined, callbackArgs, new Date(), this._gridOptions.backendServiceApi);\n }\n\n // emit an event when filters are all cleared\n this.onFilterCleared.next(true);\n }\n\n customLocalFilter(dataView: any, item: any, args: any) {\n for (const columnId of Object.keys(args.columnFilters)) {\n const columnFilter = args.columnFilters[columnId];\n const columnIndex = args.grid.getColumnIndex(columnId);\n const columnDef = args.grid.getColumns()[columnIndex];\n if (!columnDef) {\n return false;\n }\n\n // Row Detail View plugin, if the row is padding we just get the value we're filtering on from it's parent\n if (this._gridOptions.enableRowDetailView) {\n const metadataPrefix = this._gridOptions.rowDetailView && this._gridOptions.rowDetailView.keyPrefix || '__';\n if (item[`${metadataPrefix}isPadding`] && item[`${metadataPrefix}parent`]) {\n item = item[`${metadataPrefix}parent`];\n }\n }\n\n const dataKey = columnDef.dataKey;\n const fieldName = columnDef.queryFieldFilter || columnDef.queryField || columnDef.field;\n const fieldType = columnDef.type || FieldType.string;\n const filterSearchType = (columnDef.filterSearchType) ? columnDef.filterSearchType : null;\n let cellValue = item[fieldName];\n\n // when item is a complex object (dot \".\" notation), we need to filter the value contained in the object tree\n if (fieldName.indexOf('.') >= 0) {\n cellValue = getDescendantProperty(item, fieldName);\n }\n\n // if we find searchTerms use them but make a deep copy so that we don't affect original array\n // we might have to overwrite the value(s) locally that are returned\n // e.g: we don't want to operator within the search value, since it will fail filter condition check trigger afterward\n const searchValues = (columnFilter && columnFilter.searchTerms) ? $.extend(true, [], columnFilter.searchTerms) : null;\n\n let fieldSearchValue = (Array.isArray(searchValues) && searchValues.length === 1) ? searchValues[0] : '';\n\n let matches = null;\n if (fieldType !== FieldType.object) {\n fieldSearchValue = '' + fieldSearchValue; // make sure it's a string\n matches = fieldSearchValue.match(/^([<>!=\\*]{0,2})(.*[^<>!=\\*])([\\*]?)$/); // group 1: Operator, 2: searchValue, 3: last char is '*' (meaning starts with, ex.: abc*)\n }\n\n let operator = columnFilter.operator || ((matches) ? matches[1] : '');\n const searchTerm = (!!matches) ? matches[2] : '';\n const lastValueChar = (!!matches) ? matches[3] : (operator === '*z' ? '*' : '');\n\n if (searchValues && searchValues.length > 1) {\n fieldSearchValue = searchValues.join(',');\n } else if (typeof fieldSearchValue === 'string') {\n // escaping the search value\n fieldSearchValue = fieldSearchValue.replace(`'`, `''`); // escape single quotes by doubling them\n if (operator === '*' || operator === 'a*' || operator === '*z' || lastValueChar === '*') {\n operator = (operator === '*' || operator === '*z') ? OperatorType.endsWith : OperatorType.startsWith;\n }\n }\n\n // no need to query if search value is empty\n if (searchTerm === '' && (!searchValues || (Array.isArray(searchValues) && searchValues.length === 0))) {\n return true;\n }\n\n // if search value has a regex match we will only keep the value without the operator\n // in this case we need to overwrite the returned search values to truncate operator from the string search\n if (Array.isArray(matches) && matches.length >= 1 && (Array.isArray(searchValues) && searchValues.length === 1)) {\n searchValues[0] = searchTerm;\n }\n\n // filter search terms should always be string type (even though we permit the end user to input numbers)\n // so make sure each term are strings, if user has some default search terms, we will cast them to string\n if (searchValues && Array.isArray(searchValues) && fieldType !== FieldType.object) {\n for (let k = 0, ln = searchValues.length; k < ln; k++) {\n // make sure all search terms are strings\n searchValues[k] = ((searchValues[k] === undefined || searchValues[k] === null) ? '' : searchValues[k]) + '';\n }\n }\n\n // when using localization (i18n), we should use the formatter output to search as the new cell value\n if (columnDef && columnDef.params && columnDef.params.useFormatterOuputToFilter) {\n const rowIndex = (dataView && typeof dataView.getIdxById === 'function') ? dataView.getIdxById(item.id) : 0;\n cellValue = columnDef.formatter(rowIndex, columnIndex, cellValue, columnDef, item, this._grid);\n }\n\n // make sure cell value is always a string\n if (typeof cellValue === 'number') {\n cellValue = cellValue.toString();\n }\n\n const conditionOptions = {\n dataKey,\n fieldType,\n searchTerms: searchValues,\n cellValue,\n operator: operator as OperatorString,\n cellValueLastChar: lastValueChar,\n filterSearchType\n };\n\n if (!FilterConditions.executeMappedCondition(conditionOptions)) {\n return false;\n }\n }\n\n return true;\n }\n\n async executeBackendCallback(event: KeyboardEvent, args: any, startTime: Date, backendApi: BackendServiceApi) {\n const query = await backendApi.service.processOnFilterChanged(event, args);\n\n // emit an onFilterChanged event when it's not called by a clear filter\n if (args && !args.clearFilterTriggered) {\n this.emitFilterChanged(EmitterType.remote);\n }\n\n // the processes can be Observables (like HttpClient) or Promises\n const process = backendApi.process(query);\n if (process instanceof Promise && process.then) {\n process.then((processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this._gridOptions));\n } else if (isObservable(process)) {\n process.subscribe(\n (processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this._gridOptions),\n (error: any) => onBackendError(error, backendApi)\n );\n }\n }\n\n getColumnFilters() {\n return this._columnFilters;\n }\n\n getFiltersMetadata() {\n return this._filtersMetadata;\n }\n\n getCurrentLocalFilters(): CurrentFilter[] {\n const currentFilters: CurrentFilter[] = [];\n if (this._columnFilters) {\n for (const colId of Object.keys(this._columnFilters)) {\n const columnFilter = this._columnFilters[colId];\n const filter = { columnId: colId || '' } as CurrentFilter;\n\n if (columnFilter && columnFilter.searchTerms) {\n filter.searchTerms = columnFilter.searchTerms;\n }\n if (columnFilter.operator) {\n filter.operator = columnFilter.operator;\n }\n if (Array.isArray(filter.searchTerms) && filter.searchTerms.length > 0 && filter.searchTerms[0] !== '') {\n currentFilters.push(filter);\n }\n }\n }\n return currentFilters;\n }\n\n /**\n * A simple function that is binded to the subscriber and emit a change when the filter is called.\n * Other services, like Pagination, can then subscribe to it.\n * @param caller\n */\n emitFilterChanged(caller: EmitterType) {\n if (caller === EmitterType.remote && this._gridOptions && this._gridOptions.backendServiceApi) {\n let currentFilters: CurrentFilter[] = [];\n const backendService = this._gridOptions.backendServiceApi.service;\n if (backendService && backendService.getCurrentFilters) {\n currentFilters = backendService.getCurrentFilters() as CurrentFilter[];\n }\n this.onFilterChanged.next(currentFilters);\n } else if (caller === EmitterType.local) {\n this.onFilterChanged.next(this.getCurrentLocalFilters());\n }\n }\n\n onBackendFilterChange(event: KeyboardEvent, args: any) {\n if (!args || !args.grid) {\n throw new Error('Something went wrong when trying to bind the \"onBackendFilterChange(event, args)\" function, it seems that \"args\" is not populated correctly');\n }\n\n const gridOptions: GridOption = (args.grid && args.grid.getOptions) ? args.grid.getOptions() : {};\n const backendApi = gridOptions.backendServiceApi;\n\n if (!backendApi || !backendApi.process || !backendApi.service) {\n throw new Error(`BackendServiceApi requires at least a \"process\" function and a \"service\" defined`);\n }\n\n try {\n // keep start time & end timestamps & return it after process execution\n const startTime = new Date();\n\n // run a preProcess callback if defined\n if (backendApi.preProcess) {\n backendApi.preProcess();\n }\n\n // only add a delay when user is typing, on select dropdown filter (or \"Clear Filter\") it will execute right away\n let debounceTypingDelay = 0;\n const isTriggeredByClearFilter = args && args.clearFilterTriggered; // was it trigger by a \"Clear Filter\" command?\n\n if (!isTriggeredByClearFilter && event && event.keyCode !== KeyCode.ENTER && (event.type === 'input' || event.type === 'keyup' || event.type === 'keydown')) {\n debounceTypingDelay = backendApi.filterTypingDebounce || DEFAULT_FILTER_TYPING_DEBOUNCE;\n }\n\n // query backend, except when it's called by a ClearFilters then we won't\n if (args && args.shouldTriggerQuery) {\n // call the service to get a query back\n if (debounceTypingDelay > 0) {\n clearTimeout(timer);\n timer = setTimeout(() => this.executeBackendCallback(event, args, startTime, backendApi), debounceTypingDelay);\n } else {\n this.executeBackendCallback(event, args, startTime, backendApi);\n }\n }\n } catch (error) {\n onBackendError(error, backendApi);\n }\n }\n\n /**\n * When user passes an array of preset filters, we need to pre-populate each column filter searchTerm(s)\n * The process is to loop through the preset filters array, find the associated column from columnDefinitions and fill in the filter object searchTerm(s)\n * This is basically the same as if we would manually add searchTerm(s) to a column filter object in the column definition, but we do it programmatically.\n * At the end of the day, when creating the Filter (DOM Element), it will use these searchTerm(s) so we can take advantage of that without recoding each Filter type (DOM element)\n */\n populateColumnFilterSearchTerms() {\n if (this._gridOptions.presets && Array.isArray(this._gridOptions.presets.filters) && this._gridOptions.presets.filters.length > 0) {\n const filters = this._gridOptions.presets.filters;\n this._columnDefinitions.forEach((columnDef: Column) => {\n // clear any columnDef searchTerms before applying Presets\n if (columnDef.filter && columnDef.filter.searchTerms) {\n delete columnDef.filter.searchTerms;\n }\n\n // from each presets, we will find the associated columnDef and apply the preset searchTerms & operator if there is\n const columnPreset = filters.find((presetFilter: CurrentFilter) => {\n return presetFilter.columnId === columnDef.id;\n });\n if (columnPreset && columnPreset.searchTerms && Array.isArray(columnPreset.searchTerms)) {\n columnDef.filter = columnDef.filter || {};\n columnDef.filter.operator = columnPreset.operator || columnDef.filter.operator || '';\n columnDef.filter.searchTerms = columnPreset.searchTerms;\n }\n });\n }\n }\n\n // --\n // private functions\n // -------------------\n\n /** Add all created filters (from their template) to the header row section area */\n private addFilterTemplateToHeaderRow(args: { column: Column; grid: any; node: HTMLElement }, isFilterFirstRender = true) {\n const columnDef = args.column;\n const columnId = columnDef.id || '';\n\n if (columnDef && columnId !== 'selector' && columnDef.filterable) {\n let searchTerms: SearchTerm[] | undefined;\n let operator: OperatorType | OperatorString;\n const newFilter: Filter | undefined = this.filterFactory.createFilter(args.column.filter);\n operator = (columnDef && columnDef.filter && columnDef.filter.operator) || (newFilter && newFilter.operator) || undefined;\n\n if (this._columnFilters[columnDef.id]) {\n searchTerms = this._columnFilters[columnDef.id].searchTerms || undefined;\n operator = this._columnFilters[columnDef.id].operator || undefined;\n } else if (columnDef.filter) {\n // when hiding/showing (with Column Picker or Grid Menu), it will try to re-create yet again the filters (since SlickGrid does a re-render)\n // because of that we need to first get searchTerm(s) from the columnFilters (that is what the user last typed in a filter search input)\n searchTerms = columnDef.filter.searchTerms || undefined;\n this.updateColumnFilters(searchTerms, columnDef, operator);\n }\n\n const filterArguments: FilterArguments = {\n grid: this._grid,\n operator,\n searchTerms,\n columnDef,\n callback: this.callbackSearchEvent.bind(this)\n };\n\n if (newFilter) {\n newFilter.init(filterArguments, isFilterFirstRender);\n const filterExistIndex = this._filtersMetadata.findIndex((filter) => newFilter.columnDef.name === filter.columnDef.name);\n\n // add to the filters arrays or replace it when found\n if (filterExistIndex === -1) {\n this._filtersMetadata.push(newFilter);\n } else {\n this._filtersMetadata[filterExistIndex] = newFilter;\n }\n\n // when hiding/showing (with Column Picker or Grid Menu), it will try to re-create yet again the filters (since SlickGrid does a re-render)\n // we need to also set again the values in the DOM elements if the values were set by a searchTerm(s)\n if (searchTerms && newFilter.setValues) {\n newFilter.setValues(searchTerms);\n }\n }\n }\n }\n\n private updateColumnFilters(searchTerms: SearchTerm[] | undefined, columnDef: any, operator?: OperatorType | OperatorString) {\n if (searchTerms && columnDef) {\n this._columnFilters[columnDef.id] = {\n columnId: columnDef.id,\n columnDef,\n searchTerms,\n operator\n };\n }\n }\n}\n","import { Injectable } from '@angular/core';\r\nimport { CellArgs, Column, GridOption, GridServiceDeleteOption, GridServiceInsertOption, GridServiceUpdateOption, OnEventArgs } from './../models/index';\r\nimport { ExtensionService } from './extension.service';\r\nimport { FilterService } from './filter.service';\r\nimport { GridStateService } from './gridState.service';\r\nimport { SortService } from './sort.service';\r\nimport { Subject } from 'rxjs';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\nlet highlightTimerEnd: any;\r\nconst GridServiceDeleteOptionDefaults: GridServiceDeleteOption = { triggerEvent: true };\r\nconst GridServiceInsertOptionDefaults: GridServiceInsertOption = { highlightRow: true, resortGrid: false, selectRow: false, triggerEvent: true };\r\nconst GridServiceUpdateOptionDefaults: GridServiceUpdateOption = { highlightRow: true, selectRow: false, triggerEvent: true };\r\n\r\n@Injectable()\r\nexport class GridService {\r\n private _grid: any;\r\n private _dataView: any;\r\n onItemAdded = new Subject<any | any[]>();\r\n onItemDeleted = new Subject<any | any[]>();\r\n onItemUpdated = new Subject<any | any[]>();\r\n onItemUpserted = new Subject<any | any[]>();\r\n\r\n constructor(\r\n private extensionService: ExtensionService,\r\n private filterService: FilterService,\r\n private gridStateService: GridStateService,\r\n private sortService: SortService\r\n ) { }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n init(grid: any, dataView: any): void {\r\n this._grid = grid;\r\n this._dataView = dataView;\r\n }\r\n\r\n /** Clear all Filters & Sorts */\r\n clearAllFiltersAndSorts() {\r\n // call both clear Filters & Sort but only trigger the last one to avoid sending multiple backend queries\r\n if (this.sortService && this.sortService.clearSorting) {\r\n this.sortService.clearSorting(false); // skip event trigger on this one\r\n }\r\n if (this.filterService && this.filterService.clearFilters) {\r\n this.filterService.clearFilters();\r\n }\r\n }\r\n\r\n /**\r\n * From a SlickGrid Event triggered get the Column Definition and Item Data Context\r\n *\r\n * For example the SlickGrid onClick will return cell arguments when subscribing to it.\r\n * From these cellArgs, we want to get the Column Definition and Item Data\r\n * @param cell event args\r\n * @return object with columnDef and dataContext\r\n */\r\n getColumnFromEventArguments(args: CellArgs): OnEventArgs {\r\n if (!args || !args.grid || !args.grid.getColumns || !args.grid.getDataItem) {\r\n throw new Error('To get the column definition and data, we need to have these arguments passed as objects (row, cell, grid)');\r\n }\r\n\r\n return {\r\n row: args.row,\r\n cell: args.cell,\r\n columnDef: args.grid.getColumns()[args.cell],\r\n dataContext: args.grid.getDataItem(args.row),\r\n dataView: this._dataView,\r\n grid: this._grid\r\n };\r\n }\r\n\r\n /** Get data item by it's row index number */\r\n getDataItemByRowNumber(rowNumber: number) {\r\n if (!this._grid || typeof this._grid.getDataItem !== 'function') {\r\n throw new Error(`We could not find SlickGrid Grid object or it's \"getDataItem\" method`);\r\n }\r\n return this._grid.getDataItem(rowNumber);\r\n }\r\n\r\n /** Chain the item Metadata with our implementation of Metadata at given row index */\r\n getItemRowMetadataToHighlight(previousItemMetadata: any) {\r\n return (rowNumber: number) => {\r\n const item = this._dataView.getItem(rowNumber);\r\n let meta = { cssClasses: '' };\r\n if (typeof previousItemMetadata === 'function') {\r\n meta = previousItemMetadata(rowNumber);\r\n }\r\n\r\n if (!meta) {\r\n meta = { cssClasses: '' };\r\n }\r\n\r\n if (item && item._dirty) {\r\n meta.cssClasses = (meta && meta.cssClasses || '') + ' dirty';\r\n }\r\n\r\n if (item && item.rowClass && meta) {\r\n meta.cssClasses += ` ${item.rowClass}`;\r\n meta.cssClasses += ` row${rowNumber}`;\r\n }\r\n\r\n return meta;\r\n };\r\n }\r\n\r\n /**\r\n * Highlight then fade a row for x seconds.\r\n * The implementation follows this SO answer: https://stackoverflow.com/a/19985148/1212166\r\n * @param rowNumber\r\n * @param fadeDelay\r\n */\r\n highlightRow(rowNumber: number | number[], fadeDelay = 1500, fadeOutDelay = 300) {\r\n // create a SelectionModel if there's not one yet\r\n if (!this._grid.getSelectionModel()) {\r\n const rowSelectionPlugin = new Slick.RowSelectionModel(this._gridOptions.rowSelectionOptions || {});\r\n this._grid.setSelectionModel(rowSelectionPlugin);\r\n }\r\n\r\n if (Array.isArray(rowNumber)) {\r\n rowNumber.forEach(row => this.highlightRowByMetadata(row, fadeDelay, fadeOutDelay));\r\n } else {\r\n this.highlightRowByMetadata(rowNumber, fadeDelay, fadeOutDelay);\r\n }\r\n }\r\n\r\n highlightRowByMetadata(rowNumber: number, fadeDelay = 1500, fadeOutDelay = 300) {\r\n this._dataView.getItemMetadata = this.getItemRowMetadataToHighlight(this._dataView.getItemMetadata);\r\n\r\n const item = this._dataView.getItem(rowNumber);\r\n if (item && item.id) {\r\n item.rowClass = 'highlight';\r\n this._dataView.updateItem(item.id, item);\r\n this.renderGrid();\r\n\r\n // fade out\r\n clearTimeout(highlightTimerEnd);\r\n highlightTimerEnd = setTimeout(() => {\r\n item.rowClass = 'highlight-end';\r\n this._dataView.updateItem(item.id, item);\r\n this.renderGrid();\r\n }, fadeOutDelay);\r\n\r\n // delete the row's CSS highlight classes once the delay is passed\r\n setTimeout(() => {\r\n if (item && item.id) {\r\n delete item.rowClass;\r\n if (this._dataView.getIdxById(item.id) !== undefined) {\r\n this._dataView.updateItem(item.id, item);\r\n this.renderGrid();\r\n }\r\n }\r\n }, fadeDelay + fadeOutDelay);\r\n }\r\n }\r\n\r\n /** Get the Data Item from a grid row index */\r\n getDataItemByRowIndex(index: number): any {\r\n if (!this._grid || typeof this._grid.getDataItem !== 'function') {\r\n throw new Error('We could not find SlickGrid Grid object and/or \"getDataItem\" method');\r\n }\r\n\r\n return this._grid.getDataItem(index);\r\n }\r\n\r\n /** Get the Data Item from an array of grid row indexes */\r\n getDataItemByRowIndexes(indexes: number[]): any[] {\r\n if (!this._grid || typeof this._grid.getDataItem !== 'function') {\r\n throw new Error('We could not find SlickGrid Grid object and/or \"getDataItem\" method');\r\n }\r\n\r\n const dataItems = [];\r\n\r\n if (Array.isArray(indexes)) {\r\n indexes.forEach((idx) => {\r\n dataItems.push(this._grid.getDataItem(idx));\r\n });\r\n }\r\n\r\n return dataItems;\r\n }\r\n\r\n /** Get the currently selected row indexes */\r\n getSelectedRows(): number[] {\r\n if (!this._grid || typeof this._grid.getSelectedRows !== 'function') {\r\n throw new Error('We could not find SlickGrid Grid object and/or \"getSelectedRows\" method');\r\n }\r\n return this._grid.getSelectedRows();\r\n }\r\n\r\n /** Get the currently selected rows item data */\r\n getSelectedRowsDataItem(): any[] {\r\n if (!this._grid || typeof this._grid.getSelectedRows !== 'function') {\r\n throw new Error('We could not find SlickGrid Grid object and/or \"getSelectedRows\" method');\r\n }\r\n\r\n const selectedRowIndexes = this._grid.getSelectedRows();\r\n return this.getDataItemByRowIndexes(selectedRowIndexes);\r\n }\r\n\r\n /** Select the selected row by a row index */\r\n setSelectedRow(rowIndex: number) {\r\n if (this._grid && this._grid.setSelectedRows) {\r\n this._grid.setSelectedRows([rowIndex]);\r\n }\r\n }\r\n\r\n /** Set selected rows with provided array of row indexes */\r\n setSelectedRows(rowIndexes: number[]) {\r\n if (this._grid && this._grid.setSelectedRows) {\r\n this._grid.setSelectedRows(rowIndexes);\r\n }\r\n }\r\n\r\n /** Re-Render the Grid */\r\n renderGrid() {\r\n if (this._grid && typeof this._grid.invalidate === 'function') {\r\n this._grid.invalidate();\r\n this._grid.render();\r\n }\r\n }\r\n\r\n /**\r\n * Reset the grid to it's original state (clear any filters, sorting & pagination if exists) .\r\n * The column definitions could be passed as argument to reset (this can be used after a Grid State reset)\r\n * The reset will clear the Filters & Sort, then will reset the Columns to their original state\r\n */\r\n resetGrid(columnDefinitions?: Column[]) {\r\n // reset columns to original states & refresh the grid\r\n if (this._grid && this._dataView) {\r\n const originalColumns = this.extensionService.getAllColumns();\r\n\r\n if (Array.isArray(originalColumns) && originalColumns.length > 0) {\r\n // set the grid columns to it's original column definitions\r\n this._grid.setColumns(originalColumns);\r\n if (this._gridOptions && this._gridOptions.enableAutoSizeColumns) {\r\n this._grid.autosizeColumns();\r\n }\r\n this.gridStateService.resetColumns(columnDefinitions);\r\n }\r\n }\r\n\r\n if (this.filterService && this.filterService.clearFilters) {\r\n this.filterService.clearFilters();\r\n }\r\n if (this.sortService && this.sortService.clearSorting) {\r\n this.sortService.clearSorting();\r\n }\r\n }\r\n\r\n /** @deprecated please use \"addItem\" method instead */\r\n addItemToDatagrid(item: any, shouldHighlightRow = true, shouldResortGrid = false, shouldTriggerEvent = true, shouldSelectRow = true): number {\r\n return this.addItem(item, { highlightRow: shouldHighlightRow, resortGrid: shouldResortGrid, triggerEvent: shouldTriggerEvent, selectRow: shouldSelectRow });\r\n }\r\n\r\n /** @deprecated please use \"addItems\" method instead */\r\n addItemsToDatagrid(items: any[], shouldHighlightRow = true, shouldResortGrid = false, shouldTriggerEvent = true, shouldSelectRow = true): number[] {\r\n return this.addItems(items, { highlightRow: shouldHighlightRow, resortGrid: shouldResortGrid, triggerEvent: shouldTriggerEvent, selectRow: shouldSelectRow });\r\n }\r\n\r\n /**\r\n * Add an item (data item) to the datagrid, by default it will highlight (flashing) the inserted row but we can disable it too\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, resortGrid, selectRow, triggerEvent)\r\n * @return rowIndex: typically index 0\r\n */\r\n addItem(item: any, options?: GridServiceInsertOption): number {\r\n options = { ...GridServiceInsertOptionDefaults, ...options };\r\n\r\n if (!this._grid || !this._gridOptions || !this._dataView) {\r\n throw new Error('We could not find SlickGrid Grid, DataView objects');\r\n }\r\n if (!item || !item.hasOwnProperty('id')) {\r\n throw new Error(`Adding an item requires the item to include an \"id\" property`);\r\n }\r\n\r\n this._dataView.insertItem(0, item); // insert at index 0\r\n\r\n // row number in the grid, by default it will be on first row\r\n let rowNumber = 0;\r\n\r\n // do we want the item to be sorted in the grid, when set to False it will insert on first row (defaults to false)\r\n if (options.resortGrid) {\r\n this._dataView.reSort();\r\n\r\n // find the row number in the grid and if user wanted to see highlighted row\r\n // we need to do it here after resort and get each row number because it possibly changes after the sort\r\n rowNumber = this._dataView.getRowById(item.id);\r\n } else {\r\n this._grid.scrollRowIntoView(rowNumber); // scroll to row 0\r\n }\r\n\r\n // highlight the row we just added, if highlight is defined\r\n if (options.highlightRow) {\r\n this.highlightRow(rowNumber);\r\n }\r\n\r\n // select the row in the grid\r\n if (options.selectRow && this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {\r\n this._grid.setSelectedRows(rowNumber);\r\n }\r\n\r\n // do we want to trigger an event after adding the item\r\n if (options.triggerEvent) {\r\n this.onItemAdded.next(item);\r\n }\r\n\r\n return rowNumber;\r\n }\r\n\r\n /**\r\n * Add item array (data item) to the datagrid, by default it will highlight (flashing) the inserted row but we can disable it too\r\n * @param item object arrays, which must contain unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, resortGrid, selectRow, triggerEvent)\r\n */\r\n addItems(items: any | any[], options?: GridServiceInsertOption): number[] {\r\n options = { ...GridServiceInsertOptionDefaults, ...options };\r\n const rowNumbers: number[] = [];\r\n\r\n // loop through all items to add\r\n if (!Array.isArray(items)) {\r\n return [this.addItem(items, options)];\r\n } else {\r\n items.forEach((item: any) => this.addItem(item, { highlightRow: false, resortGrid: false, selectRow: false, triggerEvent: false }));\r\n }\r\n\r\n // do we want the item to be sorted in the grid, when set to False it will insert on first row (defaults to false)\r\n if (options.resortGrid) {\r\n this._dataView.reSort();\r\n\r\n // if user wanted to see highlighted row\r\n // we need to do it here after resort and get each row number because it possibly changes after the sort\r\n if (options.highlightRow) {\r\n items.forEach((item: any) => {\r\n const rowNumber = this._dataView.getRowById(item.id);\r\n rowNumbers.push(rowNumber);\r\n });\r\n }\r\n } else if (options.highlightRow) {\r\n const ln = items.length;\r\n for (let i = 0; i < ln; i++) {\r\n rowNumbers.push(i);\r\n }\r\n }\r\n\r\n // do user want to highlight the rows\r\n if (options.highlightRow) {\r\n this.highlightRow(rowNumbers);\r\n }\r\n\r\n // select the row in the grid\r\n if (options.selectRow && this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {\r\n this._grid.setSelectedRows(rowNumbers);\r\n }\r\n\r\n // do we want to trigger an event after adding the item\r\n if (options.triggerEvent) {\r\n this.onItemAdded.next(items);\r\n }\r\n\r\n return rowNumbers;\r\n }\r\n\r\n /** @deprecated please use \"deleteItem\" method instead */\r\n deleteDataGridItem(item: any, shouldTriggerEvent = true) {\r\n this.deleteItem(item, { triggerEvent: shouldTriggerEvent });\r\n }\r\n\r\n /** @deprecated please use \"deleteItems\" method instead */\r\n deleteDataGridItems(items: any[], shouldTriggerEvent = true) {\r\n this.deleteItems(items, { triggerEvent: shouldTriggerEvent });\r\n }\r\n\r\n /** @deprecated please use \"deleteItemById\" method instead */\r\n deleteDataGridItemById(itemId: string | number, shouldTriggerEvent = true) {\r\n this.deleteItemById(itemId, { triggerEvent: shouldTriggerEvent });\r\n }\r\n\r\n /** @deprecated please use \"deleteItemByIds\" method instead */\r\n deleteDataGridItemByIds(itemIds: number[] | string[], shouldTriggerEvent = true) {\r\n this.deleteItemByIds(itemIds, { triggerEvent: shouldTriggerEvent });\r\n }\r\n\r\n /**\r\n * Delete an existing item from the datagrid (dataView)\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (triggerEvent)\r\n * @return item id deleted\r\n */\r\n deleteItem(item: any, options?: GridServiceDeleteOption): number | string {\r\n options = { ...GridServiceDeleteOptionDefaults, ...options };\r\n\r\n if (!item || !item.hasOwnProperty('id')) {\r\n throw new Error(`Deleting an item requires the item to include an \"id\" property`);\r\n }\r\n return this.deleteItemById(item.id, options);\r\n }\r\n\r\n /**\r\n * Delete an array of existing items from the datagrid\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (triggerEvent)\r\n * @return item id deleted\r\n */\r\n deleteItems(items: any | any[], options?: GridServiceDeleteOption): number[] | string[] {\r\n options = { ...GridServiceDeleteOptionDefaults, ...options };\r\n\r\n // when it's not an array, we can call directly the single item delete\r\n if (!Array.isArray(items)) {\r\n this.deleteItem(items, options);\r\n return [items.id];\r\n }\r\n const itemIds = [];\r\n items.forEach((item: any) => {\r\n if (item && item.id !== undefined) {\r\n itemIds.push(item.id);\r\n }\r\n this.deleteItem(item, { triggerEvent: false });\r\n });\r\n\r\n // do we want to trigger an event after deleting the item\r\n if (options.triggerEvent) {\r\n this.onItemDeleted.next(items);\r\n }\r\n return itemIds;\r\n }\r\n\r\n /**\r\n * Delete an existing item from the datagrid (dataView) by it's id\r\n * @param itemId: item unique id\r\n * @param options: provide the possibility to do certain actions after or during the upsert (triggerEvent)\r\n * @return item id deleted\r\n */\r\n deleteItemById(itemId: string | number, options?: GridServiceDeleteOption): number | string {\r\n options = { ...GridServiceDeleteOptionDefaults, ...options };\r\n\r\n if (itemId === null || itemId === undefined) {\r\n throw new Error(`Cannot delete a row without a valid \"id\"`);\r\n }\r\n\r\n // when user has row selection enabled, we should clear any selection to avoid confusion after a delete\r\n if (this._grid && this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {\r\n this._grid.setSelectedRows([]);\r\n }\r\n\r\n // delete the item from the dataView\r\n this._dataView.deleteItem(itemId);\r\n\r\n // do we want to trigger an event after deleting the item\r\n if (options.triggerEvent) {\r\n this.onItemDeleted.next(itemId);\r\n }\r\n return itemId;\r\n }\r\n\r\n /**\r\n * Delete an array of existing items from the datagrid\r\n * @param itemIds array of item unique IDs\r\n * @param options: provide the possibility to do certain actions after or during the upsert (triggerEvent)\r\n */\r\n deleteItemByIds(itemIds: number[] | string[], options?: GridServiceDeleteOption): number[] | string[] {\r\n options = { ...GridServiceDeleteOptionDefaults, ...options };\r\n\r\n // when it's not an array, we can call directly the single item delete\r\n if (Array.isArray(itemIds)) {\r\n for (let i = 0; i < itemIds.length; i++) {\r\n if (itemIds[i] !== null) {\r\n this.deleteItemById(itemIds[i], { triggerEvent: false });\r\n }\r\n }\r\n\r\n // do we want to trigger an event after deleting the item\r\n if (options.triggerEvent) {\r\n this.onItemDeleted.next(itemIds);\r\n }\r\n return itemIds;\r\n }\r\n return [];\r\n }\r\n\r\n /** @deprecated please use \"updateItem\" method instead */\r\n updateDataGridItem(item: any, shouldHighlightRow = true, shouldTriggerEvent = true, shouldSelectRow = true): number {\r\n return this.updateItem(item, { highlightRow: shouldHighlightRow, triggerEvent: shouldTriggerEvent, selectRow: shouldSelectRow });\r\n }\r\n\r\n /** @deprecated please use \"updateItems\" method instead */\r\n updateDataGridItems(items: any | any[], shouldHighlightRow = true, shouldTriggerEvent = true, shouldSelectRow = true): number[] {\r\n return this.updateItems(items, { highlightRow: shouldHighlightRow, triggerEvent: shouldTriggerEvent, selectRow: shouldSelectRow });\r\n }\r\n\r\n /** @deprecated please use \"updateItemById\" method instead */\r\n updateDataGridItemById(itemId: number | string, item: any, shouldHighlightRow = true, shouldTriggerEvent = true, shouldSelectRow = true): number {\r\n return this.updateItemById(itemId, item, { highlightRow: shouldHighlightRow, triggerEvent: shouldTriggerEvent, selectRow: shouldSelectRow });\r\n }\r\n\r\n /**\r\n * Update an existing item with new properties inside the datagrid\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, selectRow, triggerEvent)\r\n * @return grid row index\r\n */\r\n updateItem(item: any, options?: GridServiceUpdateOption): number {\r\n options = { ...GridServiceUpdateOptionDefaults, ...options };\r\n const itemId = (!item || !item.hasOwnProperty('id')) ? undefined : item.id;\r\n\r\n if (itemId === undefined) {\r\n throw new Error(`Calling Update of an item requires the item to include an \"id\" property`);\r\n }\r\n\r\n return this.updateItemById(itemId, item, options);\r\n }\r\n\r\n /**\r\n * Update an array of existing items with new properties inside the datagrid\r\n * @param item object arrays, which must contain unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, selectRow, triggerEvent)\r\n * @return grid row indexes\r\n */\r\n updateItems(items: any | any[], options?: GridServiceUpdateOption): number[] {\r\n options = { ...GridServiceUpdateOptionDefaults, ...options };\r\n\r\n // when it's not an array, we can call directly the single item update\r\n if (!Array.isArray(items)) {\r\n return [this.updateItem(items, options)];\r\n }\r\n\r\n const gridRowNumbers: number[] = [];\r\n items.forEach((item: any) => {\r\n gridRowNumbers.push(this.updateItem(item, { highlightRow: false, selectRow: false, triggerEvent: false }));\r\n });\r\n\r\n // only highlight at the end, all at once\r\n // we have to do this because doing highlight 1 by 1 would only re-select the last highlighted row which is wrong behavior\r\n if (options.highlightRow) {\r\n this.highlightRow(gridRowNumbers);\r\n }\r\n\r\n // select the row in the grid\r\n if (options.selectRow && this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {\r\n this._grid.setSelectedRows(gridRowNumbers);\r\n }\r\n\r\n // do we want to trigger an event after updating the item\r\n if (options.triggerEvent) {\r\n this.onItemUpdated.next(items);\r\n }\r\n\r\n return gridRowNumbers;\r\n }\r\n\r\n /**\r\n * Update an existing item in the datagrid by it's id and new properties\r\n * @param itemId: item unique id\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, selectRow, triggerEvent)\r\n * @return grid row number\r\n */\r\n updateItemById(itemId: number | string, item: any, options?: GridServiceUpdateOption): number {\r\n options = { ...GridServiceUpdateOptionDefaults, ...options };\r\n if (itemId === undefined) {\r\n throw new Error(`Cannot update a row without a valid \"id\"`);\r\n }\r\n const rowNumber = this._dataView.getRowById(itemId);\r\n\r\n if (!item || rowNumber === undefined) {\r\n throw new Error(`The item to update in the grid was not found with id: ${itemId}`);\r\n }\r\n\r\n if (this._dataView.getIdxById(itemId) !== undefined) {\r\n // Update the item itself inside the dataView\r\n this._dataView.updateItem(itemId, item);\r\n this._grid.updateRow(rowNumber);\r\n\r\n // highlight the row we just updated, if defined\r\n if (options.highlightRow) {\r\n this.highlightRow(rowNumber);\r\n }\r\n\r\n // select the row in the grid\r\n if (options.selectRow && this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {\r\n this._grid.setSelectedRows(rowNumber);\r\n }\r\n\r\n // do we want to trigger an event after updating the item\r\n if (options.triggerEvent) {\r\n this.onItemUpdated.next(item);\r\n }\r\n }\r\n return rowNumber;\r\n }\r\n\r\n /**\r\n * Insert a row into the grid if it doesn't already exist or update if it does.\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, resortGrid, selectRow, triggerEvent)\r\n */\r\n upsertItem(item: any, options?: GridServiceInsertOption): number {\r\n options = { ...GridServiceInsertOptionDefaults, ...options };\r\n const itemId = (!item || !item.hasOwnProperty('id')) ? undefined : item.id;\r\n\r\n if (itemId === undefined) {\r\n throw new Error(`Calling Upsert of an item requires the item to include an \"id\" property`);\r\n }\r\n\r\n return this.upsertItemById(itemId, item, options);\r\n }\r\n\r\n /**\r\n * Update an array of existing items with new properties inside the datagrid\r\n * @param item object arrays, which must contain unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, resortGrid, selectRow, triggerEvent)\r\n * @return row numbers in the grid\r\n */\r\n upsertItems(items: any | any[], options?: GridServiceInsertOption): number[] {\r\n options = { ...GridServiceInsertOptionDefaults, ...options };\r\n // when it's not an array, we can call directly the single item update\r\n if (!Array.isArray(items)) {\r\n return [this.upsertItem(items, options)];\r\n }\r\n\r\n const gridRowNumbers: number[] = [];\r\n items.forEach((item: any) => {\r\n gridRowNumbers.push(this.upsertItem(item, { highlightRow: false, resortGrid: false, selectRow: false, triggerEvent: false }));\r\n });\r\n\r\n // only highlight at the end, all at once\r\n // we have to do this because doing highlight 1 by 1 would only re-select the last highlighted row which is wrong behavior\r\n if (options.highlightRow) {\r\n this.highlightRow(gridRowNumbers);\r\n }\r\n\r\n // select the row in the grid\r\n if (options.selectRow && this._gridOptions && (this._gridOptions.enableCheckboxSelector || this._gridOptions.enableRowSelection)) {\r\n this._grid.setSelectedRows(gridRowNumbers);\r\n }\r\n\r\n // do we want to trigger an event after updating the item\r\n if (options.triggerEvent) {\r\n this.onItemUpserted.next(items);\r\n }\r\n return gridRowNumbers;\r\n }\r\n\r\n /**\r\n * Update an existing item in the datagrid by it's id and new properties\r\n * @param itemId: item unique id\r\n * @param item object which must contain a unique \"id\" property and any other suitable properties\r\n * @param options: provide the possibility to do certain actions after or during the upsert (highlightRow, resortGrid, selectRow, triggerEvent)\r\n * @return grid row number in the grid\r\n */\r\n upsertItemById(itemId: number | string, item: any, options?: GridServiceInsertOption): number {\r\n options = { ...GridServiceInsertOptionDefaults, ...options };\r\n if (itemId === undefined) {\r\n throw new Error(`Calling Upsert of an item requires the item to include a valid and unique \"id\" property`);\r\n }\r\n\r\n let rowNumber: number;\r\n if (this._dataView.getRowById(itemId) === undefined) {\r\n rowNumber = this.addItem(item, options);\r\n } else {\r\n rowNumber = this.updateItem(item, { highlightRow: options.highlightRow, selectRow: options.selectRow, triggerEvent: options.triggerEvent });\r\n }\r\n\r\n // do we want to trigger an event after updating the item\r\n if (options.triggerEvent) {\r\n this.onItemUpserted.next(item);\r\n }\r\n return rowNumber;\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\nimport { FieldType } from './../models/index';\nimport {\n Column,\n ColumnFilter,\n Filter,\n FilterArguments,\n FilterCallback,\n GridOption,\n OperatorString,\n OperatorType,\n SearchTerm,\n} from './../models/index';\n\n// using external non-typed js libraries\ndeclare var $: any;\n\nexport class CompoundInputFilter implements Filter {\n private _clearFilterTriggered = false;\n private _shouldTriggerQuery = true;\n private _inputType = 'text';\n private $filterElm: any;\n private $filterInputElm: any;\n private $selectOperatorElm: any;\n private _operator: OperatorType | OperatorString;\n grid: any;\n searchTerms: SearchTerm[];\n columnDef: Column;\n callback: FilterCallback;\n\n constructor(protected translate: TranslateService) { }\n\n /** Getter for the Grid Options pulled through the Grid Object */\n private get gridOptions(): GridOption {\n return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {};\n }\n\n /** Getter for the Column Filter */\n get columnFilter(): ColumnFilter {\n return this.columnDef && this.columnDef.filter || {};\n }\n\n /** Getter of input type (text, number, password) */\n get inputType() {\n return this._inputType;\n }\n\n /** Setter of input type (text, number, password) */\n set inputType(type: string) {\n this._inputType = type;\n }\n\n /** Getter of the Operator to use when doing the filter comparing */\n get operator(): OperatorType | OperatorString {\n return this._operator || OperatorType.empty;\n }\n\n /** Getter of the Operator to use when doing the filter comparing */\n set operator(op: OperatorType | OperatorString) {\n this._operator = op;\n }\n\n /**\n * Initialize the Filter\n */\n init(args: FilterArguments) {\n this.grid = args.grid;\n this.callback = args.callback;\n this.columnDef = args.columnDef;\n this.operator = args.operator;\n this.searchTerms = args.searchTerms || [];\n\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\n\n // step 1, create the DOM Element of the filter which contain the compound Operator+Input\n // and initialize it if searchTerms is filled\n this.$filterElm = this.createDomElement(searchTerm);\n\n // step 3, subscribe to the keyup event and run the callback when that happens\n // also add/remove \"filled\" class for styling purposes\n this.$filterInputElm.on('keyup input change', (e: any) => {\n this.onTriggerEvent(e);\n });\n this.$selectOperatorElm.on('change', (e: any) => {\n this.onTriggerEvent(e);\n });\n }\n\n /**\n * Clear the filter value\n */\n clear(shouldTriggerQuery = true) {\n if (this.$filterElm && this.$selectOperatorElm) {\n this._clearFilterTriggered = true;\n this._shouldTriggerQuery = shouldTriggerQuery;\n this.searchTerms = [];\n this.$selectOperatorElm.val(0);\n this.$filterInputElm.val('');\n this.onTriggerEvent(null);\n }\n }\n\n /**\n * destroy the filter\n */\n destroy() {\n if (this.$filterElm && this.$selectOperatorElm) {\n this.$filterElm.off('keyup input change').remove();\n this.$selectOperatorElm.off('change');\n }\n }\n\n /**\n * Set value(s) on the DOM element\n */\n setValues(values: SearchTerm[]) {\n if (values && Array.isArray(values)) {\n this.$filterElm.val(values[0]);\n }\n }\n\n //\n // private functions\n // ------------------\n\n private buildInputHtmlString() {\n let placeholder = (this.gridOptions) ? (this.gridOptions.defaultFilterPlaceholder || '') : '';\n if (this.columnFilter && this.columnFilter.placeholder) {\n placeholder = this.columnFilter.placeholder;\n }\n return `<input type=\"${this._inputType || 'text'}\" role=\"presentation\" autocomplete=\"off\" class=\"form-control\" placeholder=\"${placeholder}\" /><span></span>`;\n }\n\n private buildSelectOperatorHtmlString() {\n const optionValues = this.getOptionValues();\n let optionValueString = '';\n optionValues.forEach((option) => {\n optionValueString += `<option value=\"${option.operator}\" title=\"${option.description}\">${option.operator}</option>`;\n });\n\n return `<select class=\"form-control\">${optionValueString}</select>`;\n }\n\n private getOptionValues(): { operator: OperatorString, description: string }[] {\n const type = (this.columnDef.type && this.columnDef.type) ? this.columnDef.type : FieldType.string;\n let optionValues = [];\n\n switch (type) {\n case FieldType.string:\n optionValues = [\n { operator: '' as OperatorString, description: this.translate.instant('CONTAINS') },\n { operator: '=' as OperatorString, description: this.translate.instant('EQUALS') },\n { operator: 'a*' as OperatorString, description: this.translate.instant('STARTS_WITH') },\n { operator: '*z' as OperatorString, description: this.translate.instant('ENDS_WITH') },\n /*\n { operator: 'IN' as OperatorString, description: this.translate.instant('IN_COLLECTION_SEPERATED_BY_COMMA') },\n { operator: 'NIN' as OperatorString, description: this.translate.instant('NOT_IN_COLLECTION_SEPERATED_BY_COMMA') },\n */\n ];\n break;\n default:\n optionValues = [\n { operator: '' as OperatorString, description: this.translate.instant('CONTAINS') },\n { operator: '=' as OperatorString, description: '' },\n { operator: '<' as OperatorString, description: '' },\n { operator: '<=' as OperatorString, description: '' },\n { operator: '>' as OperatorString, description: '' },\n { operator: '>=' as OperatorString, description: '' },\n { operator: '<>' as OperatorString, description: '' }];\n break;\n }\n\n return optionValues;\n }\n\n /**\n * Create the DOM element\n */\n private createDomElement(searchTerm?: SearchTerm) {\n const fieldId = this.columnDef && this.columnDef.id;\n const $headerElm = this.grid.getHeaderRowColumn(fieldId);\n $($headerElm).empty();\n\n // create the DOM Select dropdown for the Operator\n this.$selectOperatorElm = $(this.buildSelectOperatorHtmlString());\n this.$filterInputElm = $(this.buildInputHtmlString());\n const $filterContainerElm = $(`<div class=\"form-group search-filter filter-${fieldId}\"></div>`);\n const $containerInputGroup = $(`<div class=\"input-group\"></div>`);\n const $operatorInputGroupAddon = $(`<div class=\"input-group-addon input-group-prepend operator\"></div>`);\n\n /* the DOM element final structure will be\n <div class=\"input-group\">\n <div class=\"input-group-addon input-group-prepend operator\">\n <select class=\"form-control\"></select>\n </div>\n <input class=\"form-control\" type=\"text\" />\n </div>\n */\n $operatorInputGroupAddon.append(this.$selectOperatorElm);\n $containerInputGroup.append($operatorInputGroupAddon);\n $containerInputGroup.append(this.$filterInputElm);\n\n // create the DOM element & add an ID and filter class\n $filterContainerElm.append($containerInputGroup);\n $filterContainerElm.attr('id', `filter-${fieldId}`);\n\n this.$filterInputElm.val(searchTerm);\n this.$filterInputElm.data('columnId', fieldId);\n\n if (this.operator) {\n this.$selectOperatorElm.val(this.operator);\n }\n\n // if there's a search term, we will add the \"filled\" class for styling purposes\n if (searchTerm) {\n $filterContainerElm.addClass('filled');\n }\n\n // append the new DOM element to the header row\n if ($filterContainerElm && typeof $filterContainerElm.appendTo === 'function') {\n $filterContainerElm.appendTo($headerElm);\n }\n\n return $filterContainerElm;\n }\n\n private onTriggerEvent(e: Event | undefined) {\n if (this._clearFilterTriggered) {\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\n this.$filterElm.removeClass('filled');\n } else {\n const selectedOperator = this.$selectOperatorElm.find('option:selected').text();\n let value = this.$filterInputElm.val();\n const enableWhiteSpaceTrim = this.gridOptions.enableFilterTrimWhiteSpace || this.columnFilter.enableTrimWhiteSpace;\n if (typeof value === 'string' && enableWhiteSpaceTrim) {\n value = value.trim();\n }\n\n (value !== null && value !== undefined && value !== '') ? this.$filterElm.addClass('filled') : this.$filterElm.removeClass('filled');\n this.callback(e, { columnDef: this.columnDef, searchTerms: (value ? [value] : null), operator: selectedOperator || '', shouldTriggerQuery: this._shouldTriggerQuery });\n }\n // reset both flags for next use\n this._clearFilterTriggered = false;\n this._shouldTriggerQuery = true;\n }\n}\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { CompoundInputFilter } from './compoundInputFilter';\r\n\r\nexport class CompoundInputNumberFilter extends CompoundInputFilter {\r\n /** Initialize the Filter */\r\n constructor(protected translate: TranslateService) {\r\n super(translate);\r\n this.inputType = 'number';\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { CompoundInputFilter } from './compoundInputFilter';\r\n\r\nexport class CompoundInputPasswordFilter extends CompoundInputFilter {\r\n /** Initialize the Filter */\r\n constructor(protected translate: TranslateService) {\r\n super(translate);\r\n this.inputType = 'password';\r\n }\r\n}\r\n","import {\r\n Column,\r\n ColumnFilter,\r\n Filter,\r\n FilterArguments,\r\n FilterCallback,\r\n GridOption,\r\n OperatorString,\r\n OperatorType,\r\n SearchTerm\r\n} from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nconst DEFAULT_MIN_VALUE = 0;\r\nconst DEFAULT_MAX_VALUE = 100;\r\nconst DEFAULT_STEP = 1;\r\n\r\nexport class CompoundSliderFilter implements Filter {\r\n private _clearFilterTriggered = false;\r\n private _shouldTriggerQuery = true;\r\n private _elementRangeInputId: string;\r\n private _elementRangeOutputId: string;\r\n private _operator: OperatorType | OperatorString;\r\n private $containerInputGroupElm: any;\r\n private $filterElm: any;\r\n private $filterInputElm: any;\r\n private $selectOperatorElm: any;\r\n grid: any;\r\n searchTerms: SearchTerm[];\r\n columnDef: Column;\r\n callback: FilterCallback;\r\n\r\n constructor() { }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get gridOptions(): GridOption {\r\n return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {};\r\n }\r\n\r\n /** Getter for the Filter Generic Params */\r\n private get filterParams(): any {\r\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.params || {};\r\n }\r\n\r\n /** Getter for the `filter` properties */\r\n private get filterProperties(): ColumnFilter {\r\n return this.columnDef && this.columnDef.filter;\r\n }\r\n\r\n set operator(op: OperatorType | OperatorString) {\r\n this._operator = op;\r\n }\r\n\r\n get operator(): OperatorType | OperatorString {\r\n return this._operator || OperatorType.empty;\r\n }\r\n\r\n /**\r\n * Initialize the Filter\r\n */\r\n init(args: FilterArguments) {\r\n if (args) {\r\n this.grid = args.grid;\r\n this.callback = args.callback;\r\n this.columnDef = args.columnDef;\r\n this.operator = args.operator || '';\r\n this.searchTerms = args.searchTerms || [];\r\n\r\n // define the input & slider number IDs\r\n this._elementRangeInputId = `rangeInput_${this.columnDef.field}`;\r\n this._elementRangeOutputId = `rangeOutput_${this.columnDef.field}`;\r\n\r\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\r\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\r\n\r\n // step 1, create the DOM Element of the filter which contain the compound Operator+Input\r\n // and initialize it if searchTerm is filled\r\n this.$filterElm = this.createDomElement(searchTerm);\r\n\r\n // step 3, subscribe to the keyup event and run the callback when that happens\r\n // also add/remove \"filled\" class for styling purposes\r\n this.$filterInputElm.change((e: any) => {\r\n this.onTriggerEvent(e);\r\n });\r\n this.$selectOperatorElm.change((e: any) => {\r\n this.onTriggerEvent(e);\r\n });\r\n\r\n // if user chose to display the slider number on the right side, then update it every time it changes\r\n // we need to use both \"input\" and \"change\" event to be all cross-browser\r\n if (!this.filterParams.hideSliderNumber) {\r\n this.$filterInputElm.on('input change', (e: { target: HTMLInputElement }) => {\r\n const value = e && e.target && e.target.value || '';\r\n if (value) {\r\n document.getElementById(this._elementRangeOutputId).innerHTML = value;\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear the filter value\r\n */\r\n clear(shouldTriggerQuery = true) {\r\n if (this.$filterElm && this.$selectOperatorElm) {\r\n this._clearFilterTriggered = true;\r\n this._shouldTriggerQuery = shouldTriggerQuery;\r\n this.searchTerms = [];\r\n const clearedValue = this.filterParams.hasOwnProperty('sliderStartValue') ? this.filterParams.sliderStartValue : DEFAULT_MIN_VALUE;\r\n this.$selectOperatorElm.val(0);\r\n this.$filterInputElm.val(clearedValue);\r\n if (!this.filterParams.hideSliderNumber) {\r\n this.$containerInputGroupElm.children('div.input-group-addon.input-group-append').children().last().html(clearedValue);\r\n }\r\n this.onTriggerEvent(undefined);\r\n this.$filterElm.removeClass('filled');\r\n }\r\n }\r\n\r\n /**\r\n * destroy the filter\r\n */\r\n destroy() {\r\n if (this.$filterElm) {\r\n this.$filterElm.off('input change').remove();\r\n }\r\n }\r\n\r\n /**\r\n * Set value(s) on the DOM element\r\n */\r\n setValues(values: SearchTerm[]) {\r\n if (values && Array.isArray(values)) {\r\n this.$filterInputElm.val(values[0]);\r\n this.$containerInputGroupElm.children('div.input-group-addon.input-group-append').children().last().html(values[0]);\r\n }\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n\r\n /** Build HTML Template for the input range (slider) */\r\n private buildTemplateHtmlString() {\r\n const minValue = this.filterProperties.hasOwnProperty('minValue') ? this.filterProperties.minValue : DEFAULT_MIN_VALUE;\r\n const maxValue = this.filterProperties.hasOwnProperty('maxValue') ? this.filterProperties.maxValue : DEFAULT_MAX_VALUE;\r\n const defaultValue = this.filterParams.hasOwnProperty('sliderStartValue') ? this.filterParams.sliderStartValue : minValue;\r\n const step = this.filterProperties.hasOwnProperty('valueStep') ? this.filterProperties.valueStep : DEFAULT_STEP;\r\n\r\n return `<input type=\"range\" id=\"${this._elementRangeInputId}\"\r\n name=\"${this._elementRangeInputId}\"\r\n defaultValue=\"${defaultValue}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${step}\"\r\n class=\"form-control slider-filter-input range compound-slider\" />`;\r\n }\r\n\r\n /** Build HTML Template for the text (number) that is shown appended to the slider */\r\n private buildTemplateSliderTextHtmlString() {\r\n const minValue = this.filterProperties.hasOwnProperty('minValue') ? this.filterProperties.minValue : DEFAULT_MIN_VALUE;\r\n const defaultValue = this.filterParams.hasOwnProperty('sliderStartValue') ? this.filterParams.sliderStartValue : minValue;\r\n\r\n return `<div class=\"input-group-addon input-group-append slider-value\"><span class=\"input-group-text\" id=\"${this._elementRangeOutputId}\">${defaultValue}</span></div>`;\r\n }\r\n\r\n /** Build HTML Template select dropdown (operator) */\r\n private buildSelectOperatorHtmlString() {\r\n const optionValues = this.getOptionValues();\r\n let optionValueString = '';\r\n optionValues.forEach((option) => {\r\n optionValueString += `<option value=\"${option.operator}\" title=\"${option.description}\">${option.operator}</option>`;\r\n });\r\n\r\n return `<select class=\"form-control\">${optionValueString}</select>`;\r\n }\r\n\r\n /** Get the available operator option values */\r\n private getOptionValues(): { operator: OperatorString, description: string }[] {\r\n return [\r\n { operator: '' as OperatorString, description: '' },\r\n { operator: '=' as OperatorString, description: '' },\r\n { operator: '<' as OperatorString, description: '' },\r\n { operator: '<=' as OperatorString, description: '' },\r\n { operator: '>' as OperatorString, description: '' },\r\n { operator: '>=' as OperatorString, description: '' },\r\n { operator: '<>' as OperatorString, description: '' }\r\n ];\r\n }\r\n\r\n /**\r\n * Create the DOM element\r\n */\r\n private createDomElement(searchTerm?: SearchTerm) {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const searchTermInput = (searchTerm || '0') as string;\r\n const $headerElm = this.grid.getHeaderRowColumn(this.columnDef.id);\r\n $($headerElm).empty();\r\n\r\n // create the DOM Select dropdown for the Operator\r\n this.$selectOperatorElm = $(this.buildSelectOperatorHtmlString());\r\n this.$filterInputElm = $(this.buildTemplateHtmlString());\r\n const $filterContainerElm = $(`<div class=\"form-group search-filter filter-${fieldId}\"></div>`);\r\n this.$containerInputGroupElm = $(`<div class=\"input-group search-filter filter-${fieldId}\"></div>`);\r\n const $operatorInputGroupAddon = $(`<span class=\"input-group-addon input-group-prepend operator\"></span>`);\r\n\r\n /* the DOM element final structure will be\r\n <div class=\"input-group\">\r\n <div class=\"input-group-addon input-group-prepend operator\">\r\n <select class=\"form-control\"></select>\r\n </div>\r\n <input class=\"form-control\" type=\"text\" />\r\n <div class=\"input-group-addon input-group-prepend\" id=\"rangeOuput_percentComplete\"><span class=\"input-group-text\">0</span></div>\r\n </div>\r\n */\r\n $operatorInputGroupAddon.append(this.$selectOperatorElm);\r\n this.$containerInputGroupElm.append($operatorInputGroupAddon);\r\n this.$containerInputGroupElm.append(this.$filterInputElm);\r\n if (!this.filterParams.hideSliderNumber) {\r\n const $sliderTextInputAppendAddon = $(this.buildTemplateSliderTextHtmlString());\r\n $sliderTextInputAppendAddon.children().html(searchTermInput);\r\n this.$containerInputGroupElm.append($sliderTextInputAppendAddon);\r\n }\r\n\r\n // create the DOM element & add an ID and filter class\r\n $filterContainerElm.append(this.$containerInputGroupElm);\r\n $filterContainerElm.attr('id', `filter-${fieldId}`);\r\n\r\n this.$filterInputElm.val(searchTermInput);\r\n this.$filterInputElm.data('columnId', fieldId);\r\n\r\n if (this.operator) {\r\n this.$selectOperatorElm.val(this.operator);\r\n }\r\n\r\n // if there's a search term, we will add the \"filled\" class for styling purposes\r\n if (searchTerm) {\r\n $filterContainerElm.addClass('filled');\r\n }\r\n\r\n // append the new DOM element to the header row\r\n if ($filterContainerElm && typeof $filterContainerElm.appendTo === 'function') {\r\n $filterContainerElm.appendTo($headerElm);\r\n }\r\n\r\n return $filterContainerElm;\r\n }\r\n\r\n private onTriggerEvent(e: Event | undefined) {\r\n if (this._clearFilterTriggered) {\r\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\r\n } else {\r\n const selectedOperator = this.$selectOperatorElm.find('option:selected').text();\r\n const value = this.$filterInputElm.val();\r\n (value) ? this.$filterElm.addClass('filled') : this.$filterElm.removeClass('filled');\r\n this.callback(e, { columnDef: this.columnDef, searchTerms: (value ? [value] : null), operator: selectedOperator || '', shouldTriggerQuery: this._shouldTriggerQuery });\r\n }\r\n // reset both flags for next use\r\n this._clearFilterTriggered = false;\r\n this._shouldTriggerQuery = true;\r\n }\r\n}\r\n","import {\n Column,\n ColumnFilter,\n Filter,\n FilterArguments,\n FilterCallback,\n GridOption,\n OperatorType,\n OperatorString,\n SearchTerm,\n} from './../models/index';\n\n// using external non-typed js libraries\ndeclare var $: any;\n\nexport class InputFilter implements Filter {\n protected _clearFilterTriggered = false;\n protected _shouldTriggerQuery = true;\n protected _inputType = 'text';\n protected $filterElm: any;\n grid: any;\n searchTerms: SearchTerm[];\n columnDef: Column;\n callback: FilterCallback;\n\n constructor() { }\n\n /** Getter for the Column Filter */\n get columnFilter(): ColumnFilter {\n return this.columnDef && this.columnDef.filter || {};\n }\n\n /** Getter of input type (text, number, password) */\n get inputType() {\n return this._inputType;\n }\n\n /** Setter of input type (text, number, password) */\n set inputType(type: string) {\n this._inputType = type;\n }\n\n /** Getter of the Operator to use when doing the filter comparing */\n get operator(): OperatorType | OperatorString {\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.operator || '';\n }\n\n /** Getter for the Grid Options pulled through the Grid Object */\n protected get gridOptions(): GridOption {\n return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {};\n }\n\n /**\n * Initialize the Filter\n */\n init(args: FilterArguments) {\n this.grid = args.grid;\n this.callback = args.callback;\n this.columnDef = args.columnDef;\n this.searchTerms = args.searchTerms || [];\n\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\n\n // step 1, create HTML string template\n const filterTemplate = this.buildTemplateHtmlString();\n\n // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled\n this.$filterElm = this.createDomElement(filterTemplate, searchTerm);\n\n // step 3, subscribe to the keyup event and run the callback when that happens\n // also add/remove \"filled\" class for styling purposes\n this.$filterElm.on('keyup input change', (e: any) => {\n let value = e && e.target && e.target.value || '';\n const enableWhiteSpaceTrim = this.gridOptions.enableFilterTrimWhiteSpace || this.columnFilter.enableTrimWhiteSpace;\n if (typeof value === 'string' && enableWhiteSpaceTrim) {\n value = value.trim();\n }\n\n if (this._clearFilterTriggered) {\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\n this.$filterElm.removeClass('filled');\n } else {\n value === '' ? this.$filterElm.removeClass('filled') : this.$filterElm.addClass('filled');\n this.callback(e, { columnDef: this.columnDef, operator: this.operator, searchTerms: [value], shouldTriggerQuery: this._shouldTriggerQuery });\n }\n // reset both flags for next use\n this._clearFilterTriggered = false;\n this._shouldTriggerQuery = true;\n });\n }\n\n /**\n * Clear the filter value\n */\n clear(shouldTriggerQuery = true) {\n if (this.$filterElm) {\n this._clearFilterTriggered = true;\n this._shouldTriggerQuery = shouldTriggerQuery;\n this.searchTerms = [];\n this.$filterElm.val('');\n this.$filterElm.trigger('keyup');\n }\n }\n\n /**\n * destroy the filter\n */\n destroy() {\n if (this.$filterElm) {\n this.$filterElm.off('keyup input change').remove();\n }\n }\n\n /**\n * Set value(s) on the DOM element\n */\n setValues(values: SearchTerm) {\n if (values) {\n this.$filterElm.val(values);\n }\n }\n\n //\n // protected functions\n // ------------------\n\n /**\n * Create the HTML template as a string\n */\n protected buildTemplateHtmlString() {\n const fieldId = this.columnDef && this.columnDef.id;\n let placeholder = (this.gridOptions) ? (this.gridOptions.defaultFilterPlaceholder || '') : '';\n if (this.columnFilter && this.columnFilter.placeholder) {\n placeholder = this.columnFilter.placeholder;\n }\n return `<input type=\"${this._inputType || 'text'}\" role=\"presentation\" autocomplete=\"off\" class=\"form-control search-filter filter-${fieldId}\" placeholder=\"${placeholder}\"><span></span>`;\n }\n\n /**\n * From the html template string, create a DOM element\n * @param filterTemplate\n */\n protected createDomElement(filterTemplate: string, searchTerm?: SearchTerm) {\n const fieldId = this.columnDef && this.columnDef.id;\n const $headerElm = this.grid.getHeaderRowColumn(fieldId);\n $($headerElm).empty();\n\n // create the DOM element & add an ID and filter class\n const $filterElm = $(filterTemplate);\n\n $filterElm.val(searchTerm);\n $filterElm.attr('id', `filter-${fieldId}`);\n $filterElm.data('columnId', fieldId);\n\n // if there's a search term, we will add the \"filled\" class for styling purposes\n if (searchTerm) {\n $filterElm.addClass('filled');\n }\n\n // append the new DOM element to the header row\n if ($filterElm && typeof $filterElm.appendTo === 'function') {\n $filterElm.appendTo($headerElm);\n }\n\n return $filterElm;\n }\n}\n","import { InputFilter } from './inputFilter';\r\nimport { FilterArguments } from '../models/filterArguments.interface';\r\n\r\nexport class InputMaskFilter extends InputFilter {\r\n /** Initialize the Filter */\r\n constructor() {\r\n super();\r\n this.inputType = 'text';\r\n }\r\n\r\n /** Getter of the input mask, when provided */\r\n get inputMask(): string {\r\n return this.columnDef.params && this.columnDef.params && this.columnDef.params.mask;\r\n }\r\n\r\n /**\r\n * Override the Filter init used by SlickGrid\r\n */\r\n init(args: FilterArguments) {\r\n if (!args) {\r\n throw new Error('[Angular-SlickGrid] A filter must always have an \"init()\" with valid arguments.');\r\n }\r\n this.grid = args.grid;\r\n this.callback = args.callback;\r\n this.columnDef = args.columnDef;\r\n this.searchTerms = args.searchTerms || [];\r\n\r\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\r\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\r\n\r\n // step 1, create HTML string template\r\n const filterTemplate = this.buildTemplateHtmlString();\r\n\r\n // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled\r\n this.$filterElm = this.createDomElement(filterTemplate, searchTerm);\r\n\r\n // step 3, subscribe to the keyup event and run the callback when that happens\r\n // also add/remove \"filled\" class for styling purposes\r\n\r\n this.$filterElm.on('keyup input change', (e: any) => {\r\n let value = '';\r\n if (e && e.target && e.target.value) {\r\n let targetValue = e.target.value;\r\n const enableWhiteSpaceTrim = this.gridOptions.enableFilterTrimWhiteSpace || this.columnFilter.enableTrimWhiteSpace;\r\n if (typeof targetValue === 'string' && enableWhiteSpaceTrim) {\r\n targetValue = targetValue.trim();\r\n }\r\n\r\n // if it has a mask, we need to do a bit more work\r\n // and replace the filter string by the masked output without triggering an event\r\n const unmaskedValue = this.unmaskValue(targetValue);\r\n const maskedValue = this.maskValue(unmaskedValue);\r\n value = unmaskedValue;\r\n\r\n if (e.keyCode >= 48) {\r\n this.$filterElm.val(maskedValue); // replace filter string with masked string\r\n e.preventDefault();\r\n }\r\n }\r\n\r\n if (this._clearFilterTriggered) {\r\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\r\n this.$filterElm.removeClass('filled');\r\n } else {\r\n this.$filterElm.addClass('filled');\r\n this.callback(e, { columnDef: this.columnDef, operator: this.operator, searchTerms: [value], shouldTriggerQuery: this._shouldTriggerQuery });\r\n }\r\n // reset both flags for next use\r\n this._clearFilterTriggered = false;\r\n this._shouldTriggerQuery = true;\r\n });\r\n }\r\n\r\n /** From a regular string, we will use the mask to output a new string */\r\n private maskValue(inputValue: string): string {\r\n let i = 0;\r\n let maskedValue = '';\r\n\r\n if (this.inputMask) {\r\n maskedValue = this.inputMask.replace(/[09A]/gi, (match) => {\r\n // only replace the char when the mask is a 0 or 9 for a digit OR the mask is \"A\" and the char is a non-digit meaning a string char\r\n if (\r\n ((match === '0' || match === '9') && /\\d+/g.test(inputValue[i])) // mask is 0 or 9 and value is a digit\r\n || (match.toUpperCase() === 'A' && /[^\\d]+/gi.test(inputValue[i])) // OR mask is an \"A\" and value is non-digit\r\n ) {\r\n return inputValue[i++] || '';\r\n }\r\n return '';\r\n });\r\n }\r\n\r\n return maskedValue;\r\n }\r\n\r\n /** From a masked string, we will remove the mask and make a regular string again */\r\n private unmaskValue(maskedValue: string): string {\r\n // remove anything else but digits and chars from both the input mask and the input masked value for later comparison\r\n // e.g. (000) 000-0000 would return 0000000000\r\n const valueWithoutSymbols = maskedValue.replace(/[^0-9a-z]*/gi, '');\r\n const maskWithoutSymbols = this.inputMask.replace(/[^0-9a-z]*/gi, '');\r\n\r\n // then we can analyze if each char on each indexes equals what the mask requires, if not the char will be disregarded from the output\r\n // basically, if our mask is \"0A0\" and input value is \"2ab\", then only \"2a\" will be returned since the last char \"b\" is not part of the mask and is invalid\r\n let output = '';\r\n for (let i = 0; i < maskWithoutSymbols.length; i++) {\r\n if (valueWithoutSymbols[i]) {\r\n if (\r\n ((maskWithoutSymbols[i] === '0' || maskWithoutSymbols[i] === '9') && /\\d+/g.test(valueWithoutSymbols[i])) // mask is 0 or 9 and value is a digit\r\n || (maskWithoutSymbols[i].toUpperCase() === 'A' && /[^\\d]+/gi.test(valueWithoutSymbols[i])) // OR mask is an \"A\" and value is non-digit\r\n ) {\r\n output += valueWithoutSymbols[i]; // valid and matches the Mask, so we can add it up to the string output\r\n }\r\n }\r\n }\r\n\r\n return output;\r\n }\r\n}\r\n","import { InputFilter } from './inputFilter';\r\n\r\nexport class InputNumberFilter extends InputFilter {\r\n /** Initialize the Filter */\r\n constructor() {\r\n super();\r\n this.inputType = 'number';\r\n }\r\n}\r\n","import { InputFilter } from './inputFilter';\r\n\r\nexport class InputPasswordFilter extends InputFilter {\r\n /** Initialize the Filter */\r\n constructor() {\r\n super();\r\n this.inputType = 'password';\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport {\r\n CollectionCustomStructure,\r\n CollectionOption,\r\n Column,\r\n ColumnFilter,\r\n Filter,\r\n FilterArguments,\r\n FilterCallback,\r\n GridOption,\r\n MultipleSelectOption,\r\n OperatorType,\r\n OperatorString,\r\n SearchTerm,\r\n SelectOption,\r\n} from './../models/index';\r\nimport { CollectionService } from './../services/collection.service';\r\nimport { castToPromise, getDescendantProperty, htmlEncode, unsubscribeAllObservables } from '../services/utilities';\r\nimport { Observable, Subject, Subscription } from 'rxjs';\r\nimport * as DOMPurify_ from 'dompurify';\r\nconst DOMPurify = DOMPurify_; // patch to fix rollup to work\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nexport class SelectFilter implements Filter {\r\n private _isFilterFirstRender = true;\r\n private _shouldTriggerQuery = true;\r\n\r\n /** DOM Element Name, useful for auto-detecting positioning (dropup / dropdown) */\r\n elementName: string;\r\n\r\n /** Filter Multiple-Select options */\r\n filterElmOptions: MultipleSelectOption;\r\n\r\n /** The JQuery DOM element */\r\n $filterElm: any;\r\n\r\n grid: any;\r\n searchTerms: SearchTerm[];\r\n columnDef: Column;\r\n callback: FilterCallback;\r\n defaultOptions: MultipleSelectOption;\r\n isFilled = false;\r\n labelName: string;\r\n labelPrefixName: string;\r\n labelSuffixName: string;\r\n optionLabel: string;\r\n valueName: string;\r\n enableTranslateLabel = false;\r\n subscriptions: Subscription[] = [];\r\n\r\n /**\r\n * Initialize the Filter\r\n */\r\n constructor(protected translate: TranslateService, protected collectionService: CollectionService, protected isMultipleSelect = true) {\r\n // default options used by this Filter, user can overwrite any of these by passing \"otions\"\r\n const options: MultipleSelectOption = {\r\n autoAdjustDropHeight: true,\r\n autoAdjustDropPosition: true,\r\n autoAdjustDropWidthByTextSize: true,\r\n container: 'body',\r\n filter: false, // input search term on top of the select option list\r\n maxHeight: 275,\r\n single: true,\r\n\r\n textTemplate: ($elm) => {\r\n // render HTML code or not, by default it is sanitized and won't be rendered\r\n const isRenderHtmlEnabled = this.columnDef && this.columnDef.filter && this.columnDef.filter.enableRenderHtml || false;\r\n return isRenderHtmlEnabled ? $elm.text() : $elm.html();\r\n },\r\n onClose: () => {\r\n // we will subscribe to the onClose event for triggering our callback\r\n // also add/remove \"filled\" class for styling purposes\r\n const selectedItems = this.$filterElm.multipleSelect('getSelects');\r\n if (Array.isArray(selectedItems) && selectedItems.length > 1 || (selectedItems.length === 1 && selectedItems[0] !== '')) {\r\n this.isFilled = true;\r\n this.$filterElm.addClass('filled').siblings('div .search-filter').addClass('filled');\r\n } else {\r\n this.isFilled = false;\r\n this.$filterElm.removeClass('filled');\r\n this.$filterElm.siblings('div .search-filter').removeClass('filled');\r\n }\r\n\r\n this.callback(undefined, { columnDef: this.columnDef, operator: this.operator, searchTerms: selectedItems, shouldTriggerQuery: this._shouldTriggerQuery });\r\n // reset flag for next use\r\n this._shouldTriggerQuery = true;\r\n }\r\n };\r\n\r\n if (this.isMultipleSelect) {\r\n options.single = false;\r\n options.okButton = true;\r\n options.addTitle = true; // show tooltip of all selected items while hovering the filter\r\n options.countSelected = this.translate.instant('X_OF_Y_SELECTED');\r\n options.allSelected = this.translate.instant('ALL_SELECTED');\r\n options.selectAllText = this.translate.instant('SELECT_ALL');\r\n options.selectAllDelimiter = ['', '']; // remove default square brackets of default text \"[Select All]\" => \"Select All\"\r\n }\r\n\r\n this.defaultOptions = options;\r\n }\r\n\r\n /** Getter for the Column Filter itself */\r\n protected get columnFilter(): ColumnFilter {\r\n return this.columnDef && this.columnDef.filter;\r\n }\r\n\r\n /** Getter for the Collection Options */\r\n protected get collectionOptions(): CollectionOption {\r\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.collectionOptions;\r\n }\r\n\r\n /** Getter for the Custom Structure if exist */\r\n protected get customStructure(): CollectionCustomStructure {\r\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.customStructure;\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n protected get gridOptions(): GridOption {\r\n return (this.grid && this.grid.getOptions) ? this.grid.getOptions() : {};\r\n }\r\n\r\n /** Getter for the filter operator */\r\n get operator(): OperatorType | OperatorString {\r\n if (this.columnDef && this.columnDef.filter && this.columnDef.filter.operator) {\r\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.operator;\r\n }\r\n return this.isMultipleSelect ? OperatorType.in : OperatorType.equal;\r\n }\r\n\r\n /**\r\n * Initialize the filter template\r\n */\r\n init(args: FilterArguments, isFilterFirstRender: boolean) {\r\n this._isFilterFirstRender = isFilterFirstRender;\r\n this.grid = args.grid;\r\n this.callback = args.callback;\r\n this.columnDef = args.columnDef;\r\n this.searchTerms = args.searchTerms || [];\r\n\r\n if (!this.grid || !this.columnDef || !this.columnFilter || (!this.columnFilter.collection && !this.columnFilter.collectionAsync)) {\r\n throw new Error(`[Angular-SlickGrid] You need to pass a \"collection\" (or \"collectionAsync\") for the MultipleSelect/SingleSelect Filter to work correctly. Also each option should include a value/label pair (or value/labelKey when using Locale). For example:: { filter: model: Filters.multipleSelect, collection: [{ value: true, label: 'True' }, { value: false, label: 'False'}] }`);\r\n }\r\n\r\n this.enableTranslateLabel = this.columnFilter.enableTranslateLabel;\r\n this.labelName = this.customStructure && this.customStructure.label || 'label';\r\n this.labelPrefixName = this.customStructure && this.customStructure.labelPrefix || 'labelPrefix';\r\n this.labelSuffixName = this.customStructure && this.customStructure.labelSuffix || 'labelSuffix';\r\n this.optionLabel = this.customStructure && this.customStructure.optionLabel || 'value';\r\n this.valueName = this.customStructure && this.customStructure.value || 'value';\r\n\r\n if (this.enableTranslateLabel && (!this.translate || typeof this.translate.instant !== 'function')) {\r\n throw new Error(`[select-editor] The ngx-translate TranslateService is required for the Select Filter to work correctly`);\r\n }\r\n\r\n // always render the Select (dropdown) DOM element, even if user passed a \"collectionAsync\",\r\n // if that is the case, the Select will simply be without any options but we still have to render it (else SlickGrid would throw an error)\r\n const newCollection = this.columnFilter.collection || [];\r\n this.renderDomElement(newCollection);\r\n\r\n // on every Filter which have a \"collection\" or a \"collectionAsync\"\r\n // we will add (or replace) a Subject to the \"collectionAsync\" property so that user has possibility to change the collection\r\n // if \"collectionAsync\" is already set by the user, it will resolve it first then after it will replace it with a Subject\r\n const collectionAsync = this.columnFilter && this.columnFilter.collectionAsync;\r\n if (collectionAsync) {\r\n this.renderOptionsAsync(collectionAsync); // create Subject after resolve (createCollectionAsyncSubject)\r\n }\r\n }\r\n\r\n /**\r\n * Clear the filter values\r\n */\r\n clear(shouldTriggerQuery = true) {\r\n if (this.$filterElm && this.$filterElm.multipleSelect) {\r\n // reload the filter element by it's id, to make sure it's still a valid element (because of some issue in the GraphQL example)\r\n this.$filterElm.multipleSelect('setSelects', []);\r\n this.$filterElm.removeClass('filled');\r\n this.$filterElm.siblings('div .search-filter').removeClass('filled');\r\n this.searchTerms = [];\r\n this._shouldTriggerQuery = shouldTriggerQuery;\r\n this.callback(undefined, { columnDef: this.columnDef, clearFilterTriggered: true, shouldTriggerQuery: this._shouldTriggerQuery });\r\n // reset both flags for next use\r\n this._shouldTriggerQuery = true;\r\n }\r\n }\r\n\r\n /**\r\n * destroy the filter\r\n */\r\n destroy() {\r\n if (this.$filterElm) {\r\n // remove event watcher\r\n this.$filterElm.off().remove();\r\n const elementClassName = this.elementName.toString().replace('.', '\\\\.'); // make sure to escape any dot \".\" from CSS class to avoid console error\r\n $(`[name=${elementClassName}].ms-drop`).remove();\r\n }\r\n\r\n // also dispose of all Subscriptions\r\n this.subscriptions = unsubscribeAllObservables(this.subscriptions);\r\n }\r\n\r\n /**\r\n * Set value(s) on the DOM element\r\n */\r\n setValues(values: SearchTerm | SearchTerm[]) {\r\n if (values) {\r\n values = Array.isArray(values) ? values : [values];\r\n this.$filterElm.multipleSelect('setSelects', values);\r\n }\r\n }\r\n\r\n //\r\n // protected functions\r\n // ------------------\r\n\r\n /**\r\n * user might want to filter certain items of the collection\r\n * @param inputCollection\r\n * @return outputCollection filtered and/or sorted collection\r\n */\r\n protected filterCollection(inputCollection) {\r\n let outputCollection = inputCollection;\r\n\r\n // user might want to filter certain items of the collection\r\n if (this.columnDef && this.columnFilter && this.columnFilter.collectionFilterBy) {\r\n const filterBy = this.columnFilter.collectionFilterBy;\r\n const filterCollectionBy = this.columnFilter.collectionOptions && this.columnFilter.collectionOptions.filterResultAfterEachPass || null;\r\n outputCollection = this.collectionService.filterCollection(outputCollection, filterBy, filterCollectionBy);\r\n }\r\n\r\n return outputCollection;\r\n }\r\n\r\n /**\r\n * user might want to sort the collection in a certain way\r\n * @param inputCollection\r\n * @return outputCollection filtered and/or sorted collection\r\n */\r\n protected sortCollection(inputCollection) {\r\n let outputCollection = inputCollection;\r\n\r\n // user might want to sort the collection\r\n if (this.columnDef && this.columnFilter && this.columnFilter.collectionSortBy) {\r\n const sortBy = this.columnFilter.collectionSortBy;\r\n outputCollection = this.collectionService.sortCollection(this.columnDef, outputCollection, sortBy, this.enableTranslateLabel);\r\n }\r\n\r\n return outputCollection;\r\n }\r\n\r\n protected async renderOptionsAsync(collectionAsync: Promise<any> | Observable<any> | Subject<any>) {\r\n let awaitedCollection: any = [];\r\n\r\n if (collectionAsync) {\r\n awaitedCollection = await castToPromise(collectionAsync);\r\n this.renderDomElementFromCollectionAsync(awaitedCollection);\r\n\r\n // because we accept Promises & HttpClient Observable only execute once\r\n // we will re-create an RxJs Subject which will replace the \"collectionAsync\" which got executed once anyway\r\n // doing this provide the user a way to call a \"collectionAsync.next()\"\r\n this.createCollectionAsyncSubject();\r\n }\r\n }\r\n\r\n /** Create or recreate an Observable Subject and reassign it to the \"collectionAsync\" object so user can call a \"collectionAsync.next()\" on it */\r\n protected createCollectionAsyncSubject() {\r\n const newCollectionAsync = new Subject<any>();\r\n this.columnFilter.collectionAsync = newCollectionAsync;\r\n this.subscriptions.push(\r\n newCollectionAsync.subscribe(collection => this.renderDomElementFromCollectionAsync(collection))\r\n );\r\n }\r\n\r\n /**\r\n * When user use a CollectionAsync we will use the returned collection to render the filter DOM element\r\n * and reinitialize filter collection with this new collection\r\n */\r\n protected renderDomElementFromCollectionAsync(collection) {\r\n if (this.collectionOptions && this.collectionOptions.collectionInObjectProperty) {\r\n collection = getDescendantProperty(collection, this.collectionOptions.collectionInObjectProperty);\r\n }\r\n if (!Array.isArray(collection)) {\r\n throw new Error('Something went wrong while trying to pull the collection from the \"collectionAsync\" call in the Select Filter, the collection is not a valid array.');\r\n }\r\n\r\n // copy over the array received from the async call to the \"collection\" as the new collection to use\r\n // this has to be BEFORE the `collectionObserver().subscribe` to avoid going into an infinite loop\r\n this.columnFilter.collection = collection;\r\n\r\n // recreate Multiple Select after getting async collection\r\n this.renderDomElement(collection);\r\n }\r\n\r\n protected renderDomElement(collection) {\r\n if (!Array.isArray(collection) && this.collectionOptions && this.collectionOptions.collectionInObjectProperty) {\r\n collection = getDescendantProperty(collection, this.collectionOptions.collectionInObjectProperty);\r\n }\r\n if (!Array.isArray(collection)) {\r\n throw new Error('The \"collection\" passed to the Select Filter is not a valid array');\r\n }\r\n\r\n // user can optionally add a blank entry at the beginning of the collection\r\n if (this.collectionOptions && this.collectionOptions.addBlankEntry && this._isFilterFirstRender) {\r\n collection.unshift(this.createBlankEntry());\r\n }\r\n\r\n let newCollection = collection;\r\n\r\n // user might want to filter and/or sort certain items of the collection\r\n newCollection = this.filterCollection(newCollection);\r\n newCollection = this.sortCollection(newCollection);\r\n\r\n // step 1, create HTML string template\r\n const filterTemplate = this.buildTemplateHtmlString(newCollection, this.searchTerms);\r\n\r\n // step 2, create the DOM Element of the filter & pre-load search terms\r\n // also subscribe to the onClose event\r\n this.createDomElement(filterTemplate);\r\n }\r\n\r\n /**\r\n * Create the HTML template as a string\r\n */\r\n protected buildTemplateHtmlString(optionCollection: any[], searchTerms: SearchTerm[]) {\r\n let options = '';\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const separatorBetweenLabels = this.collectionOptions && this.collectionOptions.separatorBetweenTextLabels || '';\r\n const isRenderHtmlEnabled = this.columnFilter && this.columnFilter.enableRenderHtml || false;\r\n const sanitizedOptions = this.gridOptions && this.gridOptions.sanitizeHtmlOptions || {};\r\n\r\n // collection could be an Array of Strings OR Objects\r\n if (optionCollection.every(x => typeof x === 'string')) {\r\n optionCollection.forEach((option: string) => {\r\n const selected = (searchTerms.findIndex((term) => term === option) >= 0) ? 'selected' : '';\r\n options += `<option value=\"${option}\" label=\"${option}\" ${selected}>${option}</option>`;\r\n\r\n // if there's at least 1 search term found, we will add the \"filled\" class for styling purposes\r\n if (selected) {\r\n this.isFilled = true;\r\n }\r\n });\r\n } else {\r\n // array of objects will require a label/value pair unless a customStructure is passed\r\n optionCollection.forEach((option: SelectOption) => {\r\n if (!option || (option[this.labelName] === undefined && option.labelKey === undefined)) {\r\n throw new Error(`[select-filter] A collection with value/label (or value/labelKey when using Locale) is required to populate the Select list, for example:: { filter: model: Filters.multipleSelect, collection: [ { value: '1', label: 'One' } ]')`);\r\n }\r\n const labelKey = (option.labelKey || option[this.labelName]) as string;\r\n const selected = (searchTerms.findIndex((term) => term === option[this.valueName]) >= 0) ? 'selected' : '';\r\n const labelText = ((option.labelKey || this.enableTranslateLabel) && labelKey) ? this.translate.instant(labelKey || ' ') : labelKey;\r\n let prefixText = option[this.labelPrefixName] || '';\r\n let suffixText = option[this.labelSuffixName] || '';\r\n let optionLabel = option[this.optionLabel] || '';\r\n optionLabel = optionLabel.toString().replace(/\\\"/g, '\\''); // replace double quotes by single quotes to avoid interfering with regular html\r\n\r\n // also translate prefix/suffix if enableTranslateLabel is true and text is a string\r\n prefixText = (this.enableTranslateLabel && prefixText && typeof prefixText === 'string') ? this.translate.instant(prefixText || ' ') : prefixText;\r\n suffixText = (this.enableTranslateLabel && suffixText && typeof suffixText === 'string') ? this.translate.instant(suffixText || ' ') : suffixText;\r\n optionLabel = (this.enableTranslateLabel && optionLabel && typeof optionLabel === 'string') ? this.translate.instant(optionLabel || ' ') : optionLabel;\r\n\r\n // add to a temp array for joining purpose and filter out empty text\r\n const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text);\r\n let optionText = tmpOptionArray.join(separatorBetweenLabels);\r\n\r\n // if user specifically wants to render html text, he needs to opt-in else it will stripped out by default\r\n // also, the 3rd party lib will saninitze any html code unless it's encoded, so we'll do that\r\n if (isRenderHtmlEnabled) {\r\n // sanitize any unauthorized html tags like script and others\r\n // for the remaining allowed tags we'll permit all attributes\r\n const sanitizedText = DOMPurify.sanitize(optionText, sanitizedOptions);\r\n optionText = htmlEncode(sanitizedText);\r\n }\r\n\r\n // html text of each select option\r\n options += `<option value=\"${option[this.valueName]}\" label=\"${optionLabel}\" ${selected}>${optionText}</option>`;\r\n\r\n // if there's at least 1 search term found, we will add the \"filled\" class for styling purposes\r\n if (selected) {\r\n this.isFilled = true;\r\n }\r\n });\r\n }\r\n\r\n return `<select class=\"ms-filter search-filter filter-${fieldId}\" ${this.isMultipleSelect ? 'multiple=\"multiple\"' : ''}>${options}</select>`;\r\n }\r\n\r\n /** Create a blank entry that can be added to the collection. It will also reuse the same customStructure if need be */\r\n protected createBlankEntry() {\r\n const blankEntry = {\r\n [this.labelName]: '',\r\n [this.valueName]: ''\r\n };\r\n if (this.labelPrefixName) {\r\n blankEntry[this.labelPrefixName] = '';\r\n }\r\n if (this.labelSuffixName) {\r\n blankEntry[this.labelSuffixName] = '';\r\n }\r\n return blankEntry;\r\n }\r\n\r\n /**\r\n * From the html template string, create a DOM element\r\n * Subscribe to the onClose event and run the callback when that happens\r\n * @param filterTemplate\r\n */\r\n protected createDomElement(filterTemplate: string) {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n\r\n // provide the name attribute to the DOM element which will be needed to auto-adjust drop position (dropup / dropdown)\r\n this.elementName = `filter-${fieldId}`;\r\n this.defaultOptions.name = this.elementName;\r\n\r\n const $headerElm = this.grid.getHeaderRowColumn(fieldId);\r\n $($headerElm).empty();\r\n\r\n // create the DOM element & add an ID and filter class\r\n this.$filterElm = $(filterTemplate);\r\n if (typeof this.$filterElm.multipleSelect !== 'function') {\r\n throw new Error(`multiple-select.js was not found, make sure to modify your \"angular-cli.json\" file and include \"../node_modules/angular-slickgrid/lib/multiple-select/multiple-select.js\" and it's css or SASS file`);\r\n }\r\n this.$filterElm.attr('id', this.elementName);\r\n this.$filterElm.attr('name', this.elementName);\r\n this.$filterElm.data('columnId', fieldId);\r\n\r\n // if there's a search term, we will add the \"filled\" class for styling purposes\r\n if (this.isFilled) {\r\n this.$filterElm.addClass('filled');\r\n }\r\n\r\n // append the new DOM element to the header row\r\n if (this.$filterElm && typeof this.$filterElm.appendTo === 'function') {\r\n this.$filterElm.appendTo($headerElm);\r\n }\r\n\r\n // merge options & attach multiSelect\r\n const elementOptions: MultipleSelectOption = { ...this.defaultOptions, ...this.columnFilter.filterOptions };\r\n this.filterElmOptions = { ...this.defaultOptions, ...elementOptions };\r\n this.$filterElm = this.$filterElm.multipleSelect(this.filterElmOptions);\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { CollectionService } from './../services/collection.service';\r\nimport { SelectFilter } from './selectFilter';\r\n\r\nexport class MultipleSelectFilter extends SelectFilter {\r\n /**\r\n * Initialize the Filter\r\n */\r\n constructor(protected translate: TranslateService, protected collectionService: CollectionService) {\r\n super(translate, collectionService, true);\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport {\r\n Column,\r\n Filter,\r\n FilterArguments,\r\n FilterCallback,\r\n OperatorType,\r\n OperatorString,\r\n SearchTerm,\r\n} from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nexport class NativeSelectFilter implements Filter {\r\n private _clearFilterTriggered = false;\r\n private _shouldTriggerQuery = true;\r\n $filterElm: any;\r\n grid: any;\r\n searchTerms: SearchTerm[];\r\n columnDef: Column;\r\n callback: FilterCallback;\r\n\r\n constructor(private translate: TranslateService) { }\r\n\r\n get operator(): OperatorType | OperatorString {\r\n return (this.columnDef && this.columnDef.filter && this.columnDef.filter.operator) || OperatorType.equal;\r\n }\r\n\r\n /**\r\n * Initialize the Filter\r\n */\r\n init(args: FilterArguments) {\r\n this.grid = args.grid;\r\n this.callback = args.callback;\r\n this.columnDef = args.columnDef;\r\n this.searchTerms = args.searchTerms || [];\r\n\r\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\r\n let searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\r\n if (typeof searchTerm === 'boolean' || typeof searchTerm === 'number') {\r\n searchTerm = `${searchTerm}`;\r\n }\r\n\r\n // step 1, create HTML string template\r\n const filterTemplate = this.buildTemplateHtmlString();\r\n\r\n // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled\r\n this.$filterElm = this.createDomElement(filterTemplate, searchTerm);\r\n\r\n // step 3, subscribe to the change event and run the callback when that happens\r\n // also add/remove \"filled\" class for styling purposes\r\n this.$filterElm.change((e: any) => {\r\n const value = e && e.target && e.target.value || '';\r\n if (this._clearFilterTriggered) {\r\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\r\n this.$filterElm.removeClass('filled');\r\n } else {\r\n value === '' ? this.$filterElm.removeClass('filled') : this.$filterElm.addClass('filled');\r\n this.callback(e, { columnDef: this.columnDef, operator: this.operator, searchTerms: [value], shouldTriggerQuery: this._shouldTriggerQuery });\r\n }\r\n // reset both flags for next use\r\n this._clearFilterTriggered = false;\r\n this._shouldTriggerQuery = true;\r\n });\r\n }\r\n\r\n /**\r\n * Clear the filter values\r\n */\r\n clear(shouldTriggerQuery = true) {\r\n if (this.$filterElm) {\r\n this._clearFilterTriggered = true;\r\n this._shouldTriggerQuery = shouldTriggerQuery;\r\n this.searchTerms = [];\r\n this.$filterElm.val('');\r\n this.$filterElm.trigger('change');\r\n }\r\n }\r\n\r\n /**\r\n * destroy the filter\r\n */\r\n destroy() {\r\n if (this.$filterElm) {\r\n this.$filterElm.off('change').remove();\r\n }\r\n }\r\n\r\n /**\r\n * Set value(s) on the DOM element\r\n */\r\n setValues(values: SearchTerm | SearchTerm[]) {\r\n if (values) {\r\n this.$filterElm.val(values);\r\n }\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n\r\n private buildTemplateHtmlString() {\r\n if (!this.columnDef || !this.columnDef.filter || !this.columnDef.filter.collection) {\r\n throw new Error(`[Angular-SlickGrid] You need to pass a \"collection\" for the Select Filter to work correctly. Also each option should include a value/label pair (or value/labelKey when using Locale). For example:: { filter: model: Filters.select, collection: [{ value: true, label: 'True' }, { value: false, label: 'False'}] }`);\r\n }\r\n\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const optionCollection = this.columnDef.filter.collection || [];\r\n const labelName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.label : 'label';\r\n const valueName = (this.columnDef.filter.customStructure) ? this.columnDef.filter.customStructure.value : 'value';\r\n\r\n let options = '';\r\n\r\n // collection could be an Array of Strings OR Objects\r\n if (optionCollection.every(x => typeof x === 'string')) {\r\n optionCollection.forEach((option: string) => {\r\n options += `<option value=\"${option}\" label=\"${option}\">${option}</option>`;\r\n });\r\n } else {\r\n optionCollection.forEach((option: any) => {\r\n if (!option || (option[labelName] === undefined && option.labelKey === undefined)) {\r\n throw new Error(`A collection with value/label (or value/labelKey when using Locale) is required to populate the Select list, for example:: { filter: model: Filters.select, collection: [ { value: '1', label: 'One' } ]')`);\r\n }\r\n const labelKey = option.labelKey || option[labelName];\r\n const textLabel = ((option.labelKey || this.columnDef.filter.enableTranslateLabel) && this.translate && typeof this.translate.instant === 'function') ? this.translate.instant(labelKey || ' ') : labelKey;\r\n options += `<option value=\"${option[valueName]}\">${textLabel}</option>`;\r\n });\r\n }\r\n return `<select class=\"form-control search-filter filter-${fieldId}\">${options}</select>`;\r\n }\r\n\r\n /**\r\n * From the html template string, create a DOM element\r\n * @param filterTemplate\r\n */\r\n private createDomElement(filterTemplate: string, searchTerm?: SearchTerm) {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const $headerElm = this.grid.getHeaderRowColumn(fieldId);\r\n $($headerElm).empty();\r\n\r\n // create the DOM element & add an ID and filter class\r\n const $filterElm = $(filterTemplate);\r\n const searchTermInput = (searchTerm || '') as string;\r\n\r\n $filterElm.val(searchTermInput);\r\n $filterElm.attr('id', `filter-${fieldId}`);\r\n $filterElm.data('columnId', fieldId);\r\n\r\n // append the new DOM element to the header row\r\n if ($filterElm && typeof $filterElm.appendTo === 'function') {\r\n $filterElm.appendTo($headerElm);\r\n }\r\n\r\n return $filterElm;\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { CollectionService } from './../services/collection.service';\r\nimport { SelectFilter } from './selectFilter';\r\n\r\nexport class SingleSelectFilter extends SelectFilter {\r\n /**\r\n * Initialize the Filter\r\n */\r\n constructor(protected translate: TranslateService, protected collectionService: CollectionService) {\r\n super(translate, collectionService, false);\r\n }\r\n}\r\n","import {\r\n Column,\r\n ColumnFilter,\r\n Filter,\r\n FilterArguments,\r\n FilterCallback,\r\n OperatorType,\r\n OperatorString,\r\n SearchTerm,\r\n} from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nconst DEFAULT_MIN_VALUE = 0;\r\nconst DEFAULT_MAX_VALUE = 100;\r\nconst DEFAULT_STEP = 1;\r\n\r\nexport class SliderFilter implements Filter {\r\n private _clearFilterTriggered = false;\r\n private _shouldTriggerQuery = true;\r\n private _elementRangeInputId: string;\r\n private _elementRangeOutputId: string;\r\n private $filterElm: any;\r\n grid: any;\r\n searchTerms: SearchTerm[];\r\n columnDef: Column;\r\n callback: FilterCallback;\r\n\r\n /** Getter for the Filter Generic Params */\r\n private get filterParams(): any {\r\n return this.columnDef && this.columnDef.filter && this.columnDef.filter.params || {};\r\n }\r\n\r\n /** Getter for the `filter` properties */\r\n private get filterProperties(): ColumnFilter {\r\n return this.columnDef && this.columnDef.filter;\r\n }\r\n\r\n get operator(): OperatorType | OperatorString {\r\n return (this.columnDef && this.columnDef.filter && this.columnDef.filter.operator) || OperatorType.equal;\r\n }\r\n\r\n /**\r\n * Initialize the Filter\r\n */\r\n init(args: FilterArguments) {\r\n if (!args) {\r\n throw new Error('[Angular-SlickGrid] A filter must always have an \"init()\" with valid arguments.');\r\n }\r\n this.grid = args.grid;\r\n this.callback = args.callback;\r\n this.columnDef = args.columnDef;\r\n this.searchTerms = args.searchTerms || [];\r\n\r\n // define the input & slider number IDs\r\n this._elementRangeInputId = `rangeInput_${this.columnDef.field}`;\r\n this._elementRangeOutputId = `rangeOutput_${this.columnDef.field}`;\r\n\r\n // filter input can only have 1 search term, so we will use the 1st array index if it exist\r\n const searchTerm = (Array.isArray(this.searchTerms) && this.searchTerms[0]) || '';\r\n\r\n // step 1, create HTML string template\r\n const filterTemplate = this.buildTemplateHtmlString();\r\n\r\n // step 2, create the DOM Element of the filter & initialize it if searchTerm is filled\r\n this.$filterElm = this.createDomElement(filterTemplate, searchTerm);\r\n\r\n // step 3, subscribe to the change event and run the callback when that happens\r\n // also add/remove \"filled\" class for styling purposes\r\n this.$filterElm.change((e: any) => {\r\n const value = e && e.target && e.target.value || '';\r\n if (this._clearFilterTriggered) {\r\n this.callback(e, { columnDef: this.columnDef, clearFilterTriggered: this._clearFilterTriggered, shouldTriggerQuery: this._shouldTriggerQuery });\r\n this.$filterElm.removeClass('filled');\r\n } else {\r\n value === '' ? this.$filterElm.removeClass('filled') : this.$filterElm.addClass('filled');\r\n this.callback(e, { columnDef: this.columnDef, operator: this.operator, searchTerms: [value], shouldTriggerQuery: this._shouldTriggerQuery });\r\n }\r\n // reset both flags for next use\r\n this._clearFilterTriggered = false;\r\n this._shouldTriggerQuery = true;\r\n });\r\n\r\n // if user chose to display the slider number on the right side, then update it every time it changes\r\n // we need to use both \"input\" and \"change\" event to be all cross-browser\r\n if (!this.filterParams.hideSliderNumber) {\r\n this.$filterElm.on('input change', (e: { target: HTMLInputElement }) => {\r\n const value = e && e.target && e.target.value || '';\r\n if (value) {\r\n document.getElementById(this._elementRangeOutputId).innerHTML = value;\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Clear the filter value\r\n */\r\n clear(shouldTriggerQuery = true) {\r\n if (this.$filterElm) {\r\n this._clearFilterTriggered = true;\r\n this._shouldTriggerQuery = shouldTriggerQuery;\r\n this.searchTerms = [];\r\n const clearedValue = this.filterParams.hasOwnProperty('sliderStartValue') ? this.filterParams.sliderStartValue : DEFAULT_MIN_VALUE;\r\n this.$filterElm.children('input').val(clearedValue);\r\n this.$filterElm.children('div.input-group-addon.input-group-append').children().html(clearedValue);\r\n this.$filterElm.trigger('change');\r\n }\r\n }\r\n\r\n /**\r\n * destroy the filter\r\n */\r\n destroy() {\r\n if (this.$filterElm) {\r\n this.$filterElm.off('change').remove();\r\n }\r\n }\r\n\r\n /**\r\n * Set value(s) on the DOM element\r\n */\r\n setValues(values: SearchTerm) {\r\n if (values) {\r\n this.$filterElm.val(values);\r\n }\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n\r\n /**\r\n * Create the HTML template as a string\r\n */\r\n private buildTemplateHtmlString() {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const minValue = this.filterProperties.hasOwnProperty('minValue') ? this.filterProperties.minValue : DEFAULT_MIN_VALUE;\r\n const maxValue = this.filterProperties.hasOwnProperty('maxValue') ? this.filterProperties.maxValue : DEFAULT_MAX_VALUE;\r\n const defaultValue = this.filterParams.hasOwnProperty('sliderStartValue') ? this.filterParams.sliderStartValue : minValue;\r\n const step = this.filterProperties.hasOwnProperty('valueStep') ? this.filterProperties.valueStep : DEFAULT_STEP;\r\n\r\n if (this.filterParams.hideSliderNumber) {\r\n return `\r\n <div class=\"search-filter filter-${fieldId}\">\r\n <input type=\"range\" id=\"${this._elementRangeInputId}\"\r\n name=\"${this._elementRangeInputId}\"\r\n defaultValue=\"${defaultValue}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${step}\"\r\n class=\"form-control slider-filter-input range\" />\r\n </div>`;\r\n }\r\n\r\n return `\r\n <div class=\"input-group search-filter filter-${fieldId}\">\r\n <input type=\"range\" id=\"${this._elementRangeInputId}\"\r\n name=\"${this._elementRangeInputId}\"\r\n defaultValue=\"${defaultValue}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${step}\"\r\n class=\"form-control slider-filter-input range\" />\r\n <div class=\"input-group-addon input-group-append slider-value\">\r\n <span class=\"input-group-text\" id=\"${this._elementRangeOutputId}\">${defaultValue}</span>\r\n </div>\r\n </div>`;\r\n }\r\n\r\n /**\r\n * From the html template string, create a DOM element\r\n * @param filterTemplate\r\n */\r\n private createDomElement(filterTemplate: string, searchTerm?: SearchTerm) {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const $headerElm = this.grid.getHeaderRowColumn(fieldId);\r\n $($headerElm).empty();\r\n\r\n // create the DOM element & add an ID and filter class\r\n const $filterElm = $(filterTemplate);\r\n const searchTermInput = (searchTerm || '0') as string;\r\n\r\n $filterElm.children('input').val(searchTermInput);\r\n $filterElm.children('div.input-group-addon.input-group-append').children().html(searchTermInput);\r\n $filterElm.attr('id', `filter-${fieldId}`);\r\n $filterElm.data('columnId', fieldId);\r\n\r\n // if there's a search term, we will add the \"filled\" class for styling purposes\r\n if (searchTerm) {\r\n $filterElm.addClass('filled');\r\n }\r\n\r\n // append the new DOM element to the header row\r\n if ($filterElm && typeof $filterElm.appendTo === 'function') {\r\n $filterElm.appendTo($headerElm);\r\n }\r\n\r\n return $filterElm;\r\n }\r\n}\r\n","import { Column, Filter } from './../models/index';\r\nimport { AutoCompleteFilter } from './autoCompleteFilter';\r\nimport { CompoundDateFilter } from './compoundDateFilter';\r\nimport { CompoundInputFilter } from './compoundInputFilter';\r\nimport { CompoundInputNumberFilter } from './compoundInputNumberFilter';\r\nimport { CompoundInputPasswordFilter } from './compoundInputPasswordFilter';\r\nimport { CompoundSliderFilter } from './compoundSliderFilter';\r\nimport { InputFilter } from './inputFilter';\r\nimport { InputMaskFilter } from './inputMaskFilter';\r\nimport { InputNumberFilter } from './inputNumberFilter';\r\nimport { InputPasswordFilter } from './inputPasswordFilter';\r\nimport { MultipleSelectFilter } from './multipleSelectFilter';\r\nimport { NativeSelectFilter } from './nativeSelectFilter';\r\nimport { SingleSelectFilter } from './singleSelectFilter';\r\nimport { SliderFilter } from './sliderFilter';\r\n\r\nexport const Filters = {\r\n /** AutoComplete Filter (using jQuery UI autocomplete feature) */\r\n autoComplete: AutoCompleteFilter,\r\n\r\n /** Compound Date Filter (compound of Operator + Date picker) */\r\n compoundDate: CompoundDateFilter,\r\n\r\n /** Alias to compoundInputText to Compound Input Filter (compound of Operator + Input Text) */\r\n compoundInput: CompoundInputFilter,\r\n\r\n /** Compound Input Number Filter (compound of Operator + Input of type Number) */\r\n compoundInputNumber: CompoundInputNumberFilter,\r\n\r\n /** Compound Input Password Filter (compound of Operator + Input of type Password, also note that only the text shown in the UI will be masked, filter query is still plain text) */\r\n compoundInputPassword: CompoundInputPasswordFilter,\r\n\r\n /** Compound Input Text Filter (compound of Operator + Input Text) */\r\n compoundInputText: CompoundInputFilter,\r\n\r\n /** Compound Slider Filter (compound of Operator + Slider) */\r\n compoundSlider: CompoundSliderFilter,\r\n\r\n /** Alias to inputText, input type text filter */\r\n input: InputFilter,\r\n\r\n /**\r\n * Input Filter of type text that will be formatted with a mask output\r\n * e.g.: column: { filter: { model: Filters.inputMask }, params: { mask: '(000) 000-0000' }}\r\n */\r\n inputMask: InputMaskFilter,\r\n\r\n /** Input Filter of type Number */\r\n inputNumber: InputNumberFilter,\r\n\r\n /** Input Filter of type Password (note that only the text shown in the UI will be masked, filter query is still plain text) */\r\n inputPassword: InputPasswordFilter,\r\n\r\n /** Default Filter, input type text filter */\r\n inputText: InputFilter,\r\n\r\n /** Multiple Select filter, which uses 3rd party lib \"multiple-select.js\" */\r\n multipleSelect: MultipleSelectFilter,\r\n\r\n /** Select filter, which uses native DOM element select */\r\n select: NativeSelectFilter,\r\n\r\n /** Single Select filter, which uses 3rd party lib \"multiple-select.js\" */\r\n singleSelect: SingleSelectFilter,\r\n\r\n /** Slider Filter */\r\n slider: SliderFilter,\r\n};\r\n","import { DelimiterType, FileType, GridOption } from './models/index';\r\nimport { Filters } from './filters/index';\r\n\r\n/**\r\n * Options that can be passed to the Bootstrap-Datetimepicker directly\r\n */\r\nexport const GlobalGridOptions: GridOption = {\r\n alwaysShowVerticalScroll: true,\r\n autoEdit: false,\r\n asyncEditorLoading: false,\r\n autoFitColumnsOnFirstLoad: true,\r\n autoResize: {\r\n calculateAvailableSizeBy: 'window',\r\n bottomPadding: 20,\r\n minHeight: 180,\r\n minWidth: 300,\r\n sidePadding: 0\r\n },\r\n cellHighlightCssClass: 'slick-cell-modified',\r\n checkboxSelector: {\r\n cssClass: 'slick-cell-checkboxsel'\r\n },\r\n columnPicker: {\r\n hideForceFitButton: false,\r\n hideSyncResizeButton: true\r\n },\r\n datasetIdPropertyName: 'id',\r\n defaultFilter: Filters.input,\r\n enableFilterTrimWhiteSpace: false, // do we want to trim white spaces on all Filters?\r\n defaultFilterPlaceholder: '&#128269;',\r\n editable: false,\r\n enableAutoResize: true,\r\n enableAutoSizeColumns: true,\r\n enableCellNavigation: false,\r\n enableColumnPicker: true,\r\n enableColumnReorder: true,\r\n enableExport: true,\r\n enableGridMenu: true,\r\n enableHeaderMenu: true,\r\n enableMouseHoverHighlightRow: true,\r\n enableSorting: true,\r\n enableTextSelectionOnCells: true,\r\n explicitInitialization: true,\r\n exportOptions: {\r\n delimiter: DelimiterType.comma,\r\n exportWithFormatter: false,\r\n filename: 'export',\r\n format: FileType.csv,\r\n groupingAggregatorRowText: '',\r\n sanitizeDataExport: false,\r\n useUtf8WithBom: true\r\n },\r\n forceFitColumns: false,\r\n gridMenu: {\r\n hideClearAllFiltersCommand: false,\r\n hideClearAllSortingCommand: false,\r\n hideExportCsvCommand: false,\r\n hideExportTextDelimitedCommand: true,\r\n hideForceFitButton: false,\r\n hideRefreshDatasetCommand: false,\r\n hideSyncResizeButton: true,\r\n hideToggleFilterCommand: false,\r\n hideTogglePreHeaderCommand: false,\r\n iconCssClass: 'fa fa-bars',\r\n iconClearAllFiltersCommand: 'fa fa-filter text-danger',\r\n iconClearAllSortingCommand: 'fa fa-unsorted text-danger',\r\n iconExportCsvCommand: 'fa fa-download',\r\n iconExportTextDelimitedCommand: 'fa fa-download',\r\n iconRefreshDatasetCommand: 'fa fa-refresh',\r\n iconToggleFilterCommand: 'fa fa-random',\r\n iconTogglePreHeaderCommand: 'fa fa-random',\r\n menuWidth: 16,\r\n resizeOnShowHeaderRow: true\r\n },\r\n headerMenu: {\r\n autoAlign: true,\r\n autoAlignOffset: 12,\r\n minWidth: 140,\r\n iconClearFilterCommand: 'fa fa-filter text-danger',\r\n iconClearSortCommand: 'fa fa-unsorted',\r\n iconSortAscCommand: 'fa fa-sort-amount-asc',\r\n iconSortDescCommand: 'fa fa-sort-amount-desc',\r\n iconColumnHideCommand: 'fa fa-times',\r\n hideColumnHideCommand: false,\r\n hideClearFilterCommand: false,\r\n hideClearSortCommand: false,\r\n hideSortCommands: false\r\n },\r\n headerRowHeight: 35,\r\n multiColumnSort: true,\r\n numberedMultiColumnSort: true,\r\n tristateMultiColumnSort: false,\r\n sortColNumberInSeparateSpan: true,\r\n suppressActiveCellChangeOnEdit: true,\r\n pagination: {\r\n pageSizes: [10, 15, 20, 25, 30, 40, 50, 75, 100],\r\n pageSize: 25,\r\n totalItems: 0\r\n },\r\n rowDetailView: {\r\n cssClass: 'detail-view-toggle',\r\n panelRows: 1,\r\n keyPrefix: '__',\r\n useRowClick: true,\r\n useSimpleViewportCalc: true,\r\n saveDetailViewOnScroll: false,\r\n\r\n // the following 2 property/method should always be override by the user\r\n process: undefined,\r\n viewComponent: null\r\n },\r\n rowHeight: 35,\r\n topPanelHeight: 35\r\n};\r\n","import { GlobalGridOptions } from './global-grid-options';\r\n\r\nexport class SlickgridConfig {\r\n options: any;\r\n\r\n constructor() {\r\n this.options = GlobalGridOptions;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Filter } from '../models/filter.interface';\r\nimport { ColumnFilter } from '../models';\r\nimport { SlickgridConfig } from '../slickgrid-config';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport { CollectionService } from '../services/collection.service';\r\n\r\n@Injectable()\r\nexport class FilterFactory {\r\n /**\r\n * The options from the SlickgridConfig\r\n */\r\n private _options: any;\r\n\r\n constructor(private config: SlickgridConfig, private translate: TranslateService, private collectionService: CollectionService) {\r\n this._options = this.config.options;\r\n }\r\n\r\n // Uses the User model to create a new User\r\n createFilter(columnFilter: ColumnFilter | undefined): Filter | undefined {\r\n let filter: Filter | undefined;\r\n\r\n if (columnFilter && columnFilter.model) {\r\n filter = typeof columnFilter.model === 'function' ? new columnFilter.model(this.translate, this.collectionService) : columnFilter.model;\r\n }\r\n\r\n // fallback to the default filter\r\n if (!filter && this._options.defaultFilter) {\r\n filter = new this._options.defaultFilter(this.translate, this.collectionService);\r\n }\r\n\r\n return filter;\r\n }\r\n}\r\n","import {\r\n Column,\r\n ColumnSort,\r\n CurrentSorter,\r\n EmitterType,\r\n FieldType,\r\n GraphqlResult,\r\n GridOption,\r\n SlickEventHandler,\r\n SortDirection,\r\n SortDirectionNumber,\r\n SortDirectionString,\r\n} from './../models/index';\r\nimport { executeBackendProcessesCallback, onBackendError } from './backend-utilities';\r\nimport { getDescendantProperty } from './utilities';\r\nimport { sortByFieldType } from '../sorters/sorterUtilities';\r\nimport { isObservable, Subject } from 'rxjs';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\nexport class SortService {\r\n private _currentLocalSorters: CurrentSorter[] = [];\r\n private _eventHandler: SlickEventHandler;\r\n private _dataView: any;\r\n private _grid: any;\r\n private _isBackendGrid = false;\r\n onSortChanged = new Subject<CurrentSorter[]>();\r\n onSortCleared = new Subject<boolean>();\r\n\r\n constructor() {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n /** Getter of the SlickGrid Event Handler */\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n /** Getter for the Column Definitions pulled through the Grid Object */\r\n private get _columnDefinitions(): Column[] {\r\n return (this._grid && this._grid.getColumns) ? this._grid.getColumns() : [];\r\n }\r\n\r\n /**\r\n * Bind a backend sort (single/multi) hook to the grid\r\n * @param grid SlickGrid Grid object\r\n * @param dataView SlickGrid DataView object\r\n */\r\n bindBackendOnSort(grid: any, dataView: any) {\r\n this._isBackendGrid = true;\r\n this._grid = grid;\r\n this._dataView = dataView;\r\n\r\n // subscribe to the SlickGrid event and call the backend execution\r\n this._eventHandler.subscribe(grid.onSort, this.onBackendSortChanged.bind(this));\r\n }\r\n\r\n /**\r\n * Bind a local sort (single/multi) hook to the grid\r\n * @param grid SlickGrid Grid object\r\n * @param gridOptions Grid Options object\r\n * @param dataView\r\n */\r\n bindLocalOnSort(grid: any, dataView: any) {\r\n this._isBackendGrid = false;\r\n this._grid = grid;\r\n this._dataView = dataView;\r\n\r\n this._eventHandler.subscribe(grid.onSort, (e: any, args: any) => {\r\n if (args && (args.sortCols || args.sortCol)) {\r\n // multiSort and singleSort are not exactly the same, but we want to structure it the same for the (for loop) after\r\n // also to avoid having to rewrite the for loop in the sort, we will make the singleSort an array of 1 object\r\n const sortColumns = (args.multiColumnSort) ? args.sortCols : new Array({ sortAsc: args.sortAsc, sortCol: args.sortCol });\r\n\r\n // keep current sorters\r\n this._currentLocalSorters = []; // reset current local sorters\r\n if (Array.isArray(sortColumns)) {\r\n sortColumns.forEach((sortColumn: { sortCol: Column, sortAsc: boolean }) => {\r\n if (sortColumn.sortCol) {\r\n this._currentLocalSorters.push({\r\n columnId: sortColumn.sortCol.id,\r\n direction: sortColumn.sortAsc ? SortDirection.ASC : SortDirection.DESC\r\n });\r\n }\r\n });\r\n }\r\n\r\n this.onLocalSortChanged(grid, dataView, sortColumns);\r\n this.emitSortChanged(EmitterType.local);\r\n }\r\n });\r\n }\r\n\r\n clearSorting(triggerQueryEvent = true) {\r\n if (this._grid && this._gridOptions && this._dataView) {\r\n // remove any sort icons (this setSortColumns function call really does only that)\r\n this._grid.setSortColumns([]);\r\n\r\n // we also need to trigger a sort change\r\n // for a backend grid, we will trigger a backend sort changed with an empty sort columns array\r\n // however for a local grid, we need to pass a sort column and so we will sort by the 1st column\r\n if (triggerQueryEvent) {\r\n if (this._isBackendGrid) {\r\n this.onBackendSortChanged(undefined, { grid: this._grid, sortCols: [] });\r\n } else {\r\n if (this._columnDefinitions && Array.isArray(this._columnDefinitions)) {\r\n this.onLocalSortChanged(this._grid, this._dataView, new Array({ sortAsc: true, sortCol: this._columnDefinitions[0] }));\r\n }\r\n }\r\n } else if (this._isBackendGrid) {\r\n const backendService = this._gridOptions && this._gridOptions.backendServiceApi && this._gridOptions.backendServiceApi.service;\r\n if (backendService && backendService.clearSorters) {\r\n backendService.clearSorters();\r\n }\r\n }\r\n }\r\n\r\n // set current sorter to empty & emit a sort changed event\r\n this._currentLocalSorters = [];\r\n\r\n // emit an event when sorts are all cleared\r\n this.onSortCleared.next(true);\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n if (this._eventHandler && this._eventHandler.unsubscribeAll) {\r\n this._eventHandler.unsubscribeAll();\r\n }\r\n }\r\n\r\n getCurrentLocalSorters(): CurrentSorter[] {\r\n return this._currentLocalSorters;\r\n }\r\n\r\n /**\r\n * Get current column sorts,\r\n * If a column is passed as an argument, that will be exclusion so we won't add this column to our output array since it is already in the array.\r\n * The usage of this method is that we want to know the sort prior to calling the next sorting command\r\n */\r\n getCurrentColumnSorts(excludedColumnId?: string) {\r\n // getSortColumns() only returns sortAsc & columnId, we want the entire column definition\r\n const oldSortColumns = this._grid && this._grid.getSortColumns();\r\n\r\n // get the column definition but only keep column which are not equal to our current column\r\n if (Array.isArray(oldSortColumns)) {\r\n const sortedCols = oldSortColumns.reduce((cols, col) => {\r\n if (!excludedColumnId || col.columnId !== excludedColumnId) {\r\n cols.push({ sortCol: this._columnDefinitions[this._grid.getColumnIndex(col.columnId)], sortAsc: col.sortAsc });\r\n }\r\n return cols;\r\n }, []);\r\n\r\n return sortedCols;\r\n }\r\n return [];\r\n }\r\n\r\n /**\r\n * Load any presets, if there are any, that are defined in the Grid Options\r\n * @param grid\r\n * @param dataView\r\n */\r\n loadLocalGridPresets(grid: any, dataView: any) {\r\n const sortCols: ColumnSort[] = [];\r\n this._currentLocalSorters = []; // reset current local sorters\r\n if (this._gridOptions && this._gridOptions.presets && this._gridOptions.presets.sorters) {\r\n const sorters = this._gridOptions.presets.sorters;\r\n\r\n sorters.forEach((presetSorting: CurrentSorter) => {\r\n const gridColumn = this._columnDefinitions.find((col: Column) => col.id === presetSorting.columnId);\r\n if (gridColumn) {\r\n sortCols.push({\r\n columnId: gridColumn.id,\r\n sortAsc: ((presetSorting.direction.toUpperCase() === SortDirection.ASC) ? true : false),\r\n sortCol: gridColumn\r\n });\r\n\r\n // keep current sorters\r\n this._currentLocalSorters.push({\r\n columnId: gridColumn.id + '',\r\n direction: presetSorting.direction.toUpperCase() as SortDirectionString\r\n });\r\n }\r\n });\r\n\r\n if (sortCols.length > 0) {\r\n this.onLocalSortChanged(grid, dataView, sortCols);\r\n grid.setSortColumns(sortCols); // use this to add sort icon(s) in UI\r\n }\r\n }\r\n }\r\n\r\n onBackendSortChanged(event: Event, args: any) {\r\n if (!args || !args.grid) {\r\n throw new Error('Something went wrong when trying to bind the \"onBackendSortChanged(event, args)\" function, it seems that \"args\" is not populated correctly');\r\n }\r\n const gridOptions: GridOption = (args.grid && args.grid.getOptions) ? args.grid.getOptions() : {};\r\n const backendApi = gridOptions.backendServiceApi;\r\n\r\n if (!backendApi || !backendApi.process || !backendApi.service) {\r\n throw new Error(`BackendServiceApi requires at least a \"process\" function and a \"service\" defined`);\r\n }\r\n\r\n // keep start time & end timestamps & return it after process execution\r\n const startTime = new Date();\r\n\r\n if (backendApi.preProcess) {\r\n backendApi.preProcess();\r\n }\r\n\r\n const query = backendApi.service.processOnSortChanged(event, args);\r\n this.emitSortChanged(EmitterType.remote);\r\n\r\n // the processes can be Observables (like HttpClient) or Promises\r\n const process = backendApi.process(query);\r\n if (process instanceof Promise && process.then) {\r\n process.then((processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this._gridOptions))\r\n .catch((error: any) => onBackendError(error, backendApi));\r\n } else if (isObservable(process)) {\r\n process.subscribe(\r\n (processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this._gridOptions),\r\n (error: any) => onBackendError(error, backendApi)\r\n );\r\n }\r\n }\r\n\r\n onLocalSortChanged(grid: any, dataView: any, sortColumns: ColumnSort[], forceReSort = false) {\r\n if (grid && dataView) {\r\n if (forceReSort) {\r\n dataView.reSort();\r\n }\r\n\r\n dataView.sort(this.sortComparer.bind(this, sortColumns));\r\n\r\n grid.invalidate();\r\n grid.render();\r\n }\r\n }\r\n\r\n sortComparer(sortColumns: ColumnSort[], dataRow1: any, dataRow2: any) {\r\n if (Array.isArray(sortColumns)) {\r\n for (let i = 0, l = sortColumns.length; i < l; i++) {\r\n const columnSortObj = sortColumns[i];\r\n if (columnSortObj && columnSortObj.sortCol) {\r\n const sortDirection = columnSortObj.sortAsc ? SortDirectionNumber.asc : SortDirectionNumber.desc;\r\n const sortField = columnSortObj.sortCol.queryFieldSorter || columnSortObj.sortCol.queryField || columnSortObj.sortCol.field;\r\n const fieldType = columnSortObj.sortCol.type || FieldType.string;\r\n let value1 = dataRow1[sortField];\r\n let value2 = dataRow2[sortField];\r\n\r\n // when item is a complex object (dot \".\" notation), we need to filter the value contained in the object tree\r\n if (sortField && sortField.indexOf('.') >= 0) {\r\n value1 = getDescendantProperty(dataRow1, sortField);\r\n value2 = getDescendantProperty(dataRow2, sortField);\r\n }\r\n\r\n // user could provide his own custom Sorter\r\n if (columnSortObj.sortCol && columnSortObj.sortCol.sorter) {\r\n const customSortResult = columnSortObj.sortCol.sorter(value1, value2, sortDirection, columnSortObj.sortCol);\r\n if (customSortResult !== SortDirectionNumber.neutral) {\r\n return customSortResult;\r\n }\r\n } else {\r\n const sortResult = sortByFieldType(value1, value2, fieldType, sortDirection, columnSortObj.sortCol);\r\n if (sortResult !== SortDirectionNumber.neutral) {\r\n return sortResult;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return SortDirectionNumber.neutral;\r\n }\r\n\r\n // --\r\n // private functions\r\n // ------------------\r\n\r\n /**\r\n * A simple function that is binded to the subscriber and emit a change when the sort is called.\r\n * Other services, like Pagination, can then subscribe to it.\r\n * @param sender\r\n */\r\n private emitSortChanged(sender: EmitterType) {\r\n if (sender === EmitterType.remote && this._gridOptions && this._gridOptions.backendServiceApi) {\r\n let currentSorters: CurrentSorter[] = [];\r\n const backendService = this._gridOptions.backendServiceApi.service;\r\n if (backendService && backendService.getCurrentSorters) {\r\n currentSorters = backendService.getCurrentSorters() as CurrentSorter[];\r\n }\r\n this.onSortChanged.next(currentSorters);\r\n } else if (sender === EmitterType.local) {\r\n this.onSortChanged.next(this.getCurrentLocalSorters());\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport { Constants } from '../constants';\r\nimport {\r\n CellArgs,\r\n DelimiterType,\r\n Extension,\r\n ExtensionName,\r\n FileType,\r\n GraphqlResult,\r\n GridOption,\r\n GridMenu,\r\n GridMenuItem,\r\n SlickEventHandler,\r\n} from '../models';\r\nimport { ExportService } from '../services/export.service';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { FilterService } from '../services/filter.service';\r\nimport { SortService } from '../services/sort.service';\r\nimport { castToPromise } from '../services/utilities';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\ndeclare var $: any;\r\n\r\n@Injectable()\r\nexport class GridMenuExtension implements Extension {\r\n private _addon: any;\r\n private _areVisibleColumnDifferent = false;\r\n private _eventHandler: SlickEventHandler;\r\n private _userOriginalGridMenu: GridMenu;\r\n\r\n constructor(\r\n private exportService: ExportService,\r\n private extensionUtility: ExtensionUtility,\r\n private filterService: FilterService,\r\n private sharedService: SharedService,\r\n private sortService: SortService,\r\n private translate: TranslateService,\r\n ) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n showGridMenu(e) {\r\n this._addon.showGridMenu(e);\r\n }\r\n\r\n /** Create the Header Menu and expose all the available hooks that user can subscribe (onCommand, onBeforeMenuShow, ...) */\r\n register(): any {\r\n // keep original user grid menu, useful when switching locale to translate\r\n this._userOriginalGridMenu = { ...this.sharedService.gridOptions.gridMenu };\r\n\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.gridMenu);\r\n this.sharedService.gridOptions.gridMenu = { ...this.getDefaultGridMenuOptions(), ...this.sharedService.gridOptions.gridMenu };\r\n\r\n // merge original user grid menu items with internal items\r\n // then sort all Grid Menu Custom Items (sorted by pointer, no need to use the return)\r\n this.sharedService.gridOptions.gridMenu.customItems = [...this._userOriginalGridMenu.customItems || [], ...this.addGridMenuCustomCommands()];\r\n this.extensionUtility.translateItems(this.sharedService.gridOptions.gridMenu.customItems, 'titleKey', 'title');\r\n this.extensionUtility.sortItems(this.sharedService.gridOptions.gridMenu.customItems, 'positionOrder');\r\n\r\n this._addon = new Slick.Controls.GridMenu(this.sharedService.columnDefinitions, this.sharedService.grid, this.sharedService.gridOptions);\r\n\r\n // hook all events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.gridMenu) {\r\n if (this.sharedService.gridOptions.gridMenu.onExtensionRegistered) {\r\n this.sharedService.gridOptions.gridMenu.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onBeforeMenuShow, (e: any, args: CellArgs) => {\r\n if (this.sharedService.gridOptions.gridMenu && typeof this.sharedService.gridOptions.gridMenu.onBeforeMenuShow === 'function') {\r\n this.sharedService.gridOptions.gridMenu.onBeforeMenuShow(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onColumnsChanged, (e: any, args: CellArgs) => {\r\n this._areVisibleColumnDifferent = true;\r\n if (this.sharedService.gridOptions.gridMenu && typeof this.sharedService.gridOptions.gridMenu.onColumnsChanged === 'function') {\r\n this.sharedService.gridOptions.gridMenu.onColumnsChanged(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onCommand, (e: any, args: any) => {\r\n this.executeGridMenuInternalCustomCommands(e, args);\r\n if (this.sharedService.gridOptions.gridMenu && typeof this.sharedService.gridOptions.gridMenu.onCommand === 'function') {\r\n this.sharedService.gridOptions.gridMenu.onCommand(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onMenuClose, (e: any, args: CellArgs) => {\r\n if (this.sharedService.gridOptions.gridMenu && typeof this.sharedService.gridOptions.gridMenu.onMenuClose === 'function') {\r\n this.sharedService.gridOptions.gridMenu.onMenuClose(e, args);\r\n }\r\n\r\n // we also want to resize the columns if the user decided to hide certain column(s)\r\n if (this.sharedService.grid && typeof this.sharedService.grid.autosizeColumns === 'function') {\r\n // make sure that the grid still exist (by looking if the Grid UID is found in the DOM tree)\r\n const gridUid = this.sharedService.grid.getUID();\r\n if (this._areVisibleColumnDifferent && gridUid && $(`.${gridUid}`).length > 0) {\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableAutoSizeColumns) {\r\n this.sharedService.grid.autosizeColumns();\r\n }\r\n this._areVisibleColumnDifferent = false;\r\n }\r\n }\r\n });\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n /** Refresh the dataset through the Backend Service */\r\n refreshBackendDataset(gridOptions?: GridOption) {\r\n let query = '';\r\n\r\n // user can pass new set of grid options which will override current ones\r\n if (gridOptions) {\r\n this.sharedService.gridOptions = { ...this.sharedService.gridOptions, ...gridOptions };\r\n }\r\n\r\n const backendApi = this.sharedService.gridOptions.backendServiceApi;\r\n if (!backendApi || !backendApi.service || !backendApi.process) {\r\n throw new Error(`BackendServiceApi requires at least a \"process\" function and a \"service\" defined`);\r\n }\r\n\r\n if (backendApi.service) {\r\n query = backendApi.service.buildQuery();\r\n }\r\n\r\n if (query && query !== '') {\r\n // keep start time & end timestamps & return it after process execution\r\n const startTime = new Date();\r\n\r\n if (backendApi.preProcess) {\r\n backendApi.preProcess();\r\n }\r\n\r\n // the process could be an Observable (like HttpClient) or a Promise\r\n // in any case, we need to have a Promise so that we can await on it (if an Observable, convert it to Promise)\r\n const observableOrPromise = backendApi.process(query);\r\n\r\n castToPromise(observableOrPromise).then((processResult: GraphqlResult | any) => {\r\n const endTime = new Date();\r\n\r\n // from the result, call our internal post process to update the Dataset and Pagination info\r\n if (processResult && backendApi && backendApi.internalPostProcess) {\r\n backendApi.internalPostProcess(processResult);\r\n }\r\n\r\n // send the response process to the postProcess callback\r\n if (backendApi && backendApi.postProcess) {\r\n if (processResult instanceof Object) {\r\n processResult.statistics = {\r\n startTime,\r\n endTime,\r\n executionTime: endTime.valueOf() - startTime.valueOf(),\r\n totalItemCount: this.sharedService.gridOptions && this.sharedService.gridOptions.pagination && this.sharedService.gridOptions.pagination.totalItems\r\n };\r\n }\r\n backendApi.postProcess(processResult);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /** Translate the Grid Menu titles and column picker */\r\n translateGridMenu() {\r\n // update the properties by pointers, that is the only way to get Grid Menu Control to see the new values\r\n // we also need to call the control init so that it takes the new Grid object with latest values\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu) {\r\n this.sharedService.gridOptions.gridMenu.customItems = [];\r\n this.emptyGridMenuTitles();\r\n\r\n // merge original user grid menu items with internal items\r\n // then sort all Grid Menu Custom Items (sorted by pointer, no need to use the return)\r\n this.sharedService.gridOptions.gridMenu.customItems = [...this._userOriginalGridMenu.customItems || [], ...this.addGridMenuCustomCommands()];\r\n this.extensionUtility.translateItems(this.sharedService.gridOptions.gridMenu.customItems, 'titleKey', 'title');\r\n this.extensionUtility.sortItems(this.sharedService.gridOptions.gridMenu.customItems, 'positionOrder');\r\n\r\n this.sharedService.gridOptions.gridMenu.columnTitle = this.extensionUtility.getPickerTitleOutputString('columnTitle', 'gridMenu');\r\n this.sharedService.gridOptions.gridMenu.forceFitTitle = this.extensionUtility.getPickerTitleOutputString('forceFitTitle', 'gridMenu');\r\n this.sharedService.gridOptions.gridMenu.syncResizeTitle = this.extensionUtility.getPickerTitleOutputString('syncResizeTitle', 'gridMenu');\r\n\r\n // translate all columns (including non-visible)\r\n this.extensionUtility.translateItems(this.sharedService.allColumns, 'headerKey', 'name');\r\n\r\n // re-initialize the Grid Menu, that will recreate all the menus & list\r\n // doing an \"init()\" won't drop any existing command attached\r\n if (this._addon.init) {\r\n this._addon.init(this.sharedService.grid);\r\n }\r\n }\r\n }\r\n\r\n // --\r\n // private functions\r\n // ------------------\r\n\r\n /** Create Grid Menu with Custom Commands if user has enabled Filters and/or uses a Backend Service (OData, GraphQL) */\r\n private addGridMenuCustomCommands() {\r\n const backendApi = this.sharedService.gridOptions.backendServiceApi || null;\r\n const gridMenuCustomItems: GridMenuItem[] = [];\r\n\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableFiltering) {\r\n // show grid menu: clear all filters\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideClearAllFiltersCommand) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconClearAllFiltersCommand || 'fa fa-filter text-danger',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('CLEAR_ALL_FILTERS') : Constants.TEXT_CLEAR_ALL_FILTERS,\r\n disabled: false,\r\n command: 'clear-filter',\r\n positionOrder: 50\r\n }\r\n );\r\n }\r\n\r\n // show grid menu: toggle filter row\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideToggleFilterCommand) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconToggleFilterCommand || 'fa fa-random',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('TOGGLE_FILTER_ROW') : Constants.TEXT_TOGGLE_FILTER_ROW,\r\n disabled: false,\r\n command: 'toggle-filter',\r\n positionOrder: 52\r\n }\r\n );\r\n }\r\n\r\n // show grid menu: refresh dataset\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideRefreshDatasetCommand && backendApi) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconRefreshDatasetCommand || 'fa fa-refresh',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('REFRESH_DATASET') : Constants.TEXT_REFRESH_DATASET,\r\n disabled: false,\r\n command: 'refresh-dataset',\r\n positionOrder: 54\r\n }\r\n );\r\n }\r\n }\r\n\r\n if (this.sharedService.gridOptions.showPreHeaderPanel) {\r\n // show grid menu: toggle pre-header row\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideTogglePreHeaderCommand) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconTogglePreHeaderCommand || 'fa fa-random',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('TOGGLE_PRE_HEADER_ROW') : Constants.TEXT_TOGGLE_PRE_HEADER_ROW,\r\n disabled: false,\r\n command: 'toggle-preheader',\r\n positionOrder: 52\r\n }\r\n );\r\n }\r\n }\r\n\r\n if (this.sharedService.gridOptions.enableSorting) {\r\n // show grid menu: clear all sorting\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideClearAllSortingCommand) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconClearAllSortingCommand || 'fa fa-unsorted text-danger',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('CLEAR_ALL_SORTING') : Constants.TEXT_CLEAR_ALL_SORTING,\r\n disabled: false,\r\n command: 'clear-sorting',\r\n positionOrder: 51\r\n }\r\n );\r\n }\r\n }\r\n\r\n // show grid menu: export to file\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableExport && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideExportCsvCommand) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconExportCsvCommand || 'fa fa-download',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('EXPORT_TO_CSV') : Constants.TEXT_EXPORT_IN_CSV_FORMAT,\r\n disabled: false,\r\n command: 'export-csv',\r\n positionOrder: 53\r\n }\r\n );\r\n }\r\n // show grid menu: export to text file as tab delimited\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableExport && this.sharedService.gridOptions.gridMenu && !this.sharedService.gridOptions.gridMenu.hideExportTextDelimitedCommand) {\r\n gridMenuCustomItems.push(\r\n {\r\n iconCssClass: this.sharedService.gridOptions.gridMenu.iconExportTextDelimitedCommand || 'fa fa-download',\r\n title: this.sharedService.gridOptions.enableTranslate ? this.translate.instant('EXPORT_TO_TAB_DELIMITED') : Constants.TEXT_EXPORT_IN_TEXT_FORMAT,\r\n disabled: false,\r\n command: 'export-text-delimited',\r\n positionOrder: 54\r\n }\r\n );\r\n }\r\n\r\n // add the custom \"Commands\" title if there are any commands\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu && (gridMenuCustomItems.length > 0 || (this.sharedService.gridOptions.gridMenu.customItems && this.sharedService.gridOptions.gridMenu.customItems.length > 0))) {\r\n this.sharedService.gridOptions.gridMenu.customTitle = this.sharedService.gridOptions.gridMenu.customTitle || this.extensionUtility.getPickerTitleOutputString('customTitle', 'gridMenu');\r\n }\r\n\r\n return gridMenuCustomItems;\r\n }\r\n\r\n /**\r\n * Execute the Grid Menu Custom command callback that was triggered by the onCommand subscribe\r\n * These are the default internal custom commands\r\n * @param event\r\n * @param GridMenuItem args\r\n */\r\n private executeGridMenuInternalCustomCommands(e: Event, args: GridMenuItem) {\r\n if (args && args.command) {\r\n switch (args.command) {\r\n case 'clear-filter':\r\n this.filterService.clearFilters();\r\n this.sharedService.dataView.refresh();\r\n break;\r\n case 'clear-sorting':\r\n this.sortService.clearSorting();\r\n this.sharedService.dataView.refresh();\r\n break;\r\n case 'export-csv':\r\n this.exportService.exportToFile({\r\n delimiter: DelimiterType.comma,\r\n filename: 'export',\r\n format: FileType.csv,\r\n useUtf8WithBom: true\r\n });\r\n break;\r\n case 'export-text-delimited':\r\n this.exportService.exportToFile({\r\n delimiter: DelimiterType.tab,\r\n filename: 'export',\r\n format: FileType.txt,\r\n useUtf8WithBom: true\r\n });\r\n break;\r\n case 'toggle-filter':\r\n const showHeaderRow = this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.showHeaderRow || false;\r\n this.sharedService.grid.setHeaderRowVisibility(!showHeaderRow);\r\n break;\r\n case 'toggle-toppanel':\r\n const showTopPanel = this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.showTopPanel || false;\r\n this.sharedService.grid.setTopPanelVisibility(!showTopPanel);\r\n break;\r\n case 'toggle-preheader':\r\n const showPreHeaderPanel = this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.showPreHeaderPanel || false;\r\n this.sharedService.grid.setPreHeaderPanelVisibility(!showPreHeaderPanel);\r\n break;\r\n case 'refresh-dataset':\r\n this.refreshBackendDataset();\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n }\r\n\r\n private emptyGridMenuTitles() {\r\n if (this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.gridMenu) {\r\n this.sharedService.gridOptions.gridMenu.customTitle = '';\r\n this.sharedService.gridOptions.gridMenu.columnTitle = '';\r\n this.sharedService.gridOptions.gridMenu.forceFitTitle = '';\r\n this.sharedService.gridOptions.gridMenu.syncResizeTitle = '';\r\n }\r\n }\r\n\r\n /** @return default Grid Menu options */\r\n private getDefaultGridMenuOptions(): GridMenu {\r\n return {\r\n customTitle: undefined,\r\n columnTitle: this.extensionUtility.getPickerTitleOutputString('columnTitle', 'gridMenu'),\r\n forceFitTitle: this.extensionUtility.getPickerTitleOutputString('forceFitTitle', 'gridMenu'),\r\n syncResizeTitle: this.extensionUtility.getPickerTitleOutputString('syncResizeTitle', 'gridMenu'),\r\n iconCssClass: 'fa fa-bars',\r\n menuWidth: 18,\r\n customItems: [],\r\n hideClearAllFiltersCommand: false,\r\n hideRefreshDatasetCommand: false,\r\n hideToggleFilterCommand: false,\r\n };\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Extension } from '../models/index';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n@Injectable()\r\nexport class GroupItemMetaProviderExtension implements Extension {\r\n private _addon: any;\r\n\r\n constructor(private sharedService: SharedService) { }\r\n\r\n dispose() {\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n /** register the group item metadata provider to add expand/collapse group handlers */\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid) {\r\n this._addon = this.sharedService.groupItemMetadataProvider || {};\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Extension, ExtensionName, HeaderButtonOnCommandArgs, SlickEventHandler } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class HeaderButtonExtension implements Extension {\r\n private _eventHandler: SlickEventHandler;\r\n private _addon: any;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n // Header Button Plugin\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.headerButton);\r\n this._addon = new Slick.Plugins.HeaderButtons(this.sharedService.gridOptions.headerButton || {});\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // hook all events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.headerButton) {\r\n if (this.sharedService.gridOptions.headerButton.onExtensionRegistered) {\r\n this.sharedService.gridOptions.headerButton.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onCommand, (e: any, args: HeaderButtonOnCommandArgs) => {\r\n if (this.sharedService.gridOptions.headerButton && typeof this.sharedService.gridOptions.headerButton.onCommand === 'function') {\r\n this.sharedService.gridOptions.headerButton.onCommand(e, args);\r\n }\r\n });\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport { Constants } from '../constants';\r\nimport {\r\n Column,\r\n ColumnSort,\r\n Extension,\r\n ExtensionName,\r\n GridOption,\r\n HeaderMenu,\r\n HeaderMenuItem,\r\n HeaderMenuOnCommandArgs,\r\n HeaderMenuOnBeforeMenuShowArgs,\r\n SlickEventHandler,\r\n} from '../models/index';\r\nimport { FilterService } from '../services/filter.service';\r\nimport { SortService } from '../services/sort.service';\r\nimport { SharedService } from '../services/shared.service';\r\nimport { ExtensionUtility } from './extensionUtility';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class HeaderMenuExtension implements Extension {\r\n private _addon: any;\r\n private _eventHandler: SlickEventHandler;\r\n\r\n constructor(\r\n private extensionUtility: ExtensionUtility,\r\n private filterService: FilterService,\r\n private sharedService: SharedService,\r\n private sortService: SortService,\r\n private translate: TranslateService,\r\n ) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n /**\r\n * Create the Header Menu and expose all the available hooks that user can subscribe (onCommand, onBeforeMenuShow, ...)\r\n * @param grid\r\n * @param dataView\r\n * @param columnDefinitions\r\n */\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.headerMenu);\r\n this.sharedService.gridOptions.headerMenu = { ...this.getDefaultHeaderMenuOptions(), ...this.sharedService.gridOptions.headerMenu };\r\n if (this.sharedService.gridOptions.enableHeaderMenu) {\r\n this.sharedService.gridOptions.headerMenu = this.addHeaderMenuCustomCommands(this.sharedService.gridOptions, this.sharedService.columnDefinitions);\r\n }\r\n\r\n this._addon = new Slick.Plugins.HeaderMenu(this.sharedService.gridOptions.headerMenu);\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // hook all events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.headerMenu) {\r\n if (this.sharedService.gridOptions.headerMenu.onExtensionRegistered) {\r\n this.sharedService.gridOptions.headerMenu.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onCommand, (e: any, args: HeaderMenuOnCommandArgs) => {\r\n this.executeHeaderMenuInternalCommands(e, args);\r\n if (this.sharedService.gridOptions.headerMenu && typeof this.sharedService.gridOptions.headerMenu.onCommand === 'function') {\r\n this.sharedService.gridOptions.headerMenu.onCommand(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onBeforeMenuShow, (e: any, args: HeaderMenuOnBeforeMenuShowArgs) => {\r\n if (this.sharedService.gridOptions.headerMenu && typeof this.sharedService.gridOptions.headerMenu.onBeforeMenuShow === 'function') {\r\n this.sharedService.gridOptions.headerMenu.onBeforeMenuShow(e, args);\r\n }\r\n });\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Create Header Menu with Custom Commands if user has enabled Header Menu\r\n * @param options\r\n * @param columnDefinitions\r\n * @return header menu\r\n */\r\n private addHeaderMenuCustomCommands(options: GridOption, columnDefinitions: Column[]): HeaderMenu {\r\n const headerMenuOptions = options.headerMenu || {};\r\n\r\n if (columnDefinitions && Array.isArray(columnDefinitions) && options.enableHeaderMenu) {\r\n columnDefinitions.forEach((columnDef: Column) => {\r\n if (columnDef && !columnDef.excludeFromHeaderMenu) {\r\n if (!columnDef.header || !columnDef.header.menu) {\r\n columnDef.header = {\r\n menu: {\r\n items: []\r\n }\r\n };\r\n }\r\n\r\n const columnHeaderMenuItems: HeaderMenuItem[] = columnDef && columnDef.header && columnDef.header.menu && columnDef.header.menu.items || [];\r\n\r\n // Sorting Commands\r\n if (options.enableSorting && columnDef.sortable && headerMenuOptions && !headerMenuOptions.hideSortCommands) {\r\n if (columnHeaderMenuItems.filter((item: HeaderMenuItem) => item.command === 'sort-asc').length === 0) {\r\n columnHeaderMenuItems.push({\r\n iconCssClass: headerMenuOptions.iconSortAscCommand || 'fa fa-sort-asc',\r\n title: options.enableTranslate ? this.translate.instant('SORT_ASCENDING') : Constants.TEXT_SORT_ASCENDING,\r\n command: 'sort-asc',\r\n positionOrder: 50\r\n });\r\n }\r\n if (columnHeaderMenuItems.filter((item: HeaderMenuItem) => item.command === 'sort-desc').length === 0) {\r\n columnHeaderMenuItems.push({\r\n iconCssClass: headerMenuOptions.iconSortDescCommand || 'fa fa-sort-desc',\r\n title: options.enableTranslate ? this.translate.instant('SORT_DESCENDING') : Constants.TEXT_SORT_DESCENDING,\r\n command: 'sort-desc',\r\n positionOrder: 51\r\n });\r\n }\r\n\r\n // add a divider (separator) between the top sort commands and the other clear commands\r\n if (columnHeaderMenuItems.filter((item: HeaderMenuItem) => item.positionOrder === 52).length === 0) {\r\n columnHeaderMenuItems.push({ divider: true, command: '', positionOrder: 52 });\r\n }\r\n\r\n if (!headerMenuOptions.hideClearSortCommand && columnHeaderMenuItems.filter((item: HeaderMenuItem) => item.command === 'clear-sort').length === 0) {\r\n columnHeaderMenuItems.push({\r\n iconCssClass: headerMenuOptions.iconClearSortCommand || 'fa fa-unsorted',\r\n title: options.enableTranslate ? this.translate.instant('REMOVE_SORT') : Constants.TEXT_REMOVE_SORT,\r\n command: 'clear-sort',\r\n positionOrder: 54\r\n });\r\n }\r\n }\r\n\r\n // Filtering Commands\r\n if (options.enableFiltering && columnDef.filterable && headerMenuOptions && !headerMenuOptions.hideFilterCommands) {\r\n if (!headerMenuOptions.hideClearFilterCommand && columnHeaderMenuItems.filter((item: HeaderMenuItem) => item.command === 'clear-filter').length === 0) {\r\n columnHeaderMenuItems.push({\r\n iconCssClass: headerMenuOptions.iconClearFilterCommand || 'fa fa-filter',\r\n title: options.enableTranslate ? this.translate.instant('REMOVE_FILTER') : Constants.TEXT_REMOVE_FILTER,\r\n command: 'clear-filter',\r\n positionOrder: 53\r\n });\r\n }\r\n }\r\n\r\n // Hide Column Command\r\n if (headerMenuOptions && !headerMenuOptions.hideColumnHideCommand && columnHeaderMenuItems.filter((item: HeaderMenuItem) => item.command === 'hide').length === 0) {\r\n columnHeaderMenuItems.push({\r\n iconCssClass: headerMenuOptions.iconColumnHideCommand || 'fa fa-times',\r\n title: options.enableTranslate ? this.translate.instant('HIDE_COLUMN') : Constants.TEXT_HIDE_COLUMN,\r\n command: 'hide',\r\n positionOrder: 55\r\n });\r\n }\r\n\r\n this.extensionUtility.translateItems(columnHeaderMenuItems, 'titleKey', 'title');\r\n this.extensionUtility.sortItems(columnHeaderMenuItems, 'positionOrder');\r\n }\r\n });\r\n }\r\n return headerMenuOptions;\r\n }\r\n\r\n /** Hide a column from the grid */\r\n hideColumn(column: Column) {\r\n if (this.sharedService.grid && this.sharedService.grid.getColumns && this.sharedService.grid.setColumns && this.sharedService.grid.getColumnIndex) {\r\n const columnIndex = this.sharedService.grid.getColumnIndex(column.id);\r\n const currentColumns = this.sharedService.grid.getColumns();\r\n const visibleColumns = this.extensionUtility.arrayRemoveItemByIndex(currentColumns, columnIndex);\r\n this.sharedService.visibleColumns = visibleColumns;\r\n this.sharedService.grid.setColumns(visibleColumns);\r\n }\r\n }\r\n\r\n /**\r\n * Translate the Header Menu titles, we need to loop through all column definition to re-translate them\r\n */\r\n translateHeaderMenu() {\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.headerMenu) {\r\n this.resetHeaderMenuTranslations(this.sharedService.visibleColumns);\r\n }\r\n }\r\n\r\n // --\r\n // private functions\r\n // ------------------\r\n\r\n /** @return default Header Menu options */\r\n private getDefaultHeaderMenuOptions(): HeaderMenu {\r\n return {\r\n autoAlignOffset: 12,\r\n minWidth: 140,\r\n hideColumnHideCommand: false,\r\n hideSortCommands: false,\r\n title: ''\r\n };\r\n }\r\n\r\n /**\r\n * Reset all the Grid Menu options which have text to translate\r\n * @param grid menu object\r\n */\r\n private resetHeaderMenuTranslations(columnDefinitions: Column[]) {\r\n columnDefinitions.forEach((columnDef: Column) => {\r\n if (columnDef && columnDef.header && columnDef.header && columnDef.header.menu && columnDef.header.menu.items) {\r\n if (!columnDef.excludeFromHeaderMenu) {\r\n const columnHeaderMenuItems: HeaderMenuItem[] = columnDef.header.menu.items || [];\r\n columnHeaderMenuItems.forEach((item) => {\r\n switch (item.command) {\r\n case 'clear-filter':\r\n item.title = this.translate.instant('REMOVE_FILTER') || Constants.TEXT_REMOVE_FILTER;\r\n break;\r\n case 'clear-sort':\r\n item.title = this.translate.instant('REMOVE_SORT') || Constants.TEXT_REMOVE_SORT;\r\n break;\r\n case 'sort-asc':\r\n item.title = this.translate.instant('SORT_ASCENDING') || Constants.TEXT_SORT_ASCENDING;\r\n break;\r\n case 'sort-desc':\r\n item.title = this.translate.instant('SORT_DESCENDING') || Constants.TEXT_SORT_DESCENDING;\r\n break;\r\n case 'hide':\r\n item.title = this.translate.instant('HIDE_COLUMN') || Constants.TEXT_HIDE_COLUMN;\r\n break;\r\n }\r\n\r\n // re-translate if there's a \"titleKey\"\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableTranslate) {\r\n this.extensionUtility.translateItems(columnHeaderMenuItems, 'titleKey', 'title');\r\n }\r\n });\r\n }\r\n }\r\n });\r\n }\r\n\r\n /** Clear the Filter on the current column (if it's actually filtered) */\r\n private clearColumnFilter(event: Event, args: HeaderMenuOnCommandArgs) {\r\n if (args && args.column) {\r\n this.filterService.clearFilterByColumnId(event, args.column.id);\r\n }\r\n }\r\n\r\n /** Clear the Sort on the current column (if it's actually sorted) */\r\n private clearColumnSort(event: Event, args: HeaderMenuOnCommandArgs) {\r\n if (args && args.column && this.sharedService) {\r\n // get current sorted columns, prior to calling the new column sort\r\n const allSortedCols: ColumnSort[] = this.sortService.getCurrentColumnSorts();\r\n const sortedColsWithoutCurrent: ColumnSort[] = this.sortService.getCurrentColumnSorts(args.column.id + '');\r\n\r\n if (Array.isArray(allSortedCols) && Array.isArray(sortedColsWithoutCurrent) && allSortedCols.length !== sortedColsWithoutCurrent.length) {\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.backendServiceApi) {\r\n this.sortService.onBackendSortChanged(event, { multiColumnSort: true, sortCols: sortedColsWithoutCurrent, grid: this.sharedService.grid });\r\n } else if (this.sharedService.dataView) {\r\n this.sortService.onLocalSortChanged(this.sharedService.grid, this.sharedService.dataView, sortedColsWithoutCurrent, true);\r\n } else {\r\n // when using customDataView, we will simply send it as a onSort event with notify\r\n const isMultiSort = this.sharedService.gridOptions && this.sharedService.gridOptions.multiColumnSort || false;\r\n const sortOutput = isMultiSort ? sortedColsWithoutCurrent : sortedColsWithoutCurrent[0];\r\n args.grid.onSort.notify(sortOutput);\r\n }\r\n\r\n // update the this.sharedService.gridObj sortColumns array which will at the same add the visual sort icon(s) on the UI\r\n const updatedSortColumns: ColumnSort[] = sortedColsWithoutCurrent.map((col) => {\r\n return {\r\n columnId: col && col.sortCol && col.sortCol.id,\r\n sortAsc: col && col.sortAsc,\r\n sortCol: col && col.sortCol,\r\n };\r\n });\r\n this.sharedService.grid.setSortColumns(updatedSortColumns); // add sort icon in UI\r\n }\r\n }\r\n }\r\n\r\n /** Execute the Header Menu Commands that was triggered by the onCommand subscribe */\r\n private executeHeaderMenuInternalCommands(event: Event, args: HeaderMenuOnCommandArgs) {\r\n if (args && args.command) {\r\n switch (args.command) {\r\n case 'hide':\r\n this.hideColumn(args.column);\r\n if (this.sharedService.gridOptions && this.sharedService.gridOptions.enableAutoSizeColumns) {\r\n this.sharedService.grid.autosizeColumns();\r\n }\r\n break;\r\n case 'clear-filter':\r\n this.clearColumnFilter(event, args);\r\n break;\r\n case 'clear-sort':\r\n this.clearColumnSort(event, args);\r\n break;\r\n case 'sort-asc':\r\n case 'sort-desc':\r\n const isSortingAsc = (args.command === 'sort-asc');\r\n this.sortColumn(event, args, isSortingAsc);\r\n break;\r\n default:\r\n break;\r\n }\r\n }\r\n }\r\n\r\n /** Sort the current column */\r\n private sortColumn(event: Event, args: HeaderMenuOnCommandArgs, isSortingAsc = true) {\r\n if (args && args.column) {\r\n // get previously sorted columns\r\n const sortedColsWithoutCurrent: ColumnSort[] = this.sortService.getCurrentColumnSorts(args.column.id + '');\r\n\r\n // add to the column array, the column sorted by the header menu\r\n sortedColsWithoutCurrent.push({ sortCol: args.column, sortAsc: isSortingAsc });\r\n if (this.sharedService.gridOptions.backendServiceApi) {\r\n this.sortService.onBackendSortChanged(event, { multiColumnSort: true, sortCols: sortedColsWithoutCurrent, grid: this.sharedService.grid });\r\n } else if (this.sharedService.dataView) {\r\n this.sortService.onLocalSortChanged(this.sharedService.grid, this.sharedService.dataView, sortedColsWithoutCurrent);\r\n } else {\r\n // when using customDataView, we will simply send it as a onSort event with notify\r\n const isMultiSort = this.sharedService && this.sharedService.gridOptions && this.sharedService.gridOptions.multiColumnSort || false;\r\n const sortOutput = isMultiSort ? sortedColsWithoutCurrent : sortedColsWithoutCurrent[0];\r\n args.grid.onSort.notify(sortOutput);\r\n }\r\n\r\n // update the this.sharedService.gridObj sortColumns array which will at the same add the visual sort icon(s) on the UI\r\n const newSortColumns: ColumnSort[] = sortedColsWithoutCurrent.map((col) => {\r\n return {\r\n columnId: col && col.sortCol && col.sortCol.id,\r\n sortAsc: col && col.sortAsc,\r\n sortCol: col && col.sortCol,\r\n };\r\n });\r\n this.sharedService.grid.setSortColumns(newSortColumns); // add sort icon in UI\r\n }\r\n }\r\n}\r\n","import { ApplicationRef, ComponentRef, Injectable, Type, ViewContainerRef } from '@angular/core';\r\nimport { Column, Extension, ExtensionName, GridOption, SlickEventHandler } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { AngularUtilService } from '../services/angularUtil.service';\r\nimport { FilterService } from '../services/filter.service';\r\nimport { SharedService } from '../services/shared.service';\r\nimport { addToArrayWhenNotExists, castToPromise, unsubscribeAllObservables } from '../services/utilities';\r\nimport { Observable, Subject, Subscription } from 'rxjs';\r\nimport * as DOMPurify_ from 'dompurify';\r\nconst DOMPurify = DOMPurify_; // patch to fix rollup to work\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\nconst ROW_DETAIL_CONTAINER_PREFIX = 'container_';\r\nconst PRELOAD_CONTAINER_PREFIX = 'container_loading';\r\n\r\nexport interface CreatedView {\r\n id: string | number;\r\n dataContext: any;\r\n componentRef?: ComponentRef<any>;\r\n}\r\n\r\n@Injectable()\r\nexport class RowDetailViewExtension implements Extension {\r\n rowDetailContainer: ViewContainerRef;\r\n private _addon: any;\r\n private _eventHandler: SlickEventHandler;\r\n private _preloadComponent: Type<object>;\r\n private _views: CreatedView[] = [];\r\n private _viewComponent: Type<object>;\r\n private _subscriptions: Subscription[] = [];\r\n private _userProcessFn: (item: any) => Promise<any> | Observable<any> | Subject<any>;\r\n\r\n constructor(\r\n private angularUtilService: AngularUtilService,\r\n private appRef: ApplicationRef,\r\n private extensionUtility: ExtensionUtility,\r\n private filterService: FilterService,\r\n private sharedService: SharedService,\r\n ) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n /** Dispose of the RowDetailView Extension */\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n\r\n // also unsubscribe all RxJS subscriptions\r\n this._subscriptions = unsubscribeAllObservables(this._subscriptions);\r\n this.disposeAllViewComponents();\r\n }\r\n\r\n /** Dispose of all the opened Row Detail Panels Angular View Components */\r\n disposeAllViewComponents() {\r\n this._views.forEach((compRef) => this.disposeViewComponent(compRef));\r\n this._views = [];\r\n }\r\n\r\n /**\r\n * Create the plugin before the Grid creation, else it will behave oddly.\r\n * Mostly because the column definitions might change after the grid creation\r\n */\r\n create(columnDefinitions: Column[], gridOptions: GridOption) {\r\n if (columnDefinitions && gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.rowDetailView);\r\n\r\n if (!gridOptions.rowDetailView) {\r\n throw new Error('The Row Detail View requires options to be passed via the \"rowDetailView\" property of the Grid Options');\r\n }\r\n\r\n if (gridOptions && gridOptions.rowDetailView) {\r\n if (!this._addon) {\r\n if (typeof gridOptions.rowDetailView.process === 'function') {\r\n // we need to keep the user \"process\" method and replace it with our own execution method\r\n // we do this because when we get the item detail, we need to call \"onAsyncResponse.notify\" for the plugin to work\r\n this._userProcessFn = gridOptions.rowDetailView.process; // keep user's process method\r\n gridOptions.rowDetailView.process = (item) => this.onProcessing(item); // replace process method & run our internal one\r\n } else {\r\n throw new Error('You need to provide a \"process\" function for the Row Detail Extension to work properly');\r\n }\r\n\r\n // load the Preload & RowDetail Templates (could be straight HTML or Angular View/ViewModel)\r\n // when those are Angular View/ViewModel, we need to create View Component & provide the html containers to the Plugin (preTemplate/postTemplate methods)\r\n if (!gridOptions.rowDetailView.preTemplate) {\r\n this._preloadComponent = gridOptions && gridOptions.rowDetailView && gridOptions.rowDetailView.preloadComponent;\r\n gridOptions.rowDetailView.preTemplate = () => DOMPurify.sanitize(`<div class=\"${PRELOAD_CONTAINER_PREFIX}\"></div>`);\r\n }\r\n if (!gridOptions.rowDetailView.postTemplate) {\r\n this._viewComponent = gridOptions && gridOptions.rowDetailView && gridOptions.rowDetailView.viewComponent;\r\n gridOptions.rowDetailView.postTemplate = (itemDetail: any) => DOMPurify.sanitize(`<div class=\"${ROW_DETAIL_CONTAINER_PREFIX}${itemDetail.id}\"></div>`);\r\n }\r\n\r\n // finally register the Row Detail View Plugin\r\n this._addon = new Slick.Plugins.RowDetailView(gridOptions.rowDetailView);\r\n }\r\n const selectionColumn: Column = this._addon.getColumnDefinition();\r\n if (typeof selectionColumn === 'object') {\r\n selectionColumn.excludeFromExport = true;\r\n selectionColumn.excludeFromColumnPicker = true;\r\n selectionColumn.excludeFromGridMenu = true;\r\n selectionColumn.excludeFromQuery = true;\r\n selectionColumn.excludeFromHeaderMenu = true;\r\n columnDefinitions.unshift(selectionColumn);\r\n }\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n register(rowSelectionPlugin?: any) {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // the plugin has to be created BEFORE the grid (else it behaves oddly), but we can only watch grid events AFTER the grid is created\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // this also requires the Row Selection Model to be registered as well\r\n if (!rowSelectionPlugin || !this.sharedService.grid.getSelectionModel()) {\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.rowSelection);\r\n rowSelectionPlugin = new Slick.RowSelectionModel(this.sharedService.gridOptions.rowSelectionOptions || { selectActiveRow: true });\r\n this.sharedService.grid.setSelectionModel(rowSelectionPlugin);\r\n }\r\n\r\n // hook all events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.rowDetailView) {\r\n if (this.sharedService.gridOptions.rowDetailView.onExtensionRegistered) {\r\n this.sharedService.gridOptions.rowDetailView.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onAsyncResponse, (e: any, args: { item: any; detailView: any }) => {\r\n if (this.sharedService.gridOptions.rowDetailView && typeof this.sharedService.gridOptions.rowDetailView.onAsyncResponse === 'function') {\r\n this.sharedService.gridOptions.rowDetailView.onAsyncResponse(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onAsyncEndUpdate, (e: any, args: { grid: any; item: any; }) => {\r\n // triggers after backend called \"onAsyncResponse.notify()\"\r\n this.renderViewModel(args && args.item);\r\n\r\n if (this.sharedService.gridOptions.rowDetailView && typeof this.sharedService.gridOptions.rowDetailView.onAsyncEndUpdate === 'function') {\r\n this.sharedService.gridOptions.rowDetailView.onAsyncEndUpdate(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onAfterRowDetailToggle, (e: any, args: { grid: any; item: any; expandedRows: any[]; }) => {\r\n // display preload template & re-render all the other Detail Views after toggling\r\n // the preload View will eventually go away once the data gets loaded after the \"onAsyncEndUpdate\" event\r\n this.renderPreloadView();\r\n this.renderAllViewComponents();\r\n\r\n if (this.sharedService.gridOptions.rowDetailView && typeof this.sharedService.gridOptions.rowDetailView.onAfterRowDetailToggle === 'function') {\r\n this.sharedService.gridOptions.rowDetailView.onAfterRowDetailToggle(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onBeforeRowDetailToggle, (e: any, args: { grid: any; item: any; }) => {\r\n // before toggling row detail, we need to create View Component if it doesn't exist\r\n this.onBeforeRowDetailToggle(e, args);\r\n\r\n if (this.sharedService.gridOptions.rowDetailView && typeof this.sharedService.gridOptions.rowDetailView.onBeforeRowDetailToggle === 'function') {\r\n this.sharedService.gridOptions.rowDetailView.onBeforeRowDetailToggle(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onRowBackToViewportRange, (e: any, args: { grid: any; item: any; rowId: number; rowIndex: number; expandedRows: any[]; rowIdsOutOfViewport: number[]; }) => {\r\n // when row is back to viewport range, we will re-render the View Component(s)\r\n this.onRowBackToViewportRange(e, args);\r\n\r\n if (this.sharedService.gridOptions.rowDetailView && typeof this.sharedService.gridOptions.rowDetailView.onRowBackToViewportRange === 'function') {\r\n this.sharedService.gridOptions.rowDetailView.onRowBackToViewportRange(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onRowOutOfViewportRange, (e: any, args: { grid: any; item: any; rowId: number; rowIndex: number; expandedRows: any[]; rowIdsOutOfViewport: number[]; }) => {\r\n if (this.sharedService.gridOptions.rowDetailView && typeof this.sharedService.gridOptions.rowDetailView.onRowOutOfViewportRange === 'function') {\r\n this.sharedService.gridOptions.rowDetailView.onRowOutOfViewportRange(e, args);\r\n }\r\n });\r\n\r\n // --\r\n // hook some events needed by the Plugin itself\r\n\r\n this._eventHandler.subscribe(this.sharedService.grid.onColumnsReordered, () => this.redrawAllViewComponents());\r\n\r\n // on sort, all row detail are collapsed so we can dispose of all the Views as well\r\n this._eventHandler.subscribe(this.sharedService.grid.onSort, () => this.disposeAllViewComponents());\r\n\r\n // on filter changed, we need to re-render all Views\r\n this._subscriptions.push(\r\n this.filterService.onFilterChanged.subscribe(() => this.redrawAllViewComponents())\r\n );\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n\r\n // --\r\n // private functions\r\n // ------------------\r\n\r\n private disposeViewComponent(expandedView: CreatedView) {\r\n const compRef = expandedView && expandedView.componentRef;\r\n if (compRef) {\r\n this.appRef.detachView(compRef.hostView);\r\n compRef.destroy();\r\n return expandedView;\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * notify the onAsyncResponse with the \"args.item\" (required property)\r\n * the plugin will then use item to populate the row detail panel with the \"postTemplate\"\r\n * @param item\r\n */\r\n private notifyTemplate(item: any) {\r\n if (this._addon) {\r\n this._addon.onAsyncResponse.notify({ item }, undefined, this);\r\n }\r\n }\r\n\r\n /**\r\n * On Processing, we will notify the plugin with the new item detail once backend server call completes\r\n * @param item\r\n */\r\n private async onProcessing(item: any) {\r\n if (item && typeof this._userProcessFn === 'function') {\r\n let awaitedItemDetail: any;\r\n const userProcessFn = this._userProcessFn(item);\r\n\r\n // wait for the \"userProcessFn\", once resolved we will save it into the \"collection\"\r\n const response: any | any[] = await userProcessFn;\r\n\r\n if (response.hasOwnProperty('id')) {\r\n awaitedItemDetail = response; // from Promise\r\n } else if (response && response instanceof Observable || response instanceof Promise) {\r\n awaitedItemDetail = await castToPromise(response); // from Angular-http-client\r\n }\r\n\r\n if (!awaitedItemDetail || !awaitedItemDetail.hasOwnProperty('id')) {\r\n throw new Error(`[Angular-Slickgrid] could not process the Row Detail, you must make sure that your \"process\" callback\r\n (a Promise or an HttpClient call returning an Observable) returns an item object that has an \"id\" property`);\r\n }\r\n\r\n // notify the plugin with the new item details\r\n this.notifyTemplate(awaitedItemDetail || {});\r\n }\r\n }\r\n\r\n /**\r\n * Just before the row get expanded or collapsed we will do the following\r\n * First determine if the row is expanding or collapsing,\r\n * if it's expanding we will add it to our View Components reference array if we don't already have it\r\n * or if it's collapsing we will remove it from our View Components reference array\r\n */\r\n private onBeforeRowDetailToggle(e: Event, args: { grid: any; item: any; }) {\r\n // expanding\r\n if (args && args.item && args.item.__collapsed) {\r\n // expanding row detail\r\n const viewInfo: CreatedView = {\r\n id: args.item.id,\r\n dataContext: args.item\r\n };\r\n addToArrayWhenNotExists(this._views, viewInfo);\r\n } else {\r\n // collapsing, so dispose of the View/Component\r\n const foundViewIndex = this._views.findIndex((view: CreatedView) => view.id === args.item.id);\r\n if (foundViewIndex >= 0 && this._views.hasOwnProperty(foundViewIndex)) {\r\n const compRef = this._views[foundViewIndex].componentRef;\r\n this.appRef.detachView(compRef.hostView);\r\n compRef.destroy();\r\n this._views.splice(foundViewIndex, 1);\r\n }\r\n }\r\n }\r\n\r\n /** When Row comes back to Viewport Range, we need to redraw the View */\r\n private onRowBackToViewportRange(e: Event, args: { grid: any; item: any; rowId: number; rowIndex: number; expandedRows: any[]; rowIdsOutOfViewport: number[]; }) {\r\n if (args && args.item) {\r\n this._views.forEach((view) => {\r\n if (view.id === args.item.id) {\r\n this.redrawViewComponent(view);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /** Redraw (re-render) all the expanded row detail View Components */\r\n private redrawAllViewComponents() {\r\n this._views.forEach((compRef) => {\r\n this.redrawViewComponent(compRef);\r\n });\r\n }\r\n\r\n /** Render all the expanded row detail View Components */\r\n private renderAllViewComponents() {\r\n this._views.forEach((view) => {\r\n if (view && view.dataContext) {\r\n this.renderViewModel(view.dataContext);\r\n }\r\n });\r\n }\r\n\r\n /** Redraw the necessary View Component */\r\n private redrawViewComponent(createdView: CreatedView) {\r\n const containerElements = document.getElementsByClassName(`${ROW_DETAIL_CONTAINER_PREFIX}${createdView.id}`);\r\n if (containerElements && containerElements.length) {\r\n this.renderViewModel(createdView.dataContext);\r\n }\r\n }\r\n\r\n /** Render (or rerender) the View Component (Row Detail) */\r\n private renderPreloadView() {\r\n const containerElements = document.getElementsByClassName(`${PRELOAD_CONTAINER_PREFIX}`);\r\n if (containerElements && containerElements.length) {\r\n this.angularUtilService.createAngularComponentAppendToDom(this._preloadComponent, containerElements[0], true);\r\n }\r\n }\r\n\r\n /** Render (or rerender) the View Component (Row Detail) */\r\n private renderViewModel(item: any) {\r\n const containerElements = document.getElementsByClassName(`${ROW_DETAIL_CONTAINER_PREFIX}${item.id}`);\r\n if (containerElements && containerElements.length) {\r\n const componentOutput = this.angularUtilService.createAngularComponentAppendToDom(this._viewComponent, containerElements[0], true);\r\n if (componentOutput && componentOutput.componentRef && componentOutput.componentRef.instance) {\r\n Object.assign(componentOutput.componentRef.instance, { model: item });\r\n\r\n const viewObj = this._views.find((obj) => obj.id === item.id);\r\n if (viewObj) {\r\n viewObj.componentRef = componentOutput.componentRef;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { CellArgs, Extension, ExtensionName, SlickEventHandler } from '../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class RowMoveManagerExtension implements Extension {\r\n private _addon: any;\r\n private _eventHandler: SlickEventHandler;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n register(rowSelectionPlugin?: any): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.rowMoveManager);\r\n\r\n // this also requires the Row Selection Model to be registered as well\r\n if (!rowSelectionPlugin || !this.sharedService.grid.getSelectionModel()) {\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.rowSelection);\r\n rowSelectionPlugin = new Slick.RowSelectionModel(this.sharedService.gridOptions.rowSelectionOptions || {});\r\n this.sharedService.grid.setSelectionModel(rowSelectionPlugin);\r\n }\r\n\r\n this._addon = new Slick.RowMoveManager(this.sharedService.gridOptions.rowMoveManager || { cancelEditOnDrag: true });\r\n this.sharedService.grid.registerPlugin(this._addon);\r\n\r\n // hook all events\r\n if (this.sharedService.grid && this.sharedService.gridOptions.rowMoveManager) {\r\n if (this.sharedService.gridOptions.rowMoveManager.onExtensionRegistered) {\r\n this.sharedService.gridOptions.rowMoveManager.onExtensionRegistered(this._addon);\r\n }\r\n this._eventHandler.subscribe(this._addon.onBeforeMoveRows, (e: any, args: CellArgs) => {\r\n if (this.sharedService.gridOptions.rowMoveManager && typeof this.sharedService.gridOptions.rowMoveManager.onBeforeMoveRows === 'function') {\r\n this.sharedService.gridOptions.rowMoveManager.onBeforeMoveRows(e, args);\r\n }\r\n });\r\n this._eventHandler.subscribe(this._addon.onMoveRows, (e: any, args: CellArgs) => {\r\n if (this.sharedService.gridOptions.rowMoveManager && typeof this.sharedService.gridOptions.rowMoveManager.onMoveRows === 'function') {\r\n this.sharedService.gridOptions.rowMoveManager.onMoveRows(e, args);\r\n }\r\n });\r\n }\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { Extension, ExtensionName } from './../models/index';\r\nimport { ExtensionUtility } from './extensionUtility';\r\nimport { SharedService } from '../services/shared.service';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Injectable()\r\nexport class RowSelectionExtension implements Extension {\r\n private _addon: any;\r\n\r\n constructor(private extensionUtility: ExtensionUtility, private sharedService: SharedService) { }\r\n\r\n dispose() {\r\n if (this._addon && this._addon.destroy) {\r\n this._addon.destroy();\r\n }\r\n }\r\n\r\n register(): any {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.gridOptions) {\r\n // dynamically import the SlickGrid plugin (addon) with RequireJS\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.rowSelection);\r\n\r\n this._addon = new Slick.RowSelectionModel(this.sharedService.gridOptions.rowSelectionOptions || {});\r\n this.sharedService.grid.setSelectionModel(this._addon);\r\n return this._addon;\r\n }\r\n return null;\r\n }\r\n}\r\n","// import common 3rd party SlickGrid plugins/libs\r\nimport 'slickgrid/plugins/slick.cellrangedecorator';\r\nimport 'slickgrid/plugins/slick.cellrangeselector';\r\nimport 'slickgrid/plugins/slick.cellselectionmodel';\r\n\r\nimport { Injectable } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport {\r\n Column,\r\n ExtensionModel,\r\n ExtensionName,\r\n GridOption,\r\n} from '../models/index';\r\nimport {\r\n AutoTooltipExtension,\r\n CellExternalCopyManagerExtension,\r\n CheckboxSelectorExtension,\r\n ColumnPickerExtension,\r\n DraggableGroupingExtension,\r\n GridMenuExtension,\r\n GroupItemMetaProviderExtension,\r\n HeaderButtonExtension,\r\n HeaderMenuExtension,\r\n RowDetailViewExtension,\r\n RowMoveManagerExtension,\r\n RowSelectionExtension,\r\n} from '../extensions/index';\r\nimport { SharedService } from './shared.service';\r\n\r\n@Injectable()\r\nexport class ExtensionService {\r\n private _extensionList: ExtensionModel[] = [];\r\n\r\n constructor(\r\n private autoTooltipExtension: AutoTooltipExtension,\r\n private cellExternalCopyExtension: CellExternalCopyManagerExtension,\r\n private checkboxSelectorExtension: CheckboxSelectorExtension,\r\n private columnPickerExtension: ColumnPickerExtension,\r\n private draggableGroupingExtension: DraggableGroupingExtension,\r\n private gridMenuExtension: GridMenuExtension,\r\n private groupItemMetaExtension: GroupItemMetaProviderExtension,\r\n private headerButtonExtension: HeaderButtonExtension,\r\n private headerMenuExtension: HeaderMenuExtension,\r\n private rowDetailViewExtension: RowDetailViewExtension,\r\n private rowMoveManagerExtension: RowMoveManagerExtension,\r\n private rowSelectionExtension: RowSelectionExtension,\r\n private sharedService: SharedService,\r\n private translate: TranslateService,\r\n ) { }\r\n\r\n /** Dispose of all the controls & plugins */\r\n dispose() {\r\n this.sharedService.grid = null;\r\n this.sharedService.visibleColumns = [];\r\n\r\n // dispose of each control/plugin & reset the list\r\n this._extensionList.forEach((item) => {\r\n if (item && item.class && item.class.dispose) {\r\n item.class.dispose();\r\n }\r\n });\r\n this._extensionList = [];\r\n }\r\n\r\n /** Get all columns (includes visible and non-visible) */\r\n getAllColumns(): Column[] {\r\n return this.sharedService.allColumns || [];\r\n }\r\n\r\n /** Get only visible columns */\r\n getVisibleColumns(): Column[] {\r\n return this.sharedService.visibleColumns || [];\r\n }\r\n\r\n /** Get all Extensions */\r\n getAllExtensions(): ExtensionModel[] {\r\n return this._extensionList;\r\n }\r\n\r\n /**\r\n * Get an Extension by it's name\r\n * @param name\r\n */\r\n getExtensionByName(name: ExtensionName): ExtensionModel | undefined {\r\n return this._extensionList.find((p) => p.name === name);\r\n }\r\n\r\n /**\r\n * Get the instance of the SlickGrid addon (control or plugin).\r\n * This is the raw addon coming directly from SlickGrid itself, not to confuse with Angular-Slickgrid extension\r\n * @param name\r\n */\r\n getSlickgridAddonInstance(name: ExtensionName): any {\r\n const extension = this.getExtensionByName(name);\r\n if (extension && (extension.instance || extension.addon)) {\r\n return extension.instance;\r\n }\r\n return null;\r\n }\r\n\r\n /** Auto-resize all the column in the grid to fit the grid width */\r\n autoResizeColumns() {\r\n this.sharedService.grid.autosizeColumns();\r\n }\r\n\r\n /** Bind/Create different Controls or Plugins after the Grid is created */\r\n bindDifferentExtensions() {\r\n if (this.sharedService && this.sharedService.gridOptions) {\r\n // make sure all columns are translated before creating ColumnPicker/GridMenu Controls\r\n // this is to avoid having hidden columns not being translated on first load\r\n if (this.sharedService.gridOptions.enableTranslate) {\r\n this.translateItems(this.sharedService.allColumns, 'headerKey', 'name');\r\n }\r\n\r\n // Auto Tooltip Plugin\r\n if (this.sharedService.gridOptions.enableAutoTooltip) {\r\n if (this.autoTooltipExtension && this.autoTooltipExtension.register) {\r\n const instance = this.autoTooltipExtension.register()\r\n this._extensionList.push({ name: ExtensionName.autoTooltip, class: this.autoTooltipExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Cell External Copy Manager Plugin (Excel Like)\r\n if (this.sharedService.gridOptions.enableExcelCopyBuffer) {\r\n if (this.cellExternalCopyExtension && this.cellExternalCopyExtension.register) {\r\n const instance = this.cellExternalCopyExtension.register();\r\n this._extensionList.push({ name: ExtensionName.cellExternalCopyManager, class: this.cellExternalCopyExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Checkbox Selector Plugin\r\n if (this.sharedService.gridOptions.enableCheckboxSelector) {\r\n if (this.checkboxSelectorExtension && this.checkboxSelectorExtension.register) {\r\n const rowSelectionExtension = this.getExtensionByName(ExtensionName.rowSelection);\r\n const instance = this.checkboxSelectorExtension.register(rowSelectionExtension);\r\n this._extensionList.push({ name: ExtensionName.checkboxSelector, class: this.checkboxSelectorExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Column Picker Control\r\n if (this.sharedService.gridOptions.enableColumnPicker) {\r\n if (this.columnPickerExtension && this.columnPickerExtension.register) {\r\n const instance = this.columnPickerExtension.register();\r\n this._extensionList.push({ name: ExtensionName.columnPicker, class: this.columnPickerExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Draggable Grouping Plugin\r\n if (this.sharedService.gridOptions.enableDraggableGrouping) {\r\n if (this.draggableGroupingExtension && this.draggableGroupingExtension.register) {\r\n const instance = this.draggableGroupingExtension.register();\r\n this._extensionList.push({ name: ExtensionName.draggableGrouping, class: this.draggableGroupingExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Grid Menu Control\r\n if (this.sharedService.gridOptions.enableGridMenu) {\r\n if (this.gridMenuExtension && this.gridMenuExtension.register) {\r\n const instance = this.gridMenuExtension.register();\r\n this._extensionList.push({ name: ExtensionName.gridMenu, class: this.gridMenuExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Grouping Plugin\r\n // register the group item metadata provider to add expand/collapse group handlers\r\n if (this.sharedService.gridOptions.enableDraggableGrouping || this.sharedService.gridOptions.enableGrouping) {\r\n if (this.groupItemMetaExtension && this.groupItemMetaExtension.register) {\r\n const instance = this.groupItemMetaExtension.register();\r\n this._extensionList.push({ name: ExtensionName.groupItemMetaProvider, class: this.groupItemMetaExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Header Button Plugin\r\n if (this.sharedService.gridOptions.enableHeaderButton) {\r\n if (this.headerButtonExtension && this.headerButtonExtension.register) {\r\n const instance = this.headerButtonExtension.register();\r\n this._extensionList.push({ name: ExtensionName.headerButton, class: this.headerButtonExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Header Menu Plugin\r\n if (this.sharedService.gridOptions.enableHeaderMenu) {\r\n if (this.headerMenuExtension && this.headerMenuExtension.register) {\r\n const instance = this.headerMenuExtension.register();\r\n this._extensionList.push({ name: ExtensionName.headerMenu, class: this.headerMenuExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Row Detail View Plugin\r\n if (this.sharedService.gridOptions.enableRowDetailView) {\r\n if (this.rowDetailViewExtension && this.rowDetailViewExtension.register) {\r\n const rowSelectionExtension = this.getExtensionByName(ExtensionName.rowSelection);\r\n const instance = this.rowDetailViewExtension.register(rowSelectionExtension);\r\n this._extensionList.push({ name: ExtensionName.rowDetailView, class: this.rowDetailViewExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Row Move Manager Plugin\r\n if (this.sharedService.gridOptions.enableRowMoveManager) {\r\n if (this.rowMoveManagerExtension && this.rowMoveManagerExtension.register) {\r\n const instance = this.rowMoveManagerExtension.register();\r\n this._extensionList.push({ name: ExtensionName.rowMoveManager, class: this.rowMoveManagerExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // Row Selection Plugin\r\n if (!this.sharedService.gridOptions.enableCheckboxSelector && this.sharedService.gridOptions.enableRowSelection) {\r\n if (this.rowSelectionExtension && this.rowSelectionExtension.register) {\r\n const instance = this.rowSelectionExtension.register();\r\n this._extensionList.push({ name: ExtensionName.rowSelection, class: this.rowSelectionExtension, addon: instance, instance });\r\n }\r\n }\r\n\r\n // manually register other plugins\r\n if (this.sharedService.gridOptions.registerPlugins !== undefined) {\r\n if (Array.isArray(this.sharedService.gridOptions.registerPlugins)) {\r\n this.sharedService.gridOptions.registerPlugins.forEach((plugin) => {\r\n const instance = this.sharedService.grid.registerPlugin(plugin);\r\n this._extensionList.push({ name: ExtensionName.noname, class: null, addon: instance, instance });\r\n });\r\n } else {\r\n this.sharedService.grid.registerPlugin(this.sharedService.gridOptions.registerPlugins);\r\n const plugin = this.sharedService.gridOptions.registerPlugins;\r\n const instance = this.sharedService.grid.registerPlugin(plugin);\r\n this._extensionList.push({ name: ExtensionName.noname, class: null, addon: instance, instance });\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Bind/Create certain plugins before the Grid creation, else they might behave oddly.\r\n * Mostly because the column definitions might change after the grid creation\r\n * @param columnDefinitions\r\n * @param options\r\n */\r\n createExtensionsBeforeGridCreation(columnDefinitions: Column[], options: GridOption) {\r\n if (options.enableCheckboxSelector) {\r\n this.checkboxSelectorExtension.create(columnDefinitions, options);\r\n }\r\n if (options.enableRowDetailView) {\r\n this.rowDetailViewExtension.create(columnDefinitions, options);\r\n }\r\n if (options.enableDraggableGrouping) {\r\n const plugin = this.draggableGroupingExtension.create(options);\r\n options.enableColumnReorder = plugin.getSetupColumnReorder;\r\n }\r\n }\r\n\r\n /** Hide a column from the grid */\r\n hideColumn(column: Column) {\r\n if (this.sharedService && this.sharedService.grid && this.sharedService.grid.getColumns && this.sharedService.grid.setColumns) {\r\n const columnIndex = this.sharedService.grid.getColumnIndex(column.id);\r\n this.sharedService.visibleColumns = this.removeColumnByIndex(this.sharedService.grid.getColumns(), columnIndex);\r\n this.sharedService.grid.setColumns(this.sharedService.visibleColumns);\r\n }\r\n }\r\n\r\n /** Refresh the dataset through the Backend Service */\r\n refreshBackendDataset(gridOptions?: GridOption) {\r\n this.gridMenuExtension.refreshBackendDataset(gridOptions);\r\n }\r\n\r\n /**\r\n * Remove a column from the grid by it's index in the grid\r\n * @param columns input\r\n * @param index\r\n */\r\n removeColumnByIndex(columns: Column[], index: number): Column[] {\r\n if (Array.isArray(columns)) {\r\n return columns.filter((el: Column, i: number) => index !== i);\r\n }\r\n return columns;\r\n }\r\n\r\n /** Translate the Column Picker and it's last 2 checkboxes */\r\n translateColumnPicker() {\r\n if (this.columnPickerExtension && this.columnPickerExtension.translateColumnPicker) {\r\n this.columnPickerExtension.translateColumnPicker();\r\n }\r\n }\r\n\r\n /**\r\n * Translate the Header Menu titles, we need to loop through all column definition to re-translate them\r\n */\r\n translateGridMenu() {\r\n if (this.gridMenuExtension && this.gridMenuExtension.translateGridMenu) {\r\n this.gridMenuExtension.translateGridMenu();\r\n }\r\n }\r\n\r\n /**\r\n * Translate the Header Menu titles, we need to loop through all column definition to re-translate them\r\n */\r\n translateHeaderMenu() {\r\n if (this.headerMenuExtension && this.headerMenuExtension.translateHeaderMenu) {\r\n this.headerMenuExtension.translateHeaderMenu();\r\n }\r\n }\r\n\r\n /**\r\n * Translate manually the header titles.\r\n * We could optionally pass a locale (that will change currently loaded locale), else it will use current locale\r\n * @param locale to use\r\n * @param new column definitions (optional)\r\n */\r\n translateColumnHeaders(locale?: boolean | string, newColumnDefinitions?: Column[]) {\r\n if (locale) {\r\n this.translate.use(locale as string);\r\n }\r\n\r\n let columnDefinitions = newColumnDefinitions;\r\n if (!columnDefinitions) {\r\n columnDefinitions = this.sharedService.columnDefinitions;\r\n }\r\n\r\n this.translateItems(columnDefinitions, 'headerKey', 'name');\r\n this.translateItems(this.sharedService.allColumns, 'headerKey', 'name');\r\n\r\n // re-render the column headers\r\n this.renderColumnHeaders(columnDefinitions);\r\n }\r\n\r\n /**\r\n * Render (or re-render) the column headers from column definitions.\r\n * calling setColumns() will trigger a grid re-render\r\n */\r\n renderColumnHeaders(newColumnDefinitions?: Column[]) {\r\n let collection = newColumnDefinitions;\r\n if (!collection) {\r\n collection = this.sharedService.columnDefinitions;\r\n }\r\n if (Array.isArray(collection) && this.sharedService.grid && this.sharedService.grid.setColumns) {\r\n this.sharedService.grid.setColumns(collection);\r\n }\r\n }\r\n\r\n /** Translate an array of items from an input key and assign translated value to the output key */\r\n private translateItems(items: any[], inputKey: string, outputKey: string) {\r\n if (Array.isArray(items)) {\r\n for (const item of items) {\r\n if (item[inputKey]) {\r\n item[outputKey] = this.translate.instant(item[inputKey]);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * This GraphqlQueryBuilder class is a lib that already exist\r\n * but was causing issues with TypeScript, RequireJS and other bundler/packagers\r\n * and so I rewrote it in pure TypeScript.\r\n *\r\n * The previous lib can be viewed here at this Github\r\n * https://github.com/codemeasandwich/graphql-query-builder\r\n */\r\nexport default class GraphqlQueryBuilder {\r\n alias: string | Function;\r\n head: any[] = [];\r\n body: any;\r\n\r\n /* Constructor, query/mutator you wish to use, and an alias or filter arguments. */\r\n constructor(private queryFnName: string, aliasOrFilter?: string | object) {\r\n if (typeof aliasOrFilter === 'string') {\r\n this.alias = aliasOrFilter;\r\n } else if (typeof aliasOrFilter === 'object') {\r\n this.filter(aliasOrFilter);\r\n } else if (aliasOrFilter === undefined && arguments.length === 2) {\r\n throw new TypeError(`You have passed undefined as Second argument to \"Query\"`);\r\n } else if (aliasOrFilter !== undefined) {\r\n throw new TypeError(`Second argument to \"Query\" should be an alias name(String) or filter arguments(Object). What was passed is: ${aliasOrFilter}`);\r\n }\r\n }\r\n\r\n /**\r\n * The parameters to run the query against.\r\n * @param filters An object mapping attribute to values\r\n */\r\n filter(filters: any) {\r\n for (const prop of Object.keys(filters)) {\r\n if (typeof filters[prop] === 'function') {\r\n continue;\r\n }\r\n const val = this.getGraphQLValue(filters[prop]);\r\n if (val === '{}') {\r\n continue;\r\n }\r\n this.head.push(`${prop}:${val}`);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * Outlines the properties you wish to be returned from the query.\r\n * @param properties representing each attribute you want Returned\r\n */\r\n find(...searches: any[]) { // THIS NEED TO BE A \"FUNCTION\" to scope 'arguments'\r\n if (!searches || !Array.isArray(searches) || searches.length === 0) {\r\n throw new TypeError(`find value can not be >>falsy<<`);\r\n }\r\n // if its a string.. it may have other values\r\n // else it sould be an Object or Array of maped values\r\n const searchKeys = (searches.length === 1 && Array.isArray(searches[0])) ? searches[0] : searches;\r\n this.body = this.parceFind(searchKeys);\r\n return this;\r\n }\r\n\r\n /**\r\n * set an alias for this result.\r\n * @param alias\r\n */\r\n setAlias(alias: string) {\r\n this.alias = alias;\r\n }\r\n\r\n /**\r\n * Return to the formatted query string\r\n * @return\r\n */\r\n toString() {\r\n if (this.body === undefined) {\r\n throw new ReferenceError(`return properties are not defined. use the 'find' function to defined them`);\r\n }\r\n\r\n return `${(this.alias) ? (this.alias + ':') : ''} ${this.queryFnName} ${(this.head.length > 0) ? '(' + this.head.join(',') + ')' : ''} { ${this.body} }`;\r\n }\r\n\r\n // --\r\n // PRIVATE FUNCTIONS\r\n // -----------------\r\n\r\n private parceFind(_levelA: any[]) {\r\n const propsA = _levelA.map((currentValue, index) => {\r\n const itemX = _levelA[index];\r\n\r\n if (itemX instanceof GraphqlQueryBuilder) {\r\n return itemX.toString();\r\n } else if (!Array.isArray(itemX) && typeof itemX === 'object') {\r\n const propsAA = Object.keys(itemX);\r\n if (1 !== propsAA.length) {\r\n throw new RangeError(`Alias objects should only have one value. was passed: ${JSON.stringify(itemX)}`);\r\n }\r\n const propS = propsAA[0];\r\n const item = itemX[propS];\r\n\r\n if (Array.isArray(item)) {\r\n return new GraphqlQueryBuilder(propS).find(item);\r\n }\r\n return `${propS} : ${item} `;\r\n } else if (typeof itemX === 'string') {\r\n return itemX;\r\n } else {\r\n throw new RangeError(`cannot handle Find value of ${itemX}`);\r\n }\r\n });\r\n\r\n return propsA.join(',');\r\n }\r\n\r\n private getGraphQLValue(value: any) {\r\n if (typeof value === 'string') {\r\n value = JSON.stringify(value);\r\n } else if (Array.isArray(value)) {\r\n value = value.map(item => {\r\n return this.getGraphQLValue(item);\r\n }).join();\r\n value = `[${value}]`;\r\n } else if (value instanceof Date) {\r\n value = JSON.stringify(value);\r\n } else if (value !== null && typeof value === 'object') {\r\n value = this.objectToString(value);\r\n }\r\n return value;\r\n }\r\n\r\n private objectToString(obj: any) {\r\n const sourceA = [];\r\n\r\n for (const prop of Object.keys(obj)) {\r\n if (typeof obj[prop] === 'function') {\r\n continue;\r\n }\r\n sourceA.push(`${prop}:${this.getGraphQLValue(obj[prop])}`);\r\n }\r\n return `{${sourceA.join()}}`;\r\n }\r\n}\r\n","import { mapOperatorType, mapOperatorByFieldType } from './utilities';\r\nimport {\r\n BackendService,\r\n Column,\r\n ColumnFilter,\r\n ColumnFilters,\r\n ColumnSort,\r\n CurrentFilter,\r\n CurrentPagination,\r\n CurrentSorter,\r\n FieldType,\r\n FilterChangedArgs,\r\n GraphqlCursorPaginationOption,\r\n GraphqlDatasetFilter,\r\n GraphqlFilteringOption,\r\n GraphqlPaginationOption,\r\n GraphqlServiceOption,\r\n GraphqlSortingOption,\r\n GridOption,\r\n MultiColumnSort,\r\n Pagination,\r\n PaginationChangedArgs,\r\n SortChangedArgs,\r\n SortDirection,\r\n SortDirectionString\r\n} from './../models/index';\r\nimport QueryBuilder from './graphqlQueryBuilder';\r\n\r\nconst DEFAULT_ITEMS_PER_PAGE = 25;\r\nconst DEFAULT_PAGE_SIZE = 20;\r\n\r\nexport class GraphqlService implements BackendService {\r\n private _currentFilters: ColumnFilters | CurrentFilter[] = [];\r\n private _currentPagination: CurrentPagination;\r\n private _currentSorters: CurrentSorter[] = [];\r\n private _columnDefinitions: Column[];\r\n private _grid: any;\r\n options: GraphqlServiceOption;\r\n pagination: Pagination | undefined;\r\n defaultPaginationOptions: GraphqlPaginationOption | GraphqlCursorPaginationOption = {\r\n first: DEFAULT_ITEMS_PER_PAGE,\r\n offset: 0\r\n };\r\n\r\n /** Getter for the Column Definitions */\r\n get columnDefinitions() {\r\n return this._columnDefinitions;\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n /** Initialization of the service, which acts as a constructor */\r\n init(serviceOptions?: GraphqlServiceOption, pagination?: Pagination, grid?: any): void {\r\n this._grid = grid;\r\n this.options = serviceOptions || {};\r\n this.pagination = pagination;\r\n\r\n if (grid && grid.getColumns) {\r\n this._columnDefinitions = (serviceOptions && serviceOptions.columnDefinitions) || grid.getColumns();\r\n }\r\n }\r\n\r\n /**\r\n * Build the GraphQL query, since the service include/exclude cursor, the output query will be different.\r\n * @param serviceOptions GraphqlServiceOption\r\n */\r\n buildQuery() {\r\n if (!this.options || !this.options.datasetName || (!this._columnDefinitions && !Array.isArray(this.options.columnDefinitions))) {\r\n throw new Error('GraphQL Service requires \"datasetName\" & \"columnDefinitions\" properties for it to work');\r\n }\r\n\r\n // get the column definitions and exclude some if they were tagged as excluded\r\n let columnDefinitions = this._columnDefinitions || this.options.columnDefinitions;\r\n columnDefinitions = columnDefinitions.filter((column: Column) => !column.excludeFromQuery);\r\n\r\n const queryQb = new QueryBuilder('query');\r\n const datasetQb = new QueryBuilder(this.options.datasetName);\r\n const dataQb = (this.options.isWithCursor) ? new QueryBuilder('edges') : new QueryBuilder('nodes');\r\n\r\n // get all the columnds Ids for the filters to work\r\n const columnIds: string[] = [];\r\n if (columnDefinitions && Array.isArray(columnDefinitions)) {\r\n for (const column of columnDefinitions) {\r\n columnIds.push(column.field);\r\n\r\n // if extra \"fields\" are passed, also push them to columnIds\r\n if (column.fields) {\r\n columnIds.push(...column.fields);\r\n }\r\n }\r\n }\r\n\r\n // Slickgrid also requires the \"id\" field to be part of DataView\r\n // add it to the GraphQL query if it wasn't already part of the list\r\n if (columnIds.indexOf('id') === -1) {\r\n columnIds.unshift('id');\r\n }\r\n\r\n const filters = this.buildFilterQuery(columnIds);\r\n\r\n if (this.options.isWithCursor) {\r\n // ...pageInfo { hasNextPage, endCursor }, edges { cursor, node { _filters_ } }\r\n const pageInfoQb = new QueryBuilder('pageInfo');\r\n pageInfoQb.find('hasNextPage', 'endCursor');\r\n dataQb.find(['cursor', { node: filters }]);\r\n datasetQb.find(['totalCount', pageInfoQb, dataQb]);\r\n } else {\r\n // ...nodes { _filters_ }\r\n dataQb.find(filters);\r\n datasetQb.find(['totalCount', dataQb]);\r\n }\r\n\r\n // add dataset filters, could be Pagination and SortingFilters and/or FieldFilters\r\n let datasetFilters: GraphqlDatasetFilter = {};\r\n\r\n // only add pagination if it's enabled in the grid options\r\n if (this._gridOptions.enablePagination !== false) {\r\n datasetFilters = {\r\n ...this.options.paginationOptions,\r\n first: ((this.options.paginationOptions && this.options.paginationOptions.first) ? this.options.paginationOptions.first : ((this.pagination && this.pagination.pageSize) ? this.pagination.pageSize : null)) || this.defaultPaginationOptions.first\r\n };\r\n\r\n if (!this.options.isWithCursor) {\r\n datasetFilters.offset = ((this.options.paginationOptions && this.options.paginationOptions.hasOwnProperty('offset')) ? +this.options.paginationOptions['offset'] : 0);\r\n }\r\n }\r\n\r\n if (this.options.sortingOptions && Array.isArray(this.options.sortingOptions) && this.options.sortingOptions.length > 0) {\r\n // orderBy: [{ field:x, direction: 'ASC' }]\r\n datasetFilters.orderBy = this.options.sortingOptions;\r\n }\r\n if (this.options.filteringOptions && Array.isArray(this.options.filteringOptions) && this.options.filteringOptions.length > 0) {\r\n // filterBy: [{ field: date, operator: '>', value: '2000-10-10' }]\r\n datasetFilters.filterBy = this.options.filteringOptions;\r\n }\r\n if (this.options.addLocaleIntoQuery) {\r\n // first: 20, ... locale: \"en-CA\"\r\n datasetFilters.locale = this._gridOptions && this._gridOptions.i18n && this._gridOptions.i18n.currentLang || 'en';\r\n }\r\n if (this.options.extraQueryArguments) {\r\n // first: 20, ... userId: 123\r\n for (const queryArgument of this.options.extraQueryArguments) {\r\n datasetFilters[queryArgument.field] = queryArgument.value;\r\n }\r\n }\r\n\r\n // query { users(first: 20, orderBy: [], filterBy: [])}\r\n datasetQb.filter(datasetFilters);\r\n queryQb.find(datasetQb);\r\n\r\n const enumSearchProperties = ['direction:', 'field:', 'operator:'];\r\n return this.trimDoubleQuotesOnEnumField(queryQb.toString(), enumSearchProperties, this.options.keepArgumentFieldDoubleQuotes || false);\r\n }\r\n\r\n /**\r\n * From an input array of strings, we want to build a GraphQL query string.\r\n * The process has to take the dot notation and parse it into a valid GraphQL query\r\n * Following this SO answer https://stackoverflow.com/a/47705476/1212166\r\n *\r\n * INPUT\r\n * ['firstName', 'lastName', 'billing.address.street', 'billing.address.zip']\r\n * OUTPUT\r\n * firstName, lastName, billing{address{street, zip}}\r\n * @param inputArray\r\n */\r\n buildFilterQuery(inputArray: string[]) {\r\n\r\n const set = (o: any = {}, a: any) => {\r\n const k = a.shift();\r\n o[k] = a.length ? set(o[k], a) : null;\r\n return o;\r\n };\r\n\r\n const output = inputArray.reduce((o: any, a: string) => set(o, a.split('.')), {});\r\n\r\n return JSON.stringify(output)\r\n .replace(/\\\"|\\:|null/g, '')\r\n .replace(/^\\{/, '')\r\n .replace(/\\}$/, '');\r\n }\r\n\r\n clearFilters() {\r\n this._currentFilters = [];\r\n this.updateOptions({ filteringOptions: [] });\r\n }\r\n\r\n clearSorters() {\r\n this._currentSorters = [];\r\n this.updateOptions({ sortingOptions: [] });\r\n }\r\n\r\n /**\r\n * Get an initialization of Pagination options\r\n * @return Pagination Options\r\n */\r\n getInitPaginationOptions(): GraphqlDatasetFilter {\r\n const paginationFirst = this.pagination ? this.pagination.pageSize : DEFAULT_ITEMS_PER_PAGE;\r\n return (this.options && this.options.isWithCursor) ? { first: paginationFirst } : { first: paginationFirst, offset: 0 };\r\n }\r\n\r\n /** Get the GraphQL dataset name */\r\n getDatasetName(): string {\r\n return this.options.datasetName || '';\r\n }\r\n\r\n /** Get the Filters that are currently used by the grid */\r\n getCurrentFilters(): ColumnFilters | CurrentFilter[] {\r\n return this._currentFilters;\r\n }\r\n\r\n /** Get the Pagination that is currently used by the grid */\r\n getCurrentPagination(): CurrentPagination {\r\n return this._currentPagination;\r\n }\r\n\r\n /** Get the Sorters that are currently used by the grid */\r\n getCurrentSorters(): CurrentSorter[] {\r\n return this._currentSorters;\r\n }\r\n\r\n /*\r\n * Reset the pagination options\r\n */\r\n resetPaginationOptions() {\r\n let paginationOptions: GraphqlPaginationOption | GraphqlCursorPaginationOption;\r\n\r\n if (this.options && this.options.isWithCursor) {\r\n // first, last, after, before\r\n paginationOptions = {\r\n after: '',\r\n before: undefined,\r\n last: undefined\r\n } as GraphqlCursorPaginationOption;\r\n } else {\r\n // first, last, offset\r\n paginationOptions = (this.options.paginationOptions || this.getInitPaginationOptions()) as GraphqlPaginationOption;\r\n (paginationOptions as GraphqlPaginationOption).offset = 0;\r\n }\r\n\r\n // save current pagination as Page 1 and page size as \"first\" set size\r\n this._currentPagination = {\r\n pageNumber: 1,\r\n pageSize: paginationOptions.first\r\n };\r\n\r\n this.updateOptions({ paginationOptions });\r\n }\r\n\r\n updateOptions(serviceOptions?: GraphqlServiceOption) {\r\n this.options = { ...this.options, ...serviceOptions };\r\n }\r\n\r\n /*\r\n * FILTERING\r\n */\r\n processOnFilterChanged(event: Event, args: FilterChangedArgs): string {\r\n const gridOptions: GridOption = this._gridOptions;\r\n const backendApi = gridOptions.backendServiceApi;\r\n\r\n if (backendApi === undefined) {\r\n throw new Error('Something went wrong in the GraphqlService, \"backendServiceApi\" is not initialized');\r\n }\r\n\r\n // keep current filters & always save it as an array (columnFilters can be an object when it is dealt by SlickGrid Filter)\r\n this._currentFilters = this.castFilterToColumnFilters(args.columnFilters);\r\n\r\n if (!args || !args.grid) {\r\n throw new Error('Something went wrong when trying create the GraphQL Backend Service, it seems that \"args\" is not populated correctly');\r\n }\r\n\r\n // loop through all columns to inspect filters & set the query\r\n this.updateFilters(args.columnFilters, false);\r\n\r\n this.resetPaginationOptions();\r\n return this.buildQuery();\r\n }\r\n\r\n /*\r\n * PAGINATION\r\n * With cursor, the query can have 4 arguments (first, after, last, before), for example:\r\n * users (first:20, after:\"YXJyYXljb25uZWN0aW9uOjM=\") {\r\n * totalCount\r\n * pageInfo {\r\n * hasNextPage\r\n * endCursor\r\n * }\r\n * edges {\r\n * cursor\r\n * node {\r\n * name\r\n * gender\r\n * }\r\n * }\r\n * }\r\n * Without cursor, the query can have 3 arguments (first, last, offset), for example:\r\n * users (first:20, offset: 10) {\r\n * totalCount\r\n * nodes {\r\n * name\r\n * gender\r\n * }\r\n * }\r\n */\r\n processOnPaginationChanged(event: Event, args: PaginationChangedArgs): string {\r\n const pageSize = +(args.pageSize || ((this.pagination) ? this.pagination.pageSize : DEFAULT_PAGE_SIZE));\r\n this.updatePagination(args.newPage, pageSize);\r\n\r\n // build the GraphQL query which we will use in the WebAPI callback\r\n return this.buildQuery();\r\n }\r\n\r\n /*\r\n * SORTING\r\n * we will use sorting as per a Facebook suggestion on a Github issue (with some small changes)\r\n * https://github.com/graphql/graphql-relay-js/issues/20#issuecomment-220494222\r\n *\r\n * users (first: 20, offset: 10, orderBy: [{field: lastName, direction: ASC}, {field: firstName, direction: DESC}]) {\r\n * totalCount\r\n * nodes {\r\n * name\r\n * gender\r\n * }\r\n * }\r\n */\r\n // @deprecated note, we should remove \"SortChangedArgs\" and only use: ColumnSort | MultiColumnSort\r\n processOnSortChanged(event: Event, args: SortChangedArgs | ColumnSort | MultiColumnSort): string {\r\n const sortColumns = (args.multiColumnSort) ? (args as MultiColumnSort).sortCols : new Array({ sortCol: (args as ColumnSort).sortCol, sortAsc: (args as ColumnSort).sortAsc });\r\n\r\n // loop through all columns to inspect sorters & set the query\r\n this.updateSorters(sortColumns);\r\n\r\n // build the GraphQL query which we will use in the WebAPI callback\r\n return this.buildQuery();\r\n }\r\n\r\n /**\r\n * loop through all columns to inspect filters & update backend service filteringOptions\r\n * @param columnFilters\r\n */\r\n updateFilters(columnFilters: ColumnFilters | CurrentFilter[], isUpdatedByPreset: boolean) {\r\n const searchByArray: GraphqlFilteringOption[] = [];\r\n let searchValue: string | string[];\r\n\r\n // on filter preset load, we need to keep current filters\r\n if (isUpdatedByPreset) {\r\n this._currentFilters = this.castFilterToColumnFilters(columnFilters);\r\n }\r\n\r\n for (const columnId in columnFilters) {\r\n if (columnFilters.hasOwnProperty(columnId)) {\r\n const columnFilter = columnFilters[columnId];\r\n\r\n // if user defined some \"presets\", then we need to find the filters from the column definitions instead\r\n let columnDef: Column | undefined;\r\n if (isUpdatedByPreset && Array.isArray(this._columnDefinitions)) {\r\n columnDef = this._columnDefinitions.find((column: Column) => column.id === columnFilter.columnId);\r\n } else {\r\n columnDef = columnFilter.columnDef;\r\n }\r\n if (!columnDef) {\r\n throw new Error('[GraphQL Service]: Something went wrong in trying to get the column definition of the specified filter (or preset filters). Did you make a typo on the filter columnId?');\r\n }\r\n\r\n const fieldName = columnDef.queryFieldFilter || columnDef.queryField || columnDef.field || columnDef.name || '';\r\n const searchTerms = columnFilter && columnFilter.searchTerms || [];\r\n let fieldSearchValue = (Array.isArray(searchTerms) && searchTerms.length === 1) ? searchTerms[0] : '';\r\n if (typeof fieldSearchValue === 'undefined') {\r\n fieldSearchValue = '';\r\n }\r\n\r\n if (!fieldName) {\r\n throw new Error(`GraphQL filter could not find the field name to query the search, your column definition must include a valid \"field\" or \"name\" (optionally you can also use the \"queryfield\" or \"queryFieldFilter\").`);\r\n }\r\n\r\n fieldSearchValue = '' + fieldSearchValue; // make sure it's a string\r\n const matches = fieldSearchValue.match(/^([<>!=\\*]{0,2})(.*[^<>!=\\*])([\\*]?)$/); // group 1: Operator, 2: searchValue, 3: last char is '*' (meaning starts with, ex.: abc*)\r\n let operator = columnFilter.operator || ((matches) ? matches[1] : '');\r\n searchValue = (!!matches) ? matches[2] : '';\r\n const lastValueChar = (!!matches) ? matches[3] : (operator === '*z' ? '*' : '');\r\n\r\n // no need to query if search value is empty\r\n if (fieldName && searchValue === '' && searchTerms.length === 0) {\r\n continue;\r\n }\r\n\r\n // when having more than 1 search term (we need to create a CSV string for GraphQL \"IN\" or \"NOT IN\" filter search)\r\n if (searchTerms && searchTerms.length > 1) {\r\n searchValue = searchTerms.join(',');\r\n } else if (typeof searchValue === 'string') {\r\n // escaping the search value\r\n searchValue = searchValue.replace(`'`, `''`); // escape single quotes by doubling them\r\n if (operator === '*' || operator === 'a*' || operator === '*z' || lastValueChar === '*') {\r\n operator = (operator === '*' || operator === '*z') ? 'endsWith' : 'startsWith';\r\n }\r\n }\r\n\r\n // if we didn't find an Operator but we have a Column Operator inside the Filter (DOM Element), we should use its default Operator\r\n // multipleSelect is \"IN\", while singleSelect is \"EQ\", else don't map any operator\r\n if (!operator && columnDef.filter) {\r\n operator = columnDef.filter.operator;\r\n }\r\n\r\n // if we still don't have an operator find the proper Operator to use by it's field type\r\n if (!operator) {\r\n operator = mapOperatorByFieldType(columnDef.type || FieldType.string);\r\n }\r\n\r\n searchByArray.push({\r\n field: fieldName,\r\n operator: mapOperatorType(operator),\r\n value: searchValue\r\n });\r\n }\r\n }\r\n\r\n // update the service options with filters for the buildQuery() to work later\r\n this.updateOptions({ filteringOptions: searchByArray });\r\n }\r\n\r\n /**\r\n * Update the pagination component with it's new page number and size\r\n * @param newPage\r\n * @param pageSize\r\n */\r\n updatePagination(newPage: number, pageSize: number) {\r\n this._currentPagination = {\r\n pageNumber: newPage,\r\n pageSize\r\n };\r\n\r\n let paginationOptions;\r\n if (this.options.isWithCursor) {\r\n paginationOptions = {\r\n first: pageSize\r\n };\r\n } else {\r\n paginationOptions = {\r\n first: pageSize,\r\n offset: (newPage - 1) * pageSize\r\n };\r\n }\r\n\r\n this.updateOptions({ paginationOptions });\r\n }\r\n\r\n /**\r\n * loop through all columns to inspect sorters & update backend service sortingOptions\r\n * @param columnFilters\r\n */\r\n updateSorters(sortColumns?: ColumnSort[], presetSorters?: CurrentSorter[]) {\r\n let currentSorters: CurrentSorter[] = [];\r\n const graphqlSorters: GraphqlSortingOption[] = [];\r\n\r\n if (!sortColumns && presetSorters) {\r\n // make the presets the current sorters, also make sure that all direction are in uppercase for GraphQL\r\n currentSorters = presetSorters;\r\n currentSorters.forEach((sorter) => sorter.direction = sorter.direction.toUpperCase() as SortDirectionString);\r\n\r\n // display the correct sorting icons on the UI, for that it requires (columnId, sortAsc) properties\r\n const tmpSorterArray = currentSorters.map((sorter) => {\r\n const columnDef = this._columnDefinitions.find((column: Column) => column.id === sorter.columnId);\r\n\r\n graphqlSorters.push({\r\n field: columnDef ? ((columnDef.queryFieldSorter || columnDef.queryField || columnDef.field) + '') : (sorter.columnId + ''),\r\n direction: sorter.direction\r\n });\r\n\r\n // return only the column(s) found in the Column Definitions ELSE null\r\n if (columnDef) {\r\n return {\r\n columnId: sorter.columnId,\r\n sortAsc: sorter.direction.toUpperCase() === SortDirection.ASC\r\n };\r\n }\r\n return null;\r\n });\r\n\r\n // set the sort icons, but also make sure to filter out null values (that happens when columnDef is not found)\r\n if (Array.isArray(tmpSorterArray)) {\r\n this._grid.setSortColumns(tmpSorterArray.filter((sorter) => sorter));\r\n }\r\n } else if (sortColumns && !presetSorters) {\r\n // build the orderBy array, it could be multisort, example\r\n // orderBy:[{field: lastName, direction: ASC}, {field: firstName, direction: DESC}]\r\n if (Array.isArray(sortColumns) && sortColumns.length > 0) {\r\n for (const column of sortColumns) {\r\n if (column && column.sortCol) {\r\n currentSorters.push({\r\n columnId: column.sortCol.id + '',\r\n direction: column.sortAsc ? SortDirection.ASC : SortDirection.DESC\r\n });\r\n\r\n const fieldName = (column.sortCol.queryFieldSorter || column.sortCol.queryField || column.sortCol.field || '') + '';\r\n if (fieldName) {\r\n graphqlSorters.push({\r\n field: fieldName,\r\n direction: column.sortAsc ? SortDirection.ASC : SortDirection.DESC\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // keep current Sorters and update the service options with the new sorting\r\n this._currentSorters = currentSorters;\r\n this.updateOptions({ sortingOptions: graphqlSorters });\r\n }\r\n\r\n /**\r\n * A function which takes an input string and removes double quotes only\r\n * on certain fields are identified as GraphQL enums (except fields with dot notation)\r\n * For example let say we identified (\"direction:\", \"sort\") as word which are GraphQL enum fields\r\n * then the result will be:\r\n * FROM\r\n * query { users (orderBy:[{field:\"firstName\", direction:\"ASC\"} }]) }\r\n * TO\r\n * query { users (orderBy:[{field: firstName, direction: ASC}})}\r\n *\r\n * EXCEPTIONS (fields with dot notation \".\" which are inside a \"field:\")\r\n * these fields will keep double quotes while everything else will be stripped of double quotes\r\n * query { users (orderBy:[{field:\"billing.street.name\", direction: \"ASC\"} }\r\n * TO\r\n * query { users (orderBy:[{field:\"billing.street.name\", direction: ASC}}\r\n * @param inputStr input string\r\n * @param enumSearchWords array of enum words to filter\r\n * @returns outputStr output string\r\n */\r\n trimDoubleQuotesOnEnumField(inputStr: string, enumSearchWords: string[], keepArgumentFieldDoubleQuotes: boolean) {\r\n const patternWordInQuotes = `\\s?((field:\\s*)?\".*?\")`;\r\n let patternRegex = enumSearchWords.join(patternWordInQuotes + '|');\r\n patternRegex += patternWordInQuotes; // the last one should also have the pattern but without the pipe \"|\"\r\n // example with (field: & direction:): /field:s?(\".*?\")|direction:s?(\".*?\")/\r\n const reg = new RegExp(patternRegex, 'g');\r\n\r\n return inputStr.replace(reg, (group1, group2, group3) => {\r\n // remove double quotes except when the string starts with a \"field:\"\r\n let removeDoubleQuotes = true;\r\n if (group1.startsWith('field:') && keepArgumentFieldDoubleQuotes) {\r\n removeDoubleQuotes = false;\r\n }\r\n const rep = removeDoubleQuotes ? group1.replace(/\"/g, '') : group1;\r\n return rep;\r\n });\r\n }\r\n\r\n //\r\n // private functions\r\n // -------------------\r\n /**\r\n * Cast provided filters (could be in multiple formats) into an array of ColumnFilter\r\n * @param columnFilters\r\n */\r\n private castFilterToColumnFilters(columnFilters: ColumnFilters | CurrentFilter[]): CurrentFilter[] {\r\n\r\n // keep current filters & always save it as an array (columnFilters can be an object when it is dealt by SlickGrid Filter)\r\n const filtersArray: ColumnFilter[] = (typeof columnFilters === 'object') ? Object.keys(columnFilters).map(key => columnFilters[key]) : columnFilters;\r\n\r\n if (!Array.isArray(filtersArray)) {\r\n return [];\r\n }\r\n\r\n return filtersArray.map((filter) => {\r\n const tmpFilter: CurrentFilter = { columnId: filter.columnId || '' };\r\n if (filter.operator) {\r\n tmpFilter.operator = filter.operator;\r\n }\r\n if (Array.isArray(filter.searchTerms)) {\r\n tmpFilter.searchTerms = filter.searchTerms;\r\n }\r\n return tmpFilter;\r\n });\r\n }\r\n}\r\n","import { CaseType, OdataOption } from '../models/index';\r\nimport { titleCase } from './utilities';\r\n\r\nexport class OdataQueryBuilderService {\r\n _columnFilters: any;\r\n _defaultSortBy: string;\r\n _filterCount: number;\r\n _odataOptions: OdataOption;\r\n\r\n constructor() {\r\n this._odataOptions = {\r\n filterQueue: [],\r\n orderBy: ''\r\n };\r\n this._defaultSortBy = '';\r\n this._columnFilters = {};\r\n }\r\n\r\n /*\r\n * Build the OData query string from all the options provided\r\n * @return string OData query\r\n */\r\n buildQuery(): string {\r\n if (!this._odataOptions) {\r\n throw new Error('Odata Service requires certain options like \"top\" for it to work');\r\n }\r\n this._odataOptions.filterQueue = [];\r\n const queryTmpArray = [];\r\n\r\n if (this._odataOptions.top) {\r\n queryTmpArray.push(`$top=${this._odataOptions.top}`);\r\n }\r\n if (this._odataOptions.skip) {\r\n queryTmpArray.push(`$skip=${this._odataOptions.skip}`);\r\n }\r\n if (this._odataOptions.orderBy) {\r\n let argument = '';\r\n if (Array.isArray(this._odataOptions.orderBy)) {\r\n argument = this._odataOptions.orderBy.join(','); // csv, that will form a query, for example: $orderby=RoleName asc, Id desc\r\n } else {\r\n argument = this._odataOptions.orderBy;\r\n }\r\n queryTmpArray.push(`$orderby=${argument}`);\r\n }\r\n if (this._odataOptions.filterBy || this._odataOptions.filter) {\r\n const filterBy = this._odataOptions.filter || this._odataOptions.filterBy;\r\n if (filterBy) {\r\n this._filterCount = 1;\r\n this._odataOptions.filterQueue = [];\r\n let filterStr = filterBy;\r\n if (Array.isArray(filterBy)) {\r\n this._filterCount = filterBy.length;\r\n filterStr = filterBy.join(` ${this._odataOptions.filterBySeparator || 'and'} `);\r\n }\r\n\r\n if (typeof filterStr === 'string') {\r\n if (!(filterStr[0] === '(' && filterStr.slice(-1) === ')')) {\r\n this.addToFilterQueueWhenNotExists(`(${filterStr})`);\r\n } else {\r\n this.addToFilterQueueWhenNotExists(filterStr);\r\n }\r\n }\r\n }\r\n }\r\n if (this._odataOptions.filterQueue.length > 0) {\r\n const query = this._odataOptions.filterQueue.join(` ${this._odataOptions.filterBySeparator || 'and'} `);\r\n this._odataOptions.filter = query; // overwrite with\r\n queryTmpArray.push(`$filter=${query}`);\r\n }\r\n\r\n // join all the odata functions by a '&'\r\n return queryTmpArray.join('&');\r\n }\r\n\r\n getFilterCount(): number {\r\n return this._filterCount;\r\n }\r\n\r\n get columnFilters(): any[] {\r\n return this._columnFilters;\r\n }\r\n\r\n get options(): OdataOption {\r\n return this._odataOptions;\r\n }\r\n\r\n set options(options: OdataOption) {\r\n this._odataOptions = options;\r\n }\r\n\r\n removeColumnFilter(fieldName: string) {\r\n if (this._columnFilters && this._columnFilters.hasOwnProperty(fieldName)) {\r\n delete this._columnFilters[fieldName];\r\n }\r\n }\r\n\r\n saveColumnFilter(fieldName: string, value: any, searchTerms?: any[]) {\r\n this._columnFilters[fieldName] = {\r\n search: searchTerms,\r\n value\r\n };\r\n }\r\n\r\n /**\r\n * Change any OData options that will be used to build the query\r\n * @param object options\r\n */\r\n updateOptions(options: OdataOption) {\r\n for (const property of Object.keys(options)) {\r\n if (options.hasOwnProperty(property)) {\r\n this._odataOptions[property] = options[property]; // replace of the property\r\n }\r\n\r\n // we need to keep the defaultSortBy for references whenever the user removes his Sorting\r\n // then we would revert to the defaultSortBy and the only way is to keep a hard copy here\r\n if (property === 'orderBy' || property === 'sortBy') {\r\n let sortBy = options[property];\r\n\r\n // make sure first char of each orderBy field is capitalize\r\n if (this._odataOptions.caseType === CaseType.pascalCase) {\r\n if (Array.isArray(sortBy)) {\r\n sortBy.forEach((field, index, inputArray) => {\r\n inputArray[index] = titleCase(field);\r\n });\r\n } else {\r\n sortBy = titleCase(options[property]);\r\n }\r\n }\r\n this._odataOptions.orderBy = sortBy;\r\n this._defaultSortBy = sortBy;\r\n }\r\n }\r\n }\r\n\r\n //\r\n // private functions\r\n // -------------------\r\n\r\n private addToFilterQueueWhenNotExists(filterStr: string) {\r\n if (this._odataOptions.filterQueue && this._odataOptions.filterQueue.indexOf(filterStr) === -1) {\r\n this._odataOptions.filterQueue.push(filterStr);\r\n }\r\n }\r\n}\r\n","import { mapOperatorByFieldType, parseUtcDate, titleCase } from './utilities';\r\nimport { Injectable } from '@angular/core';\r\nimport {\r\n BackendService,\r\n CaseType,\r\n Column,\r\n ColumnFilter,\r\n ColumnFilters,\r\n ColumnSort,\r\n CurrentFilter,\r\n CurrentPagination,\r\n CurrentSorter,\r\n FilterChangedArgs,\r\n FieldType,\r\n GridOption,\r\n OdataOption,\r\n Pagination,\r\n PaginationChangedArgs,\r\n SortChangedArgs,\r\n SortDirection,\r\n SortDirectionString,\r\n OdataSortingOption,\r\n OperatorType\r\n} from './../models/index';\r\nimport { OdataQueryBuilderService } from './odataQueryBuilder.service';\r\n\r\nconst DEFAULT_ITEMS_PER_PAGE = 25;\r\nconst DEFAULT_PAGE_SIZE = 20;\r\n\r\n@Injectable()\r\nexport class GridOdataService implements BackendService {\r\n private _currentFilters: CurrentFilter[] = [];\r\n private _currentPagination: CurrentPagination;\r\n private _currentSorters: CurrentSorter[] = [];\r\n private _columnDefinitions: Column[];\r\n private _grid: any;\r\n private _odataService: OdataQueryBuilderService;\r\n options: OdataOption;\r\n pagination: Pagination | undefined;\r\n defaultOptions: OdataOption = {\r\n top: DEFAULT_ITEMS_PER_PAGE,\r\n orderBy: '',\r\n caseType: CaseType.pascalCase\r\n };\r\n\r\n /** Getter for the Column Definitions */\r\n get columnDefinitions() {\r\n return this._columnDefinitions;\r\n }\r\n\r\n /** Getter for the Odata Service */\r\n get odataService() {\r\n return this._odataService;\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n constructor() {\r\n this._odataService = new OdataQueryBuilderService();\r\n }\r\n\r\n init(serviceOptions: OdataOption, pagination?: Pagination, grid?: any): void {\r\n this._grid = grid;\r\n const mergedOptions = { ...this.defaultOptions, ...serviceOptions };\r\n if (pagination && pagination.pageSize) {\r\n mergedOptions.top = pagination.pageSize;\r\n }\r\n this._odataService.options = { ...mergedOptions, top: mergedOptions.top || this.defaultOptions.top };\r\n this.options = this._odataService.options;\r\n this.pagination = pagination;\r\n\r\n // save current pagination as Page 1 and page size as \"top\"\r\n this._currentPagination = {\r\n pageNumber: 1,\r\n pageSize: this._odataService.options.top || this.defaultOptions.top || DEFAULT_PAGE_SIZE\r\n };\r\n\r\n if (grid && grid.getColumns) {\r\n this._columnDefinitions = serviceOptions && serviceOptions.columnDefinitions || grid.getColumns();\r\n this._columnDefinitions = this._columnDefinitions.filter((column: Column) => !column.excludeFromQuery);\r\n }\r\n }\r\n\r\n buildQuery(): string {\r\n return this._odataService.buildQuery();\r\n }\r\n\r\n clearFilters() {\r\n this._currentFilters = [];\r\n this.updateFilters([]);\r\n }\r\n\r\n clearSorters() {\r\n this._currentSorters = [];\r\n this.updateSorters([]);\r\n }\r\n\r\n updateOptions(serviceOptions?: OdataOption) {\r\n this.options = { ...this.options, ...serviceOptions };\r\n this._odataService.options = this.options;\r\n }\r\n\r\n removeColumnFilter(fieldName: string): void {\r\n this._odataService.removeColumnFilter(fieldName);\r\n }\r\n\r\n /** Get the Filters that are currently used by the grid */\r\n getCurrentFilters(): CurrentFilter[] {\r\n return this._currentFilters;\r\n }\r\n\r\n /** Get the Pagination that is currently used by the grid */\r\n getCurrentPagination(): CurrentPagination {\r\n return this._currentPagination;\r\n }\r\n\r\n /** Get the Sorters that are currently used by the grid */\r\n getCurrentSorters(): CurrentSorter[] {\r\n return this._currentSorters;\r\n }\r\n\r\n /**\r\n * Mapper for mathematical operators (ex.: <= is \"le\", > is \"gt\")\r\n * @param string operator\r\n * @returns string map\r\n */\r\n mapOdataOperator(operator: string) {\r\n let map = '';\r\n switch (operator) {\r\n case '<':\r\n map = 'lt';\r\n break;\r\n case '<=':\r\n map = 'le';\r\n break;\r\n case '>':\r\n map = 'gt';\r\n break;\r\n case '>=':\r\n map = 'ge';\r\n break;\r\n case '<>':\r\n case '!=':\r\n map = 'ne';\r\n break;\r\n case '=':\r\n case '==':\r\n default:\r\n map = 'eq';\r\n break;\r\n }\r\n\r\n return map;\r\n }\r\n\r\n /*\r\n * Reset the pagination options\r\n */\r\n resetPaginationOptions() {\r\n this._odataService.updateOptions({\r\n skip: 0\r\n });\r\n }\r\n\r\n saveColumnFilter(fieldName: string, value: string, terms?: any[]) {\r\n this._odataService.saveColumnFilter(fieldName, value, terms);\r\n }\r\n\r\n /*\r\n * FILTERING\r\n */\r\n processOnFilterChanged(event: Event, args: FilterChangedArgs): string {\r\n const gridOptions: GridOption = this._gridOptions;\r\n const backendApi = gridOptions.backendServiceApi;\r\n\r\n if (backendApi === undefined) {\r\n throw new Error('Something went wrong in the GridOdataService, \"backendServiceApi\" is not initialized');\r\n }\r\n\r\n // keep current filters & always save it as an array (columnFilters can be an object when it is dealt by SlickGrid Filter)\r\n this._currentFilters = this.castFilterToColumnFilters(args.columnFilters);\r\n\r\n if (!args || !args.grid) {\r\n throw new Error('Something went wrong when trying create the GridOdataService, it seems that \"args\" is not populated correctly');\r\n }\r\n\r\n // loop through all columns to inspect filters & set the query\r\n this.updateFilters(args.columnFilters);\r\n\r\n this.resetPaginationOptions();\r\n return this._odataService.buildQuery();\r\n }\r\n\r\n /*\r\n * PAGINATION\r\n */\r\n processOnPaginationChanged(event: Event, args: PaginationChangedArgs) {\r\n const pageSize = +(args.pageSize || ((this.pagination) ? this.pagination.pageSize : DEFAULT_PAGE_SIZE));\r\n this.updatePagination(args.newPage, pageSize);\r\n\r\n // build the OData query which we will use in the WebAPI callback\r\n return this._odataService.buildQuery();\r\n }\r\n\r\n /*\r\n * SORTING\r\n */\r\n processOnSortChanged(event: Event, args: SortChangedArgs) {\r\n const sortColumns = (args.multiColumnSort) ? args.sortCols : new Array({ sortCol: args.sortCol, sortAsc: args.sortAsc });\r\n\r\n // loop through all columns to inspect sorters & set the query\r\n this.updateSorters(sortColumns);\r\n\r\n // build the OData query which we will use in the WebAPI callback\r\n return this._odataService.buildQuery();\r\n }\r\n\r\n /**\r\n * loop through all columns to inspect filters & update backend service filters\r\n * @param columnFilters\r\n */\r\n updateFilters(columnFilters: ColumnFilters | CurrentFilter[], isUpdatedByPreset?: boolean) {\r\n let searchBy = '';\r\n const searchByArray: string[] = [];\r\n\r\n // on filter preset load, we need to keep current filters\r\n if (isUpdatedByPreset) {\r\n this._currentFilters = this.castFilterToColumnFilters(columnFilters);\r\n }\r\n\r\n // loop through all columns to inspect filters\r\n for (const columnId in columnFilters) {\r\n if (columnFilters.hasOwnProperty(columnId)) {\r\n const columnFilter = columnFilters[columnId];\r\n\r\n // if user defined some \"presets\", then we need to find the filters from the column definitions instead\r\n let columnDef: Column | undefined;\r\n if (isUpdatedByPreset && Array.isArray(this._columnDefinitions)) {\r\n columnDef = this._columnDefinitions.find((column: Column) => {\r\n return column.id === columnFilter.columnId;\r\n });\r\n } else {\r\n columnDef = columnFilter.columnDef;\r\n }\r\n if (!columnDef) {\r\n throw new Error('[GridOData Service]: Something went wrong in trying to get the column definition of the specified filter (or preset filters). Did you make a typo on the filter columnId?');\r\n }\r\n\r\n let fieldName = columnDef.queryFieldFilter || columnDef.queryField || columnDef.field || columnDef.name || '';\r\n const fieldType = columnDef.type || FieldType.string;\r\n const searchTerms = (columnFilter ? columnFilter.searchTerms : null) || [];\r\n let fieldSearchValue = (Array.isArray(searchTerms) && searchTerms.length === 1) ? searchTerms[0] : '';\r\n if (typeof fieldSearchValue === 'undefined') {\r\n fieldSearchValue = '';\r\n }\r\n\r\n if (!fieldName) {\r\n throw new Error(`GridOData filter could not find the field name to query the search, your column definition must include a valid \"field\" or \"name\" (optionally you can also use the \"queryfield\" or \"queryFieldFilter\").`);\r\n }\r\n\r\n fieldSearchValue = '' + fieldSearchValue; // make sure it's a string\r\n const matches = fieldSearchValue.match(/^([<>!=\\*]{0,2})(.*[^<>!=\\*])([\\*]?)$/); // group 1: Operator, 2: searchValue, 3: last char is '*' (meaning starts with, ex.: abc*)\r\n let operator = columnFilter.operator || ((matches) ? matches[1] : '');\r\n let searchValue = (!!matches) ? matches[2] : '';\r\n const lastValueChar = (!!matches) ? matches[3] : (operator === '*z' ? '*' : '');\r\n const bypassOdataQuery = columnFilter.bypassBackendQuery || false;\r\n\r\n // no need to query if search value is empty\r\n if (fieldName && searchValue === '' && searchTerms.length <= 1) {\r\n this.removeColumnFilter(fieldName);\r\n continue;\r\n }\r\n\r\n // escaping the search value\r\n searchValue = searchValue.replace(`'`, `''`); // escape single quotes by doubling them\r\n searchValue = encodeURIComponent(searchValue); // encode URI of the final search value\r\n\r\n // if we didn't find an Operator but we have a Column Operator inside the Filter (DOM Element), we should use its default Operator\r\n // multipleSelect is \"IN\", while singleSelect is \"EQ\", else don't map any operator\r\n if (!operator && columnDef.filter) {\r\n operator = columnDef.filter.operator;\r\n }\r\n\r\n // if we still don't have an operator find the proper Operator to use by it's field type\r\n if (!operator) {\r\n operator = mapOperatorByFieldType(columnDef.type || FieldType.string);\r\n }\r\n\r\n // extra query arguments\r\n if (bypassOdataQuery) {\r\n // push to our temp array and also trim white spaces\r\n if (fieldName) {\r\n this.saveColumnFilter(fieldName, fieldSearchValue, searchTerms);\r\n }\r\n } else {\r\n searchBy = '';\r\n\r\n // titleCase the fieldName so that it matches the WebApi names\r\n if (this._odataService.options.caseType === CaseType.pascalCase) {\r\n fieldName = titleCase(fieldName || '');\r\n }\r\n\r\n // when having more than 1 search term (then check if we have a \"IN\" or \"NOT IN\" filter search)\r\n if (searchTerms && searchTerms.length > 1) {\r\n const tmpSearchTerms = [];\r\n\r\n if (operator === 'IN') {\r\n // example:: (Stage eq \"Expired\" or Stage eq \"Renewal\")\r\n for (let j = 0, lnj = searchTerms.length; j < lnj; j++) {\r\n tmpSearchTerms.push(`${fieldName} eq '${searchTerms[j]}'`);\r\n }\r\n searchBy = tmpSearchTerms.join(' or ');\r\n if (!(typeof searchBy === 'string' && searchBy[0] === '(' && searchBy.slice(-1) === ')')) {\r\n searchBy = `(${searchBy})`;\r\n }\r\n } else if (operator === 'NIN' || operator === 'NOTIN' || operator === 'NOT IN' || operator === 'NOT_IN') {\r\n // example:: (Stage ne \"Expired\" and Stage ne \"Renewal\")\r\n for (let k = 0, lnk = searchTerms.length; k < lnk; k++) {\r\n tmpSearchTerms.push(`${fieldName} ne '${searchTerms[k]}'`);\r\n }\r\n searchBy = tmpSearchTerms.join(' and ');\r\n if (!(typeof searchBy === 'string' && searchBy[0] === '(' && searchBy.slice(-1) === ')')) {\r\n searchBy = `(${searchBy})`;\r\n }\r\n }\r\n } else if (operator === '*' || operator === 'a*' || operator === '*z' || lastValueChar === '*') {\r\n // first/last character is a '*' will be a startsWith or endsWith\r\n searchBy = (operator === '*' || operator === '*z')\r\n ? `endswith(${fieldName}, '${searchValue}')`\r\n : `startswith(${fieldName}, '${searchValue}')`;\r\n } else if (fieldType === FieldType.date) {\r\n // date field needs to be UTC and within DateTime function\r\n const dateFormatted = parseUtcDate(searchValue, true);\r\n if (dateFormatted) {\r\n searchBy = `${fieldName} ${this.mapOdataOperator(operator)} DateTime'${dateFormatted}'`;\r\n }\r\n } else if (fieldType === FieldType.string) {\r\n // string field needs to be in single quotes\r\n if (operator === '' || operator === OperatorType.contains || operator === OperatorType.notContains) {\r\n searchBy = `substringof('${searchValue}', ${fieldName})`;\r\n if (operator === OperatorType.notContains) {\r\n searchBy = `not ${searchBy}`;\r\n }\r\n } else {\r\n // searchBy = `substringof('${searchValue}', ${fieldNameCased}) ${this.mapOdataOperator(operator)} true`;\r\n searchBy = `${fieldName} ${this.mapOdataOperator(operator)} '${searchValue}'`;\r\n }\r\n } else {\r\n // any other field type (or undefined type)\r\n searchValue = (fieldType === FieldType.number || fieldType === FieldType.boolean) ? searchValue : `'${searchValue}'`;\r\n searchBy = `${fieldName} ${this.mapOdataOperator(operator)} ${searchValue}`;\r\n }\r\n\r\n // push to our temp array and also trim white spaces\r\n if (searchBy !== '') {\r\n searchByArray.push(searchBy.trim());\r\n this.saveColumnFilter(fieldName || '', fieldSearchValue, searchTerms);\r\n }\r\n }\r\n }\r\n }\r\n\r\n // update the service options with filters for the buildQuery() to work later\r\n this._odataService.updateOptions({\r\n filter: (searchByArray.length > 0) ? searchByArray.join(' and ') : '',\r\n skip: undefined\r\n });\r\n }\r\n\r\n /**\r\n * Update the pagination component with it's new page number and size\r\n * @param newPage\r\n * @param pageSize\r\n */\r\n updatePagination(newPage: number, pageSize: number) {\r\n this._currentPagination = {\r\n pageNumber: newPage,\r\n pageSize\r\n };\r\n\r\n this._odataService.updateOptions({\r\n top: pageSize,\r\n skip: (newPage - 1) * pageSize\r\n });\r\n }\r\n\r\n /**\r\n * loop through all columns to inspect sorters & update backend service orderBy\r\n * @param columnFilters\r\n */\r\n updateSorters(sortColumns?: ColumnSort[], presetSorters?: CurrentSorter[]) {\r\n let currentSorters: CurrentSorter[] = [];\r\n const odataSorters: OdataSortingOption[] = [];\r\n\r\n if (!sortColumns && presetSorters) {\r\n // make the presets the current sorters, also make sure that all direction are in lowercase for OData\r\n currentSorters = presetSorters;\r\n currentSorters.forEach((sorter) => sorter.direction = sorter.direction.toLowerCase() as SortDirectionString);\r\n\r\n // display the correct sorting icons on the UI, for that it requires (columnId, sortAsc) properties\r\n const tmpSorterArray = currentSorters.map((sorter) => {\r\n const columnDef = this._columnDefinitions.find((column: Column) => column.id === sorter.columnId);\r\n\r\n odataSorters.push({\r\n field: columnDef ? ((columnDef.queryFieldSorter || columnDef.queryField || columnDef.field) + '') : (sorter.columnId + ''),\r\n direction: sorter.direction\r\n });\r\n\r\n // return only the column(s) found in the Column Definitions ELSE null\r\n if (columnDef) {\r\n return {\r\n columnId: sorter.columnId,\r\n sortAsc: sorter.direction.toUpperCase() === SortDirection.ASC\r\n };\r\n }\r\n return null;\r\n });\r\n\r\n // set the sort icons, but also make sure to filter out null values (that happens when columnDef is not found)\r\n if (Array.isArray(tmpSorterArray)) {\r\n this._grid.setSortColumns(tmpSorterArray);\r\n }\r\n } else if (sortColumns && !presetSorters) {\r\n // build the SortBy string, it could be multisort, example: customerNo asc, purchaserName desc\r\n if (sortColumns && sortColumns.length === 0) {\r\n // TODO fix this line\r\n // currentSorters = new Array(this.defaultOptions.orderBy); // when empty, use the default sort\r\n } else {\r\n if (sortColumns) {\r\n for (const columnDef of sortColumns) {\r\n if (columnDef.sortCol) {\r\n let fieldName = (columnDef.sortCol.queryFieldSorter || columnDef.sortCol.queryField || columnDef.sortCol.field) + '';\r\n let columnFieldName = (columnDef.sortCol.field || columnDef.sortCol.id) + '';\r\n let queryField = (columnDef.sortCol.queryFieldSorter || columnDef.sortCol.queryField || columnDef.sortCol.field || '') + '';\r\n if (this._odataService.options.caseType === CaseType.pascalCase) {\r\n fieldName = titleCase(fieldName);\r\n columnFieldName = titleCase(columnFieldName);\r\n queryField = titleCase(queryField);\r\n }\r\n\r\n if (columnFieldName !== '') {\r\n currentSorters.push({\r\n columnId: columnFieldName,\r\n direction: columnDef.sortAsc ? 'asc' : 'desc'\r\n });\r\n }\r\n\r\n if (queryField !== '') {\r\n odataSorters.push({\r\n field: queryField,\r\n direction: columnDef.sortAsc ? SortDirection.ASC : SortDirection.DESC\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // transform the sortby array into a CSV string for OData\r\n currentSorters = currentSorters || [] as CurrentSorter[];\r\n const csvString = odataSorters.map((sorter) => {\r\n if (sorter && sorter.field) {\r\n const sortField = (this._odataService.options.caseType === CaseType.pascalCase) ? titleCase(sorter.field) : sorter.field;\r\n return `${sortField} ${sorter && sorter.direction && sorter.direction.toLowerCase() || ''}`;\r\n }\r\n return '';\r\n }).join(',');\r\n\r\n this._odataService.updateOptions({\r\n orderBy: csvString\r\n });\r\n\r\n // keep current Sorters and update the service options with the new sorting\r\n this._currentSorters = currentSorters;\r\n\r\n // build the OData query which we will use in the WebAPI callback\r\n return this._odataService.buildQuery();\r\n }\r\n\r\n //\r\n // private functions\r\n // -------------------\r\n /**\r\n * Cast provided filters (could be in multiple format) into an array of ColumnFilter\r\n * @param columnFilters\r\n */\r\n private castFilterToColumnFilters(columnFilters: ColumnFilters | CurrentFilter[]): CurrentFilter[] {\r\n // keep current filters & always save it as an array (columnFilters can be an object when it is dealt by SlickGrid Filter)\r\n const filtersArray: ColumnFilter[] = (typeof columnFilters === 'object') ? Object.keys(columnFilters).map(key => columnFilters[key]) : columnFilters;\r\n\r\n if (!Array.isArray(filtersArray)) {\r\n return [];\r\n }\r\n\r\n return filtersArray.map((filter) => {\r\n const tmpFilter: CurrentFilter = { columnId: filter.columnId || '' };\r\n if (filter.operator) {\r\n tmpFilter.operator = filter.operator;\r\n }\r\n if (Array.isArray(filter.searchTerms)) {\r\n tmpFilter.searchTerms = filter.searchTerms;\r\n }\r\n return tmpFilter;\r\n });\r\n }\r\n}\r\n","import { OnEventArgs, CellArgs, SlickEventHandler } from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\nexport class GridEventService {\r\n private _eventHandler: SlickEventHandler;\r\n\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n constructor() {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n /* OnCellChange Event */\r\n bindOnCellChange(grid: any, dataView: any) {\r\n // subscribe to this Slickgrid event of onCellChange\r\n this._eventHandler.subscribe(grid.onCellChange, (e: Event, args: CellArgs) => {\r\n if (!e || !args || !grid || args.cell === undefined || !grid.getColumns || !grid.getDataItem) {\r\n return;\r\n }\r\n const column = grid.getColumns()[args.cell];\r\n\r\n // if the column definition has a onCellChange property (a callback function), then run it\r\n if (typeof column.onCellChange === 'function') {\r\n // add to the output gridOptions & dataView since we'll need them inside the AJAX column.onCellChange\r\n const returnedArgs: OnEventArgs = {\r\n row: args.row,\r\n cell: args.cell,\r\n dataView,\r\n grid,\r\n columnDef: column,\r\n dataContext: grid.getDataItem(args.row)\r\n };\r\n\r\n // finally call up the Slick.column.onCellChanges.... function\r\n column.onCellChange(e, returnedArgs);\r\n }\r\n });\r\n }\r\n\r\n /* OnClick Event */\r\n bindOnClick(grid: any, dataView: any) {\r\n this._eventHandler.subscribe(grid.onClick, (e: Event, args: CellArgs) => {\r\n if (!e || !args || !grid || args.cell === undefined || !grid.getColumns || !grid.getDataItem) {\r\n return;\r\n }\r\n const column = grid && grid.getColumns && grid.getColumns()[args.cell];\r\n const gridOptions = grid && grid.getOptions && grid.getOptions() || {};\r\n\r\n // only when using autoCommitEdit, we will make the cell active (in focus) when clicked\r\n // setting the cell as active as a side effect and if autoCommitEdit is set to false then the Editors won't save correctly\r\n if (gridOptions.enableCellNavigation && (!gridOptions.editable || (gridOptions.editable && gridOptions.autoCommitEdit))) {\r\n grid.setActiveCell(args.row, args.cell);\r\n }\r\n\r\n // if the column definition has a onCellClick property (a callback function), then run it\r\n if (typeof column.onCellClick === 'function') {\r\n // add to the output gridOptions & dataView since we'll need them inside the AJAX column.onClick\r\n const returnedArgs: OnEventArgs = {\r\n row: args.row,\r\n cell: args.cell,\r\n dataView,\r\n grid,\r\n columnDef: column,\r\n dataContext: grid.getDataItem(args.row)\r\n };\r\n\r\n // finally call up the Slick.column.onCellClick.... function\r\n column.onCellClick(e, returnedArgs);\r\n }\r\n });\r\n }\r\n\r\n dispose() {\r\n this._eventHandler.unsubscribeAll();\r\n }\r\n}\r\n","import {\r\n Column,\r\n CurrentColumn,\r\n CurrentFilter,\r\n CurrentPagination,\r\n CurrentSorter,\r\n ExtensionName,\r\n GridOption,\r\n GridState,\r\n GridStateChange,\r\n GridStateType,\r\n} from './../models/index';\r\nimport { ExtensionService } from './extension.service';\r\nimport { FilterService } from './filter.service';\r\nimport { SortService } from './sort.service';\r\nimport { Subject, Subscription } from 'rxjs';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\nexport class GridStateService {\r\n private _eventHandler = new Slick.EventHandler();\r\n private _columns: Column[] = [];\r\n private _currentColumns: CurrentColumn[] = [];\r\n private _grid: any;\r\n private extensionService: ExtensionService;\r\n private filterService: FilterService;\r\n private sortService: SortService;\r\n private subscriptions: Subscription[] = [];\r\n onGridStateChanged = new Subject<GridStateChange>();\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n /**\r\n * Initialize the Export Service\r\n * @param grid\r\n * @param filterService\r\n * @param sortService\r\n * @param dataView\r\n */\r\n init(grid: any, extensionService: ExtensionService, filterService: FilterService, sortService: SortService): void {\r\n this._grid = grid;\r\n this.extensionService = extensionService;\r\n this.filterService = filterService;\r\n this.sortService = sortService;\r\n\r\n this.subscribeToAllGridChanges(grid);\r\n }\r\n\r\n /** Dispose of all the SlickGrid & Angular subscriptions */\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n\r\n // also unsubscribe all Angular Subscriptions\r\n this.subscriptions.forEach((subscription: Subscription) => {\r\n if (subscription && subscription.unsubscribe) {\r\n subscription.unsubscribe();\r\n }\r\n });\r\n this.subscriptions = [];\r\n this._currentColumns = [];\r\n this._columns = [];\r\n }\r\n\r\n /**\r\n * Get the current grid state (filters/sorters/pagination)\r\n * @return grid state\r\n */\r\n getCurrentGridState(): GridState {\r\n const gridState: GridState = {\r\n columns: this.getCurrentColumns(),\r\n filters: this.getCurrentFilters(),\r\n sorters: this.getCurrentSorters()\r\n };\r\n\r\n const currentPagination = this.getCurrentPagination();\r\n if (currentPagination) {\r\n gridState.pagination = currentPagination;\r\n }\r\n return gridState;\r\n }\r\n\r\n /**\r\n * Get the Columns (and their state: visibility/position) that are currently applied in the grid\r\n * @return current columns\r\n */\r\n getColumns(): Column[] {\r\n return this._columns;\r\n }\r\n\r\n /**\r\n * From an array of Grid Column Definitions, get the associated Current Columns\r\n * @param gridColumns\r\n */\r\n getAssociatedCurrentColumns(gridColumns: Column[]): CurrentColumn[] {\r\n const currentColumns: CurrentColumn[] = [];\r\n\r\n if (gridColumns && Array.isArray(gridColumns)) {\r\n gridColumns.forEach((column: Column, index: number) => {\r\n if (column && column.id) {\r\n currentColumns.push({\r\n columnId: column.id as string,\r\n cssClass: column.cssClass || '',\r\n headerCssClass: column.headerCssClass || '',\r\n width: column.width || 0\r\n });\r\n }\r\n });\r\n }\r\n this._currentColumns = currentColumns;\r\n return currentColumns;\r\n }\r\n\r\n /**\r\n * From an array of Current Columns, get the associated Grid Column Definitions\r\n * @param grid\r\n * @param currentColumns\r\n */\r\n getAssociatedGridColumns(grid: any, currentColumns: CurrentColumn[]): Column[] {\r\n const columns: Column[] = [];\r\n const gridColumns: Column[] = grid.getColumns();\r\n\r\n if (currentColumns && Array.isArray(currentColumns)) {\r\n currentColumns.forEach((currentColumn: CurrentColumn, index: number) => {\r\n const gridColumn: Column = gridColumns.find((c: Column) => c.id === currentColumn.columnId);\r\n if (gridColumn && gridColumn.id) {\r\n columns.push({\r\n ...gridColumn,\r\n cssClass: currentColumn.cssClass,\r\n headerCssClass: currentColumn.headerCssClass,\r\n width: currentColumn.width\r\n });\r\n }\r\n });\r\n }\r\n this._columns = columns;\r\n return columns;\r\n }\r\n\r\n /**\r\n * Get the Columns (and their state: visibility/position) that are currently applied in the grid\r\n * @return current columns\r\n */\r\n getCurrentColumns(): CurrentColumn[] {\r\n let currentColumns: CurrentColumn[] = [];\r\n if (this._currentColumns && Array.isArray(this._currentColumns) && this._currentColumns.length > 0) {\r\n currentColumns = this._currentColumns;\r\n } else {\r\n currentColumns = this.getAssociatedCurrentColumns(this._grid.getColumns());\r\n }\r\n\r\n return currentColumns;\r\n }\r\n\r\n /**\r\n * Get the Filters (and their state, columnId, searchTerm(s)) that are currently applied in the grid\r\n * @return current filters\r\n */\r\n getCurrentFilters(): CurrentFilter[] | null {\r\n if (this._gridOptions && this._gridOptions.backendServiceApi) {\r\n const backendService = this._gridOptions.backendServiceApi.service;\r\n if (backendService && backendService.getCurrentFilters) {\r\n return backendService.getCurrentFilters() as CurrentFilter[];\r\n }\r\n } else if (this.filterService && this.filterService.getCurrentLocalFilters) {\r\n return this.filterService.getCurrentLocalFilters();\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get current Pagination (and it's state, pageNumber, pageSize) that are currently applied in the grid\r\n * @return current pagination state\r\n */\r\n getCurrentPagination(): CurrentPagination | null {\r\n if (this._gridOptions && this._gridOptions.backendServiceApi) {\r\n const backendService = this._gridOptions.backendServiceApi.service;\r\n if (backendService && backendService.getCurrentPagination) {\r\n return backendService.getCurrentPagination();\r\n }\r\n } else {\r\n // TODO implement this whenever local pagination gets implemented\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Get the current Sorters (and their state, columnId, direction) that are currently applied in the grid\r\n * @return current sorters\r\n */\r\n getCurrentSorters(): CurrentSorter[] | null {\r\n if (this._gridOptions && this._gridOptions.backendServiceApi) {\r\n const backendService = this._gridOptions.backendServiceApi.service;\r\n if (backendService && backendService.getCurrentSorters) {\r\n return backendService.getCurrentSorters() as CurrentSorter[];\r\n }\r\n } else if (this.sortService && this.sortService.getCurrentLocalSorters) {\r\n return this.sortService.getCurrentLocalSorters();\r\n }\r\n return null;\r\n }\r\n\r\n resetColumns(columnDefinitions?: Column[]) {\r\n const columns: Column[] = columnDefinitions || this._columns;\r\n const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);\r\n this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });\r\n }\r\n\r\n /** if we use Row Selection or the Checkbox Selector, we need to reset any selection */\r\n resetRowSelection() {\r\n if (this._gridOptions.enableRowSelection || this._gridOptions.enableCheckboxSelector) {\r\n // this also requires the Row Selection Model to be registered as well\r\n const rowSelectionExtension = this.extensionService && this.extensionService.getExtensionByName && this.extensionService.getExtensionByName(ExtensionName.rowSelection);\r\n if (rowSelectionExtension && rowSelectionExtension.instance) {\r\n this._grid.setSelectedRows([]);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Subscribe to all necessary SlickGrid or Service Events that deals with a Grid change,\r\n * when triggered, we will publish a Grid State Event with current Grid State\r\n */\r\n subscribeToAllGridChanges(grid: any) {\r\n // Subscribe to Event Emitter of Filter changed\r\n this.subscriptions.push(\r\n this.filterService.onFilterChanged.subscribe((currentFilters: CurrentFilter[]) => {\r\n this.resetRowSelection();\r\n this.onGridStateChanged.next({ change: { newValues: currentFilters, type: GridStateType.filter }, gridState: this.getCurrentGridState() });\r\n })\r\n );\r\n // Subscribe to Event Emitter of Filter cleared\r\n this.subscriptions.push(\r\n this.filterService.onFilterCleared.subscribe(() => {\r\n this.resetRowSelection();\r\n this.onGridStateChanged.next({ change: { newValues: [], type: GridStateType.filter }, gridState: this.getCurrentGridState() });\r\n })\r\n );\r\n\r\n // Subscribe to Event Emitter of Sort changed\r\n this.subscriptions.push(\r\n this.sortService.onSortChanged.subscribe((currentSorters: CurrentSorter[]) => {\r\n this.resetRowSelection();\r\n this.onGridStateChanged.next({ change: { newValues: currentSorters, type: GridStateType.sorter }, gridState: this.getCurrentGridState() });\r\n })\r\n );\r\n\r\n // Subscribe to Event Emitter of Sort cleared\r\n this.subscriptions.push(\r\n this.sortService.onSortCleared.subscribe(() => {\r\n this.resetRowSelection();\r\n this.onGridStateChanged.next({ change: { newValues: [], type: GridStateType.sorter }, gridState: this.getCurrentGridState() });\r\n })\r\n );\r\n\r\n // Subscribe to ColumnPicker and/or GridMenu for show/hide Columns visibility changes\r\n this.bindExtensionAddonEventToGridStateChange(ExtensionName.columnPicker, 'onColumnsChanged');\r\n this.bindExtensionAddonEventToGridStateChange(ExtensionName.gridMenu, 'onColumnsChanged');\r\n\r\n // subscribe to Column Resize & Reordering\r\n this.bindSlickGridEventToGridStateChange('onColumnsReordered', grid);\r\n this.bindSlickGridEventToGridStateChange('onColumnsResized', grid);\r\n }\r\n\r\n // --\r\n // private methods\r\n // ------------------\r\n\r\n /**\r\n * Bind a SlickGrid Extension Event to a Grid State change event\r\n * @param extension name\r\n * @param grid\r\n */\r\n private bindExtensionAddonEventToGridStateChange(extensionName: ExtensionName, eventName: string) {\r\n const extension = this.extensionService && this.extensionService.getExtensionByName && this.extensionService.getExtensionByName(extensionName);\r\n const slickEvent = extension && extension.instance && extension.instance[eventName];\r\n\r\n if (slickEvent && slickEvent.subscribe) {\r\n this._eventHandler.subscribe(slickEvent, (e: Event, args: any) => {\r\n const columns: Column[] = args && args.columns;\r\n const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);\r\n this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Bind a Grid Event to a Grid State change event\r\n * @param event name\r\n * @param grid\r\n */\r\n private bindSlickGridEventToGridStateChange(eventName: string, grid: any) {\r\n const slickGridEvent = grid && grid[eventName];\r\n\r\n if (slickGridEvent && slickGridEvent.subscribe) {\r\n this._eventHandler.subscribe(slickGridEvent, (e: Event, args: any) => {\r\n const columns: Column[] = grid.getColumns();\r\n const currentColumns: CurrentColumn[] = this.getAssociatedCurrentColumns(columns);\r\n this.onGridStateChanged.next({ change: { newValues: currentColumns, type: GridStateType.columns }, gridState: this.getCurrentGridState() });\r\n });\r\n }\r\n }\r\n}\r\n","\r\nimport {\r\n Column,\r\n GridOption,\r\n SlickEventHandler,\r\n} from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare let $: any;\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\nexport class GroupingAndColspanService {\r\n private _eventHandler: SlickEventHandler;\r\n private _grid: any;\r\n\r\n constructor() {\r\n this._eventHandler = new Slick.EventHandler();\r\n }\r\n\r\n /** Getter of the SlickGrid Event Handler */\r\n get eventHandler(): SlickEventHandler {\r\n return this._eventHandler;\r\n }\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n /** Getter for the Column Definitions pulled through the Grid Object */\r\n private get _columnDefinitions(): Column[] {\r\n return (this._grid && this._grid.getColumns) ? this._grid.getColumns() : [];\r\n }\r\n\r\n init(grid: any, dataView: any) {\r\n this._grid = grid;\r\n\r\n if (grid && this._gridOptions) {\r\n // When dealing with Pre-Header Grouping colspan, we need to re-create the pre-header in multiple occasions\r\n // for all these events, we have to trigger a re-create\r\n if (this._gridOptions.createPreHeaderPanel) {\r\n this._eventHandler.subscribe(grid.onSort, (e: Event, args: any) => {\r\n this.createPreHeaderRowGroupingTitle();\r\n });\r\n this._eventHandler.subscribe(grid.onColumnsResized, (e: Event, args: any) => {\r\n this.createPreHeaderRowGroupingTitle();\r\n });\r\n this._eventHandler.subscribe(dataView.onRowCountChanged, (e: Event, args: any) => {\r\n this.createPreHeaderRowGroupingTitle();\r\n });\r\n\r\n // also not sure why at this point, but it seems that I need to call the 1st create in a delayed execution\r\n // probably some kind of timing issues and delaying it until the grid is fully ready does help\r\n setTimeout(() => this.createPreHeaderRowGroupingTitle(), 50);\r\n }\r\n }\r\n }\r\n\r\n dispose() {\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n }\r\n\r\n createPreHeaderRowGroupingTitle() {\r\n const $preHeaderPanel = $(this._grid.getPreHeaderPanel())\r\n .empty()\r\n .addClass('slick-header-columns')\r\n .css('left', '-1000px')\r\n .width(this._grid.getHeadersWidth());\r\n\r\n $preHeaderPanel.parent().addClass('slick-header');\r\n\r\n const headerColumnWidthDiff = this._grid.getHeaderColumnWidthDiff();\r\n let m;\r\n let header;\r\n let lastColumnGroup = '';\r\n let widthTotal = 0;\r\n\r\n for (let i = 0; i < this._columnDefinitions.length; i++) {\r\n m = this._columnDefinitions[i];\r\n if (lastColumnGroup === m.columnGroup && i > 0) {\r\n widthTotal += m.width;\r\n header.width(widthTotal - headerColumnWidthDiff);\r\n } else {\r\n widthTotal = m.width;\r\n header = $(`<div class=\"ui-state-default slick-header-column\" />`)\r\n .html(`<span class=\"slick-column-name\">${m.columnGroup || ''}</span>`)\r\n .width(m.width - headerColumnWidthDiff)\r\n .appendTo($preHeaderPanel);\r\n }\r\n lastColumnGroup = m.columnGroup;\r\n }\r\n }\r\n}\r\n","import { GridOption } from './../models/index';\r\nimport { getScrollBarWidth } from './utilities';\r\nimport { Subject } from 'rxjs';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n// global constants, height/width are in pixels\r\nconst DATAGRID_MIN_HEIGHT = 180;\r\nconst DATAGRID_MIN_WIDTH = 300;\r\nconst DATAGRID_BOTTOM_PADDING = 20;\r\nconst DATAGRID_PAGINATION_HEIGHT = 35;\r\n\r\nexport interface GridDimension {\r\n height: number;\r\n width: number;\r\n heightWithPagination?: number;\r\n}\r\n\r\nexport class ResizerService {\r\n private _fixedHeight: number | null;\r\n private _fixedWidth: number | null;\r\n private _grid: any;\r\n private _lastDimensions: GridDimension;\r\n private _timer: any;\r\n private _resizePaused = false;\r\n onGridAfterResize = new Subject<GridDimension>();\r\n onGridBeforeResize = new Subject<Event>();\r\n\r\n /** Getter for the Grid Options pulled through the Grid Object */\r\n private get _gridOptions(): GridOption {\r\n return (this._grid && this._grid.getOptions) ? this._grid.getOptions() : {};\r\n }\r\n\r\n private get _gridUid(): string {\r\n return (this._grid && this._grid.getUID) ? this._grid.getUID() : this._gridOptions && this._gridOptions.gridId;\r\n }\r\n\r\n init(grid: any, fixedDimensions?: GridDimension): void {\r\n this._grid = grid;\r\n if (fixedDimensions) {\r\n this._fixedHeight = fixedDimensions.height;\r\n this._fixedWidth = fixedDimensions.width;\r\n }\r\n }\r\n\r\n /** Bind an auto resize trigger on the datagrid, if that is enable then it will resize itself to the available space\r\n * Options: we could also provide a % factor to resize on each height/width independently\r\n */\r\n bindAutoResizeDataGrid(newSizes?: GridDimension) {\r\n // if we can't find the grid to resize, return without binding anything\r\n const gridDomElm = $(`#${this._gridOptions && this._gridOptions.gridId ? this._gridOptions.gridId : 'grid1'}`);\r\n if (gridDomElm === undefined || gridDomElm.offset() === undefined) {\r\n return null;\r\n }\r\n\r\n // -- 1st resize the datagrid size at first load (we need this because the .on event is not triggered on first load)\r\n // -- also we add a slight delay (in ms) so that we resize after the grid render is done\r\n this.resizeGrid(10, newSizes);\r\n\r\n // -- 2nd bind a trigger on the Window DOM element, so that it happens also when resizing after first load\r\n // -- bind auto-resize to Window object only if it exist\r\n $(window).on(`resize.grid.${this._gridUid}`, (event: Event) => {\r\n this.onGridBeforeResize.next(event);\r\n if (!this._resizePaused) {\r\n this.resizeGrid(0, newSizes);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Calculate the datagrid new height/width from the available space, also consider that a % factor might be applied to calculation\r\n * object gridOptions\r\n */\r\n calculateGridNewDimensions(gridOptions: GridOption): GridDimension | null {\r\n const gridDomElm = $(`#${gridOptions.gridId}`);\r\n const autoResizeOptions = gridOptions && gridOptions.autoResize || {};\r\n const containerElm = (autoResizeOptions && autoResizeOptions.containerId) ? $(`#${autoResizeOptions.containerId}`) : $(`#${gridOptions.gridContainerId}`);\r\n if (!window || containerElm === undefined || gridDomElm === undefined) {\r\n return null;\r\n }\r\n\r\n // calculate bottom padding\r\n // if using pagination, we need to add the pagination height to this bottom padding\r\n let bottomPadding = (autoResizeOptions && autoResizeOptions.bottomPadding) ? autoResizeOptions.bottomPadding : DATAGRID_BOTTOM_PADDING;\r\n if (bottomPadding && (gridOptions.enablePagination || this._gridOptions.backendServiceApi)) {\r\n bottomPadding += DATAGRID_PAGINATION_HEIGHT;\r\n }\r\n\r\n let gridHeight = 0;\r\n let gridOffsetTop = 0;\r\n\r\n // which DOM element are we using to calculate the available size for the grid?\r\n if (autoResizeOptions.calculateAvailableSizeBy === 'container') {\r\n // uses the container's height to calculate grid height without any top offset\r\n gridHeight = containerElm.height() || 0;\r\n } else {\r\n // uses the browser's window height with its top offset to calculate grid height\r\n gridHeight = window.innerHeight || 0;\r\n const coordOffsetTop = gridDomElm.offset();\r\n gridOffsetTop = (coordOffsetTop !== undefined) ? coordOffsetTop.top : 0;\r\n }\r\n\r\n const availableHeight = gridHeight - gridOffsetTop - bottomPadding;\r\n const availableWidth = containerElm.width() || 0;\r\n const maxHeight = autoResizeOptions && autoResizeOptions.maxHeight || undefined;\r\n const minHeight = autoResizeOptions && autoResizeOptions.minHeight || DATAGRID_MIN_HEIGHT;\r\n const maxWidth = autoResizeOptions && autoResizeOptions.maxWidth || undefined;\r\n const minWidth = autoResizeOptions && autoResizeOptions.minWidth || DATAGRID_MIN_WIDTH;\r\n\r\n let newHeight = availableHeight;\r\n let newWidth = (autoResizeOptions && autoResizeOptions.sidePadding) ? availableWidth - autoResizeOptions.sidePadding : availableWidth;\r\n\r\n // optionally (when defined), make sure that grid height & width are within their thresholds\r\n if (newHeight < minHeight) {\r\n newHeight = minHeight;\r\n }\r\n if (maxHeight && newHeight > maxHeight) {\r\n newHeight = maxHeight;\r\n }\r\n if (newWidth < minWidth) {\r\n newWidth = minWidth;\r\n }\r\n if (maxWidth && newWidth > maxWidth) {\r\n newWidth = maxWidth;\r\n }\r\n\r\n // return the new dimensions unless a fixed height/width was defined\r\n return {\r\n height: this._fixedHeight || newHeight,\r\n width: this._fixedWidth || newWidth\r\n };\r\n }\r\n\r\n /**\r\n * Dispose function when element is destroyed\r\n */\r\n dispose() {\r\n $(window).off(`resize.grid.${this._gridUid}`);\r\n }\r\n\r\n /**\r\n * For some reason this only seems to happen in Chrome and is sometime miscalculated by SlickGrid measureSrollbar() method\r\n * When that happens we will compensate and resize the Grid Viewport to avoid seeing horizontal scrollbar\r\n * Most of the time it happens, it's a tiny offset calculation of usually 3px (enough to show scrollbar)\r\n * GitHub issue reference: https://github.com/6pac/SlickGrid/issues/275\r\n */\r\n compensateHorizontalScroll(grid: any, gridOptions: GridOption) {\r\n const gridElm = $(`#${gridOptions.gridId}`);\r\n\r\n const scrollbarDimensions = grid && grid.getScrollbarDimensions();\r\n const slickGridScrollbarWidth = scrollbarDimensions && scrollbarDimensions.width;\r\n const calculatedScrollbarWidth = getScrollBarWidth();\r\n\r\n // if scrollbar width is different from SlickGrid calculation to our custom calculation\r\n // then resize the grid with the missing pixels to remove scroll (usually only 3px)\r\n if (slickGridScrollbarWidth < calculatedScrollbarWidth) {\r\n gridElm.width(gridElm.width() + (calculatedScrollbarWidth - slickGridScrollbarWidth));\r\n }\r\n }\r\n\r\n /**\r\n * Return the last resize dimensions used by the service\r\n * @return last dimensions\r\n */\r\n getLastResizeDimensions(): GridDimension {\r\n return this._lastDimensions;\r\n }\r\n\r\n /** Provide the possibility to pause the resizer for some time, until user decides to re-enabled it later if he wish to. */\r\n pauseResizer(isResizePaused: boolean) {\r\n this._resizePaused = isResizePaused;\r\n }\r\n\r\n /** Resize the datagrid to fit the browser height & width */\r\n resizeGrid(delay = 10, newSizes?: GridDimension): Promise<GridDimension> {\r\n if (!this._grid || !this._gridOptions) {\r\n throw new Error(`\r\n Angular-Slickgrid resizer requires a valid Grid object and Grid Options defined.\r\n You can fix this by setting your gridOption to use \"enableAutoResize\" or create an instance of the ResizerService by calling bindAutoResizeDataGrid()`);\r\n }\r\n\r\n return new Promise((resolve) => {\r\n // because of the javascript async nature, we might want to delay the resize a little bit\r\n delay = delay || 0;\r\n\r\n if (delay > 0) {\r\n clearTimeout(this._timer);\r\n this._timer = setTimeout(() => resolve(this.resizeGridCallback(newSizes)), delay);\r\n } else {\r\n resolve(this.resizeGridCallback(newSizes));\r\n }\r\n });\r\n }\r\n\r\n resizeGridCallback(newSizes: GridDimension) {\r\n const lastDimensions = this.resizeGridWithDimensions(newSizes);\r\n this.onGridAfterResize.next(lastDimensions);\r\n return lastDimensions;\r\n }\r\n\r\n resizeGridWithDimensions(newSizes?: GridDimension): GridDimension {\r\n // calculate the available sizes with minimum height defined as a constant\r\n const availableDimensions = this.calculateGridNewDimensions(this._gridOptions);\r\n const gridElm = $(`#${this._gridOptions.gridId}`) || {};\r\n const gridContainerElm = $(`#${this._gridOptions.gridContainerId}`) || {};\r\n\r\n if ((newSizes || availableDimensions) && gridElm.length > 0) {\r\n // get the new sizes, if new sizes are passed (not 0), we will use them else use available space\r\n // basically if user passes 1 of the dimension, let say he passes just the height,\r\n // we will use the height as a fixed height but the width will be resized by it's available space\r\n const newHeight = (newSizes && newSizes.height) ? newSizes.height : availableDimensions.height;\r\n const newWidth = (newSizes && newSizes.width) ? newSizes.width : availableDimensions.width;\r\n\r\n // apply these new height/width to the datagrid\r\n if (!this._gridOptions.autoHeight) {\r\n gridElm.height(newHeight);\r\n gridContainerElm.height(newHeight);\r\n }\r\n gridElm.width(newWidth);\r\n gridContainerElm.width(newWidth);\r\n\r\n // resize the slickgrid canvas on all browser except some IE versions\r\n // exclude all IE below IE11\r\n // IE11 wants to be a better standard (W3C) follower (finally) they even changed their appName output to also have 'Netscape'\r\n if (new RegExp('MSIE [6-8]').exec(navigator.userAgent) === null && this._grid && this._grid.resizeCanvas) {\r\n this._grid.resizeCanvas();\r\n }\r\n\r\n // also call the grid auto-size columns so that it takes available when going bigger\r\n if (this._gridOptions && this._gridOptions.enableAutoSizeColumns && this._grid.autosizeColumns) {\r\n // make sure that the grid still exist (by looking if the Grid UID is found in the DOM tree) to avoid SlickGrid error \"missing stylesheet\"\r\n if (this._gridUid && $(`.${this._gridUid}`).length > 0) {\r\n this._grid.autosizeColumns();\r\n }\r\n\r\n // compensate anytime SlickGrid measureScrollbar is incorrect\r\n this.compensateHorizontalScroll(this._grid, this._gridOptions);\r\n }\r\n\r\n // keep last resized dimensions & resolve them to the Promise\r\n this._lastDimensions = {\r\n height: newHeight,\r\n width: newWidth\r\n };\r\n\r\n if ((this._gridOptions.enablePagination || this._gridOptions.backendServiceApi)) {\r\n this._lastDimensions.heightWithPagination = newHeight + DATAGRID_PAGINATION_HEIGHT;\r\n }\r\n }\r\n\r\n return this._lastDimensions;\r\n }\r\n}\r\n","import { Aggregator } from './../models/aggregator.interface';\r\n\r\nexport class AvgAggregator implements Aggregator {\r\n private _count = 0;\r\n private _nonNullCount: number;\r\n private _sum: number;\r\n private _field: number | string;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n init(): void {\r\n this._count = 0;\r\n this._nonNullCount = 0;\r\n this._sum = 0;\r\n }\r\n\r\n accumulate(item: any) {\r\n const val = (item && item.hasOwnProperty(this._field)) ? item[this._field] : null;\r\n this._count++;\r\n if (val != null && val !== '' && !isNaN(val)) {\r\n this._nonNullCount++;\r\n this._sum += parseFloat(val);\r\n }\r\n }\r\n\r\n storeResult(groupTotals: any) {\r\n if (!groupTotals || groupTotals.avg === undefined) {\r\n groupTotals.avg = {};\r\n }\r\n if (this._nonNullCount !== 0) {\r\n groupTotals.avg[this._field] = this._sum / this._nonNullCount;\r\n }\r\n }\r\n}\r\n","import { Aggregator } from './../models/aggregator.interface';\r\n\r\nexport class MinAggregator implements Aggregator {\r\n private _min: number | null;\r\n private _field: number | string;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n init() {\r\n this._min = null;\r\n }\r\n\r\n accumulate(item: any) {\r\n const val = (item && item.hasOwnProperty(this._field)) ? item[this._field] : null;\r\n if (val != null && val !== '' && !isNaN(val)) {\r\n if (this._min == null || val < this._min) {\r\n this._min = parseFloat(val);\r\n }\r\n }\r\n }\r\n\r\n storeResult(groupTotals: any) {\r\n if (!groupTotals || groupTotals.min === undefined) {\r\n groupTotals.min = {};\r\n }\r\n groupTotals.min[this._field] = this._min;\r\n }\r\n}\r\n","import { Aggregator } from './../models/aggregator.interface';\r\n\r\nexport class MaxAggregator implements Aggregator {\r\n private _max: number | null;\r\n private _field: number | string;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n init(): void {\r\n this._max = null;\r\n }\r\n\r\n accumulate(item: any) {\r\n const val = (item && item.hasOwnProperty(this._field)) ? item[this._field] : null;\r\n if (val != null && val !== '' && !isNaN(val)) {\r\n if (this._max == null || val > this._max) {\r\n this._max = parseFloat(val);\r\n }\r\n }\r\n }\r\n\r\n storeResult(groupTotals: any) {\r\n if (!groupTotals || groupTotals.max === undefined) {\r\n groupTotals.max = {};\r\n }\r\n groupTotals.max[this._field] = this._max;\r\n }\r\n}\r\n","import { Aggregator } from './../models/aggregator.interface';\r\n\r\nexport class SumAggregator implements Aggregator {\r\n private _sum: number = 0;\r\n private _field: number | string;\r\n\r\n constructor(field: number | string) {\r\n this._field = field;\r\n }\r\n\r\n init() {\r\n this._sum = 0;\r\n }\r\n\r\n accumulate(item: any) {\r\n const val = (item && item.hasOwnProperty(this._field)) ? item[this._field] : null;\r\n if (val != null && val !== '' && !isNaN(val)) {\r\n this._sum += parseFloat(val);\r\n }\r\n }\r\n\r\n storeResult(groupTotals: any) {\r\n if (!groupTotals || groupTotals.sum === undefined) {\r\n groupTotals.sum = {};\r\n }\r\n groupTotals.sum[this._field] = this._sum;\r\n }\r\n}\r\n","import { AvgAggregator } from './avgAggregator';\r\nimport { MinAggregator } from './minAggregator';\r\nimport { MaxAggregator } from './maxAggregator';\r\nimport { SumAggregator } from './sumAggregator';\r\n\r\n/** Provides a list of different Aggregators for the Group Formatter */\r\nexport const Aggregators = {\r\n Avg: AvgAggregator,\r\n Min: MinAggregator,\r\n Max: MaxAggregator,\r\n Sum: SumAggregator\r\n};\r\n","import {\r\n Column,\r\n ColumnEditor,\r\n Editor,\r\n EditorValidator,\r\n EditorValidatorOutput,\r\n KeyCode,\r\n CollectionCustomStructure,\r\n FieldType\r\n} from './../models/index';\r\nimport { Constants } from './../constants';\r\nimport { findOrDefault } from '../services/utilities';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class AutoCompleteEditor implements Editor {\r\n private _currentValue: any;\r\n private _defaultTextValue: string;\r\n private _lastInputEvent: KeyboardEvent;\r\n $input: any;\r\n\r\n /** The property name for labels in the collection */\r\n labelName: string;\r\n\r\n /** The property name for values in the collection */\r\n valueName: string;\r\n\r\n forceUserInput: boolean;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get the Collection */\r\n get collection(): any[] {\r\n return this.columnDef && this.columnDef && this.columnDef.internalColumnEditor.collection || [];\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n /** Getter for the Custom Structure if exist */\r\n get customStructure(): CollectionCustomStructure {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.customStructure;\r\n }\r\n\r\n get hasAutoCommitEdit() {\r\n return this.args.grid.getOptions().autoCommitEdit;\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n get editorOptions() {\r\n return this.columnEditor && this.columnEditor.editorOptions || {};\r\n }\r\n\r\n init(): void {\r\n const columnId = this.columnDef && this.columnDef.id;\r\n const placeholder = this.columnEditor && this.columnEditor.placeholder || '';\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n this.labelName = this.customStructure && this.customStructure.label || 'label';\r\n this.valueName = this.customStructure && this.customStructure.value || 'value';\r\n this.$input = $(`<input type=\"text\" role=\"presentation\" autocomplete=\"off\" class=\"autocomplete editor-text editor-${columnId}\" placeholder=\"${placeholder}\" title=\"${title}\" />`)\r\n .appendTo(this.args.container)\r\n .on('keydown.nav', (event: KeyboardEvent) => {\r\n this._lastInputEvent = event;\r\n if (event.keyCode === KeyCode.LEFT || event.keyCode === KeyCode.RIGHT) {\r\n event.stopImmediatePropagation();\r\n }\r\n });\r\n\r\n // user might pass his own autocomplete options\r\n const autoCompleteOptions = this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.editorOptions;\r\n\r\n // user might provide his own custom structure\r\n // jQuery UI autocomplete requires a label/value pair, so we must remap them when user provide different ones\r\n let collection = this.collection;\r\n if (Array.isArray(collection) && this.customStructure) {\r\n collection = collection.map((item) => {\r\n return { label: item[this.labelName], value: item[this.valueName] };\r\n });\r\n }\r\n\r\n // when user passes it's own autocomplete options\r\n // we still need to provide our own \"select\" callback implementation\r\n if (autoCompleteOptions) {\r\n autoCompleteOptions.select = (event: Event, ui: any) => this.onClose(event, ui);\r\n this.$input.autocomplete(autoCompleteOptions);\r\n } else {\r\n this.$input.autocomplete({\r\n source: collection,\r\n minLength: 0,\r\n select: (event: Event, ui: any) => this.onClose(event, ui),\r\n });\r\n }\r\n\r\n setTimeout(() => {\r\n this.$input.focus().select();\r\n }, 50);\r\n }\r\n\r\n destroy() {\r\n this.$input.off('keydown.nav').remove();\r\n }\r\n\r\n focus() {\r\n this.$input.focus();\r\n }\r\n\r\n getValue() {\r\n return this.$input.val();\r\n }\r\n\r\n setValue(val: string) {\r\n this.$input.val(val);\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n const data = item[fieldNameFromComplexObject || fieldName];\r\n this._currentValue = data;\r\n this._defaultTextValue = typeof data === 'string' ? data : data[this.labelName];\r\n this.$input.val(this._defaultTextValue);\r\n this.$input[0].defaultValue = this._defaultTextValue;\r\n this.$input.select();\r\n }\r\n\r\n }\r\n\r\n save() {\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.hasAutoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n }\r\n\r\n serializeValue() {\r\n // if user provided a custom structure, we will serialize the value returned from the object with custom structure\r\n const minLength = typeof this.editorOptions.minLength !== 'undefined' ? this.editorOptions.minLength : 3;\r\n if (this.editorOptions.forceUserInput) {\r\n this._currentValue = this.$input.val().length >= minLength ? this.$input.val() : this._currentValue;\r\n }\r\n if (this.customStructure && this._currentValue.hasOwnProperty(this.labelName)) {\r\n return this._currentValue[this.labelName];\r\n } else if (this._currentValue.label) {\r\n if (this.columnDef.type === FieldType.object) {\r\n return {\r\n [this.labelName]: this._currentValue.label,\r\n [this.valueName]: this._currentValue.value\r\n };\r\n }\r\n return this._currentValue.label;\r\n }\r\n return this._currentValue;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n let newValue = state;\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // if we have a collection defined, we will try to find the string within the collection and return it\r\n if (Array.isArray(this.collection) && this.collection.length > 0) {\r\n newValue = findOrDefault(this.collection, (collectionItem: any) => {\r\n if (collectionItem && collectionItem.hasOwnProperty(this.labelName)) {\r\n return collectionItem[this.labelName].toString() === state;\r\n }\r\n return collectionItem.toString() === state;\r\n });\r\n }\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(newValue);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? newValue : '';\r\n }\r\n\r\n isValueChanged() {\r\n const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;\r\n if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {\r\n return true;\r\n }\r\n return (!(this.$input.val() === '' && this._defaultTextValue === null)) && (this.$input.val() !== this._defaultTextValue);\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const isRequired = this.columnEditor.required;\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();\r\n const errorMsg = this.columnEditor.errorMessage;\r\n\r\n if (this.validator) {\r\n return this.validator(elmValue, this.args);\r\n }\r\n\r\n // by default the editor is almost always valid (except when it's required but not provided)\r\n if (isRequired && elmValue === '') {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n\r\n private onClose(event: Event, ui: any) {\r\n if (ui && ui.item) {\r\n this._currentValue = ui && ui.item;\r\n const itemLabel = typeof ui.item === 'string' ? ui.item : ui.item.label;\r\n this.setValue(itemLabel);\r\n\r\n if (this.args.grid.getOptions().autoCommitEdit) {\r\n // do not use args.commitChanges() as this sets the focus to the next row.\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n }\r\n }\r\n }\r\n return false;\r\n }\r\n}\r\n","import { Constants } from './../constants';\r\nimport { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput } from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class CheckboxEditor implements Editor {\r\n $input: any;\r\n defaultValue: boolean;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init(): void {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n\r\n this.$input = $(`<input type=\"checkbox\" value=\"true\" class=\"editor-checkbox editor-${fieldId}\" title=\"${title}\" />`);\r\n this.$input.appendTo(this.args.container);\r\n this.$input.focus();\r\n\r\n // make the checkbox editor act like a regular checkbox that commit the value on click\r\n if (this.args.grid.getOptions().autoCommitEdit) {\r\n this.$input.click(() => this.args.grid.getEditorLock().commitCurrentEdit());\r\n }\r\n }\r\n\r\n destroy(): void {\r\n this.$input.remove();\r\n }\r\n\r\n focus(): void {\r\n this.$input.focus();\r\n }\r\n\r\n hide() {\r\n this.$input.hide();\r\n }\r\n\r\n show() {\r\n this.$input.show();\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultValue = !!item[fieldNameFromComplexObject || fieldName];\r\n if (this.defaultValue) {\r\n this.$input.prop('checked', true);\r\n } else {\r\n this.$input.prop('checked', false);\r\n }\r\n }\r\n }\r\n\r\n preClick() {\r\n this.$input.prop('checked', !this.$input.prop('checked'));\r\n }\r\n\r\n serializeValue(): boolean {\r\n return this.$input.prop('checked');\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(state);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';\r\n }\r\n\r\n isValueChanged() {\r\n return (this.serializeValue() !== this.defaultValue);\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const isRequired = this.columnEditor.required;\r\n const isChecked = (inputValue !== undefined) ? inputValue : this.$input && this.$input.prop && this.$input.prop('checked');\r\n const errorMsg = this.columnEditor.errorMessage;\r\n\r\n if (this.validator) {\r\n return this.validator(isChecked, this.args);\r\n }\r\n\r\n // by default the editor is almost always valid (except when it's required but not provided)\r\n if (isRequired && !isChecked) {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { Constants } from './../constants';\r\nimport { mapFlatpickrDateFormatWithFieldType, mapMomentDateFormatWithFieldType } from './../services/utilities';\r\nimport { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput, FieldType, GridOption, KeyCode } from './../models/index';\r\nimport * as moment_ from 'moment-mini';\r\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\r\n\r\ndeclare function require(name: string);\r\nrequire('flatpickr');\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/*\r\n * An example of a date picker editor using Flatpickr\r\n * https://chmln.github.io/flatpickr\r\n */\r\nexport class DateEditor implements Editor {\r\n private _$inputWithData: any;\r\n $input: any;\r\n flatInstance: any;\r\n defaultDate: string;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n /** Get Flatpickr options passed to the editor by the user */\r\n get editorOptions(): any {\r\n return this.columnEditor.editorOptions || {};\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init(): void {\r\n if (this.args && this.args.column) {\r\n const columnId = this.columnDef && this.columnDef.id;\r\n const placeholder = this.columnEditor && this.columnEditor.placeholder || '';\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n const gridOptions = this.args.grid.getOptions() as GridOption;\r\n this.defaultDate = (this.args.item) ? this.args.item[this.args.column.field] : null;\r\n const inputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.type || FieldType.dateIso);\r\n const outputFormat = mapFlatpickrDateFormatWithFieldType(this.columnDef.outputType || FieldType.dateUtc);\r\n let currentLocale = this.getCurrentLocale(this.columnDef, gridOptions);\r\n if (currentLocale.length > 2) {\r\n currentLocale = currentLocale.substring(0, 2);\r\n }\r\n\r\n const pickerOptions: any = {\r\n defaultDate: this.defaultDate,\r\n altInput: true,\r\n altInputClass: 'flatpickr-alt-input',\r\n altFormat: inputFormat,\r\n dateFormat: outputFormat,\r\n closeOnSelect: false,\r\n locale: (currentLocale !== 'en') ? this.loadFlatpickrLocale(currentLocale) : 'en',\r\n onChange: (selectedDates: any[] | any, dateStr: string, instance: any) => {\r\n this.save();\r\n },\r\n };\r\n\r\n // merge options with optional user's custom options\r\n const pickerMergedOptions = { ...pickerOptions, ...this.editorOptions };\r\n const inputCssClasses = `.editor-text.editor-${columnId}.flatpickr`;\r\n\r\n this.$input = $(`<input type=\"text\" data-defaultDate=\"${this.defaultDate}\" class=\"${inputCssClasses.replace(/\\./g, ' ')}\" placeholder=\"${placeholder}\" title=\"${title}\" />`);\r\n this.$input.appendTo(this.args.container);\r\n this.flatInstance = (this.$input[0] && typeof this.$input[0].flatpickr === 'function') ? this.$input[0].flatpickr(pickerMergedOptions) : null;\r\n\r\n // when we're using an alternate input to display data, we'll consider this input as the one to do the focus later on\r\n // else just use the top one\r\n this._$inputWithData = (pickerMergedOptions && pickerMergedOptions.altInput) ? $(`${inputCssClasses}.flatpickr-alt-input`) : this.$input;\r\n }\r\n }\r\n\r\n getCurrentLocale(columnDef: Column, gridOptions: GridOption) {\r\n const options = gridOptions || columnDef.params || {};\r\n if (options.i18n && options.i18n instanceof TranslateService) {\r\n return options.i18n.currentLang;\r\n }\r\n\r\n return 'en';\r\n }\r\n\r\n loadFlatpickrLocale(locale: string) {\r\n // change locale if needed, Flatpickr reference: https://chmln.github.io/flatpickr/localization/\r\n const gridOptions = this.args && this.args.grid && this.args.grid.getOptions();\r\n if (gridOptions && gridOptions.params && gridOptions.params.flapickrLocale) {\r\n return gridOptions.params.flapickrLocale;\r\n } else if (locale !== 'en') {\r\n const localeDefault: any = require(`flatpickr/dist/l10n/${locale}.js`).default;\r\n return (localeDefault && localeDefault[locale]) ? localeDefault[locale] : 'en';\r\n }\r\n return 'en';\r\n }\r\n\r\n destroy() {\r\n this.hide();\r\n this.$input.remove();\r\n if (this._$inputWithData && typeof this._$inputWithData.remove === 'function') {\r\n this._$inputWithData.remove();\r\n }\r\n }\r\n\r\n show() {\r\n if (this.flatInstance && typeof this.flatInstance.open === 'function') {\r\n this.flatInstance.open();\r\n }\r\n }\r\n\r\n hide() {\r\n if (this.flatInstance && typeof this.flatInstance.close === 'function') {\r\n this.flatInstance.close();\r\n }\r\n }\r\n\r\n focus() {\r\n if (this._$inputWithData && this._$inputWithData.focus) {\r\n this._$inputWithData.focus().select();\r\n } else if (this.$input && this.$input.focus) {\r\n this.$input.focus().select();\r\n }\r\n }\r\n\r\n save() {\r\n // autocommit will not focus the next editor\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.args.grid.getOptions().autoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n }\r\n\r\n getColumnEditor() {\r\n return this.args && this.args.column && this.args.column.internalColumnEditor && this.args.column.internalColumnEditor;\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultDate = item[fieldNameFromComplexObject || fieldName];\r\n this.flatInstance.setDate(item[this.args.column.field]);\r\n this.focus();\r\n }\r\n }\r\n\r\n serializeValue() {\r\n const domValue: string = this.$input.val();\r\n\r\n if (!domValue) {\r\n return '';\r\n }\r\n\r\n const outputFormat = mapMomentDateFormatWithFieldType(this.args.column.type || FieldType.dateIso);\r\n const value = moment(domValue).format(outputFormat);\r\n\r\n return value;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n const outputFormat = mapMomentDateFormatWithFieldType(this.args.column.type || FieldType.dateIso);\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const newValue = state ? moment(state, outputFormat).toDate() : '';\r\n const validation = this.validate(newValue);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? newValue : '';\r\n }\r\n\r\n isValueChanged() {\r\n return (!(this.$input.val() === '' && this.defaultDate == null)) && (this.$input.val() !== this.defaultDate);\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const isRequired = this.columnEditor.required;\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();\r\n const errorMsg = this.columnEditor.errorMessage;\r\n\r\n if (this.validator) {\r\n return this.validator(elmValue, this.args);\r\n }\r\n\r\n // by default the editor is almost always valid (except when it's required but not provided)\r\n if (isRequired && elmValue === '') {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n","import { Constants } from '../constants';\r\nimport { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput, KeyCode } from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nconst defaultDecimalPlaces = 0;\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class FloatEditor implements Editor {\r\n private _lastInputEvent: KeyboardEvent;\r\n $input: any;\r\n defaultValue: any;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n get hasAutoCommitEdit() {\r\n return this.args && this.args.grid && this.args.grid.getOptions && this.args.grid.getOptions().autoCommitEdit;\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init(): void {\r\n const columnId = this.columnDef && this.columnDef.id;\r\n const placeholder = this.columnEditor && this.columnEditor.placeholder || '';\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n\r\n this.$input = $(`<input type=\"number\" role=\"presentation\" autocomplete=\"off\" class=\"editor-text editor-${columnId}\" placeholder=\"${placeholder}\" title=\"${title}\" step=\"${this.getInputDecimalSteps()}\" />`)\r\n .appendTo(this.args.container)\r\n .on('keydown.nav', (event: KeyboardEvent) => {\r\n this._lastInputEvent = event;\r\n if (event.keyCode === KeyCode.LEFT || event.keyCode === KeyCode.RIGHT) {\r\n event.stopImmediatePropagation();\r\n }\r\n });\r\n\r\n // the lib does not get the focus out event for some reason\r\n // so register it here\r\n if (this.hasAutoCommitEdit) {\r\n this.$input.on('focusout', () => this.save());\r\n }\r\n\r\n setTimeout(() => {\r\n this.$input.focus().select();\r\n }, 50);\r\n }\r\n\r\n destroy() {\r\n this.$input.off('keydown.nav focusout').remove();\r\n }\r\n\r\n focus() {\r\n this.$input.focus();\r\n }\r\n\r\n getColumnEditor() {\r\n return this.args && this.args.column && this.args.column.internalColumnEditor;\r\n }\r\n\r\n getDecimalPlaces(): number {\r\n // returns the number of fixed decimal places or null\r\n let rtn = (this.columnEditor.params && this.columnEditor.params.hasOwnProperty('decimalPlaces')) ? this.columnEditor.params.decimalPlaces : undefined;\r\n\r\n if (rtn === undefined) {\r\n rtn = defaultDecimalPlaces;\r\n }\r\n return (!rtn && rtn !== 0 ? null : rtn);\r\n }\r\n\r\n getInputDecimalSteps(): string {\r\n const decimals = this.getDecimalPlaces();\r\n let zeroString = '';\r\n for (let i = 1; i < decimals; i++) {\r\n zeroString += '0';\r\n }\r\n\r\n if (decimals > 0) {\r\n return `0.${zeroString}1`;\r\n }\r\n return '1';\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultValue = item[fieldNameFromComplexObject || fieldName];\r\n const decPlaces = this.getDecimalPlaces();\r\n if (decPlaces !== null\r\n && (this.defaultValue || this.defaultValue === 0)\r\n && this.defaultValue.toFixed) {\r\n this.defaultValue = this.defaultValue.toFixed(decPlaces);\r\n }\r\n\r\n this.$input.val(this.defaultValue);\r\n this.$input[0].defaultValue = this.defaultValue;\r\n this.$input.select();\r\n }\r\n }\r\n\r\n serializeValue() {\r\n const elmValue = this.$input.val();\r\n if (elmValue === '' || isNaN(elmValue)) {\r\n return elmValue;\r\n }\r\n\r\n let rtn = parseFloat(elmValue);\r\n const decPlaces = this.getDecimalPlaces();\r\n if (decPlaces !== null\r\n && (rtn || rtn === 0)\r\n && rtn.toFixed) {\r\n rtn = parseFloat(rtn.toFixed(decPlaces));\r\n }\r\n\r\n return rtn;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(state);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';\r\n }\r\n\r\n isValueChanged() {\r\n const elmValue = this.$input.val();\r\n const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;\r\n if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {\r\n return true;\r\n }\r\n return (!(elmValue === '' && this.defaultValue === null)) && (elmValue !== this.defaultValue);\r\n }\r\n\r\n save() {\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.hasAutoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();\r\n const floatNumber = !isNaN(elmValue as number) ? parseFloat(elmValue) : null;\r\n const decPlaces = this.getDecimalPlaces();\r\n const isRequired = this.columnEditor.required;\r\n const minValue = this.columnEditor.minValue;\r\n const maxValue = this.columnEditor.maxValue;\r\n const errorMsg = this.columnEditor.errorMessage;\r\n const mapValidation = {\r\n '{{minValue}}': minValue,\r\n '{{maxValue}}': maxValue,\r\n '{{minDecimal}}': 0,\r\n '{{maxDecimal}}': decPlaces\r\n };\r\n let isValid = true;\r\n let outputMsg = '';\r\n\r\n if (this.validator) {\r\n return this.validator(elmValue, this.args);\r\n } else if (isRequired && elmValue === '') {\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_REQUIRED_FIELD;\r\n } else if (isNaN(elmValue as number) || (decPlaces === 0 && !/^[-+]?(\\d+(\\.)?(\\d)*)$/.test(elmValue))) {\r\n // when decimal value is 0 (which is the default), we accept 0 or more decimal values\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_VALID_NUMBER;\r\n } else if (minValue !== undefined && maxValue !== undefined && floatNumber !== null && (floatNumber < minValue || floatNumber > maxValue)) {\r\n // MIN & MAX Values provided\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_NUMBER_BETWEEN.replace(/{{minValue}}|{{maxValue}}/gi, (matched) => mapValidation[matched]);\r\n } else if (minValue !== undefined && floatNumber !== null && floatNumber <= minValue) {\r\n // MIN VALUE ONLY\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_NUMBER_MIN.replace(/{{minValue}}/gi, (matched) => mapValidation[matched]);\r\n } else if (maxValue !== undefined && floatNumber !== null && floatNumber >= maxValue) {\r\n // MAX VALUE ONLY\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_NUMBER_MAX.replace(/{{maxValue}}/gi, (matched) => mapValidation[matched]);\r\n } else if ((decPlaces > 0 && !new RegExp(`^(\\\\d*(\\\\.)?(\\\\d){0,${decPlaces}})$`).test(elmValue))) {\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_DECIMAL_BETWEEN.replace(/{{minDecimal}}|{{maxDecimal}}/gi, (matched) => mapValidation[matched]);\r\n }\r\n\r\n return {\r\n valid: isValid,\r\n msg: outputMsg\r\n };\r\n }\r\n}\r\n","import { Constants } from './../constants';\r\nimport { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput, KeyCode } from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class IntegerEditor implements Editor {\r\n private _lastInputEvent: KeyboardEvent;\r\n $input: any;\r\n defaultValue: any;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n get hasAutoCommitEdit() {\r\n return this.args && this.args.grid && this.args.grid.getOptions && this.args.grid.getOptions().autoCommitEdit;\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init(): void {\r\n const columnId = this.columnDef && this.columnDef.id;\r\n const placeholder = this.columnEditor && this.columnEditor.placeholder || '';\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n\r\n this.$input = $(`<input type=\"number\" role=\"presentation\" autocomplete=\"off\" class=\"editor-text editor-${columnId}\" placeholder=\"${placeholder}\" title=\"${title}\" />`)\r\n .appendTo(this.args.container)\r\n .on('keydown.nav', (event: KeyboardEvent) => {\r\n this._lastInputEvent = event;\r\n if (event.keyCode === KeyCode.LEFT || event.keyCode === KeyCode.RIGHT) {\r\n event.stopImmediatePropagation();\r\n }\r\n });\r\n\r\n // the lib does not get the focus out event for some reason\r\n // so register it here\r\n if (this.hasAutoCommitEdit) {\r\n this.$input.on('focusout', () => this.save());\r\n }\r\n\r\n setTimeout(() => {\r\n this.$input.focus().select();\r\n }, 50);\r\n }\r\n\r\n destroy() {\r\n this.$input.off('keydown.nav focusout').remove();\r\n }\r\n\r\n focus() {\r\n this.$input.focus();\r\n }\r\n\r\n getColumnEditor() {\r\n return this.args && this.args.column && this.args.column.internalColumnEditor;\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultValue = item[fieldNameFromComplexObject || fieldName];\r\n this.$input.val(this.defaultValue);\r\n this.$input[0].defaultValue = this.defaultValue;\r\n this.$input.select();\r\n }\r\n }\r\n\r\n serializeValue() {\r\n const elmValue = this.$input.val();\r\n if (elmValue === '' || isNaN(elmValue)) {\r\n return elmValue;\r\n }\r\n return isNaN(elmValue) ? elmValue : parseInt(elmValue, 10);\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(state);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';\r\n }\r\n\r\n isValueChanged() {\r\n const elmValue = this.$input.val();\r\n const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;\r\n if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {\r\n return true;\r\n }\r\n return (!(elmValue === '' && this.defaultValue === null)) && (elmValue !== this.defaultValue);\r\n }\r\n\r\n save() {\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.hasAutoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();\r\n const intNumber = !isNaN(elmValue as number) ? parseInt(elmValue, 10) : null;\r\n const errorMsg = this.columnEditor.errorMessage;\r\n const isRequired = this.columnEditor.required;\r\n const minValue = this.columnEditor.minValue;\r\n const maxValue = this.columnEditor.maxValue;\r\n const mapValidation = {\r\n '{{minValue}}': minValue,\r\n '{{maxValue}}': maxValue\r\n };\r\n let isValid = true;\r\n let outputMsg = '';\r\n\r\n if (this.validator) {\r\n return this.validator(elmValue, this.args);\r\n } else if (isRequired && elmValue === '') {\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_REQUIRED_FIELD;\r\n } else if (isNaN(elmValue as number) || !/^[+-]?\\d+$/.test(elmValue)) {\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_VALID_INTEGER;\r\n } else if (minValue !== undefined && maxValue !== undefined && intNumber !== null && (intNumber < minValue || intNumber > maxValue)) {\r\n // MIN & MAX Values provided\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_INTEGER_BETWEEN.replace(/{{minValue}}|{{maxValue}}/gi, (matched) => mapValidation[matched]);\r\n } else if (minValue !== undefined && intNumber !== null && intNumber <= minValue) {\r\n // MIN VALUE ONLY\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_INTEGER_MIN.replace(/{{minValue}}/gi, (matched) => mapValidation[matched]);\r\n } else if (maxValue !== undefined && intNumber !== null && intNumber >= maxValue) {\r\n // MAX VALUE ONLY\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n isValid = false;\r\n outputMsg = errorMsg || Constants.VALIDATION_EDITOR_INTEGER_MAX.replace(/{{maxValue}}/gi, (matched) => mapValidation[matched]);\r\n }\r\n\r\n return {\r\n valid: isValid,\r\n msg: outputMsg\r\n };\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { Constants } from './../constants';\r\nimport {\r\n Column,\r\n ColumnEditor,\r\n Editor,\r\n EditorValidator,\r\n EditorValidatorOutput,\r\n GridOption,\r\n HtmlElementPosition,\r\n KeyCode\r\n} from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class LongTextEditor implements Editor {\r\n $textarea: any;\r\n $wrapper: any;\r\n defaultValue: any;\r\n\r\n /** Grid options */\r\n gridOptions: GridOption;\r\n\r\n /** The translate library */\r\n private _translate: TranslateService;\r\n\r\n constructor(private args: any) {\r\n this.gridOptions = this.args.grid.getOptions() as GridOption;\r\n const options = this.gridOptions || this.args.column.params || {};\r\n this._translate = options.i18n;\r\n\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n get hasAutoCommitEdit() {\r\n return this.args.grid.getOptions().autoCommitEdit;\r\n }\r\n\r\n init(): void {\r\n const columnId = this.columnDef && this.columnDef.id;\r\n const placeholder = this.columnEditor && this.columnEditor.placeholder || '';\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n const cancelText = this._translate && this._translate.instant('CANCEL') || Constants.TEXT_CANCEL;\r\n const saveText = this._translate && this._translate.instant('SAVE') || Constants.TEXT_SAVE;\r\n const $container = $('body');\r\n\r\n this.$wrapper = $(`<div class=\"slick-large-editor-text editor-${columnId}\" />`).appendTo($container);\r\n this.$textarea = $(`<textarea hidefocus rows=\"5\" placeholder=\"${placeholder}\" title=\"${title}\">`).appendTo(this.$wrapper);\r\n\r\n // the lib does not get the focus out event for some reason\r\n // so register it here\r\n if (this.hasAutoCommitEdit) {\r\n this.$textarea.on('focusout', () => this.save());\r\n }\r\n\r\n $(`<div class=\"editor-footer\">\r\n <button class=\"btn btn-primary btn-xs\">${saveText}</button>\r\n <button class=\"btn btn-default btn-xs\">${cancelText}</button>\r\n </div>`).appendTo(this.$wrapper);\r\n\r\n this.$wrapper.find('button:first').on('click', () => this.save());\r\n this.$wrapper.find('button:last').on('click', () => this.cancel());\r\n this.$textarea.on('keydown', this.handleKeyDown.bind(this));\r\n\r\n this.position(this.args && this.args.position);\r\n this.$textarea.focus().select();\r\n }\r\n\r\n handleKeyDown(event: KeyboardEvent) {\r\n if (event.which === KeyCode.ENTER && event.ctrlKey) {\r\n this.save();\r\n } else if (event.which === KeyCode.ESCAPE) {\r\n event.preventDefault();\r\n this.cancel();\r\n } else if (event.which === KeyCode.TAB && event.shiftKey) {\r\n event.preventDefault();\r\n if (this.args && this.args.grid) {\r\n this.args.grid.navigatePrev();\r\n }\r\n } else if (event.which === KeyCode.TAB) {\r\n event.preventDefault();\r\n if (this.args && this.args.grid) {\r\n this.args.grid.navigateNext();\r\n }\r\n }\r\n }\r\n\r\n cancel() {\r\n this.$textarea.val(this.defaultValue);\r\n if (this.args && this.args.cancelChanges) {\r\n this.args.cancelChanges();\r\n }\r\n }\r\n\r\n hide() {\r\n this.$wrapper.hide();\r\n }\r\n\r\n show() {\r\n this.$wrapper.show();\r\n }\r\n\r\n position(position: HtmlElementPosition) {\r\n this.$wrapper\r\n .css('top', (position.top || 0) - 5)\r\n .css('left', (position.left || 0) - 5);\r\n }\r\n\r\n destroy() {\r\n this.$wrapper.off('keydown focusout').remove();\r\n }\r\n\r\n focus() {\r\n this.$textarea.focus();\r\n }\r\n\r\n getValue() {\r\n return this.$textarea.val();\r\n }\r\n\r\n setValue(val: string) {\r\n this.$textarea.val(val);\r\n }\r\n\r\n getColumnEditor() {\r\n return this.args && this.args.column && this.args.column.internalColumnEditor && this.args.column.internalColumnEditor;\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultValue = item[fieldNameFromComplexObject || fieldName];\r\n this.$textarea.val(this.defaultValue);\r\n this.$textarea.select();\r\n }\r\n }\r\n\r\n serializeValue() {\r\n return this.$textarea.val();\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(state);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';\r\n }\r\n\r\n\r\n isValueChanged() {\r\n return (!(this.$textarea.val() === '' && this.defaultValue === null)) && (this.$textarea.val() !== this.defaultValue);\r\n }\r\n\r\n save() {\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.hasAutoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const isRequired = this.columnEditor.required;\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$textarea && this.$textarea.val && this.$textarea.val();\r\n const errorMsg = this.columnEditor.errorMessage;\r\n\r\n if (this.validator) {\r\n return this.validator(elmValue, this.args);\r\n }\r\n\r\n // by default the editor is almost always valid (except when it's required but not provided)\r\n if (isRequired && elmValue === '') {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n","import { TranslateService } from '@ngx-translate/core';\r\nimport { Constants } from '../constants';\r\nimport {\r\n CollectionCustomStructure,\r\n CollectionOption,\r\n Column,\r\n ColumnEditor,\r\n Editor,\r\n EditorValidator,\r\n EditorValidatorOutput,\r\n FieldType,\r\n GridOption,\r\n MultipleSelectOption,\r\n SelectOption,\r\n} from './../models/index';\r\nimport { CollectionService } from '../services/index';\r\nimport { charArraysEqual, findOrDefault, getDescendantProperty, htmlEncode, unsubscribeAllObservables } from '../services/utilities';\r\nimport { Subscription } from 'rxjs';\r\nimport * as DOMPurify_ from 'dompurify';\r\nconst DOMPurify = DOMPurify_; // patch to fix rollup to work\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/**\r\n * Slickgrid editor class for multiple/single select lists\r\n */\r\nexport class SelectEditor implements Editor {\r\n /** The JQuery DOM element */\r\n $editorElm: any;\r\n\r\n /** Editor Multiple-Select options */\r\n editorElmOptions: MultipleSelectOption;\r\n\r\n /** DOM Element Name, useful for auto-detecting positioning (dropup / dropdown) */\r\n elementName: string;\r\n\r\n /** The multiple-select options for a multiple select list */\r\n defaultOptions: MultipleSelectOption;\r\n\r\n /** The default item values that are set */\r\n defaultValue: any[];\r\n\r\n /** The property name for values in the collection */\r\n valueName: string;\r\n\r\n /** The property name for labels in the collection */\r\n labelName: string;\r\n\r\n /** The property name for a prefix that can be added to the labels in the collection */\r\n labelPrefixName: string;\r\n\r\n /** The property name for a suffix that can be added to the labels in the collection */\r\n labelSuffixName: string;\r\n\r\n /** A label that can be added to each option and can be used as an alternative to display selected options */\r\n optionLabel: string;\r\n\r\n /** Grid options */\r\n gridOptions: GridOption;\r\n\r\n /** Do we translate the label? */\r\n enableTranslateLabel: boolean;\r\n\r\n /** Observable Subscriptions */\r\n _subscriptions: Subscription[] = [];\r\n\r\n // flag to signal that the editor is destroying itself, helps prevent\r\n // commit changes from being called twice and erroring\r\n protected _destroying = false;\r\n\r\n /** Collection Service */\r\n protected _collectionService: CollectionService;\r\n\r\n /** The translate library */\r\n protected _translate: TranslateService;\r\n\r\n constructor(protected args: any, protected isMultipleSelect) {\r\n this.gridOptions = this.args.grid.getOptions() as GridOption;\r\n const gridOptions = this.gridOptions || this.args.column.params || {};\r\n this._translate = gridOptions.i18n;\r\n\r\n // provide the name attribute to the DOM element which will be needed to auto-adjust drop position (dropup / dropdown)\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n this.elementName = `editor-${fieldId}`;\r\n\r\n const libOptions: MultipleSelectOption = {\r\n autoAdjustDropHeight: true,\r\n autoAdjustDropPosition: true,\r\n autoAdjustDropWidthByTextSize: true,\r\n container: 'body',\r\n filter: false,\r\n maxHeight: 275,\r\n name: this.elementName,\r\n single: true,\r\n textTemplate: ($elm) => {\r\n // render HTML code or not, by default it is sanitized and won't be rendered\r\n const isRenderHtmlEnabled = this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.enableRenderHtml || false;\r\n return isRenderHtmlEnabled ? $elm.text() : $elm.html();\r\n },\r\n onBlur: () => this.destroy(),\r\n onClose: () => {\r\n if (!this._destroying && this.hasAutoCommitEdit) {\r\n // do not use args.commitChanges() as this sets the focus to the next\r\n // row. Also the select list will stay shown when clicking off the grid\r\n args.grid.getEditorLock().commitCurrentEdit();\r\n }\r\n }\r\n };\r\n\r\n if (isMultipleSelect) {\r\n libOptions.single = false;\r\n libOptions.addTitle = true;\r\n libOptions.okButton = true;\r\n libOptions.selectAllDelimiter = ['', ''];\r\n\r\n if (this._translate) {\r\n libOptions.countSelected = this._translate.instant('X_OF_Y_SELECTED');\r\n libOptions.allSelected = this._translate.instant('ALL_SELECTED');\r\n libOptions.selectAllText = this._translate.instant('SELECT_ALL');\r\n }\r\n }\r\n\r\n // assign the multiple select lib options\r\n this.defaultOptions = libOptions;\r\n\r\n this.init();\r\n }\r\n\r\n /** Get the Collection */\r\n get collection(): any[] {\r\n return this.columnDef && this.columnDef && this.columnDef.internalColumnEditor.collection || [];\r\n }\r\n\r\n /** Getter for the Collection Options */\r\n get collectionOptions(): CollectionOption {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.collectionOptions;\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n /** Getter for the Custom Structure if exist */\r\n protected get customStructure(): CollectionCustomStructure {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.customStructure;\r\n }\r\n\r\n get hasAutoCommitEdit() {\r\n return this.args.grid.getOptions().autoCommitEdit;\r\n }\r\n\r\n /**\r\n * The current selected values (multiple select) from the collection\r\n */\r\n get currentValues() {\r\n // collection of strings, just return the filtered string that are equals\r\n if (this.collection.every(x => typeof x === 'string')) {\r\n return this.collection.filter(c => this.$editorElm.val().indexOf(c.toString()) !== -1);\r\n }\r\n\r\n // collection of label/value pair\r\n const separatorBetweenLabels = this.collectionOptions && this.collectionOptions.separatorBetweenTextLabels || '';\r\n const isIncludingPrefixSuffix = this.collectionOptions && this.collectionOptions.includePrefixSuffixToSelectedValues || false;\r\n\r\n return this.collection\r\n .filter(c => this.$editorElm.val().indexOf(c[this.valueName].toString()) !== -1)\r\n .map(c => {\r\n const labelText = c[this.valueName];\r\n let prefixText = c[this.labelPrefixName] || '';\r\n let suffixText = c[this.labelSuffixName] || '';\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n if (fieldNameFromComplexObject && typeof c === 'object') {\r\n return c;\r\n }\r\n\r\n // also translate prefix/suffix if enableTranslateLabel is true and text is a string\r\n prefixText = (this.enableTranslateLabel && prefixText && typeof prefixText === 'string') ? this._translate.instant(prefixText || ' ') : prefixText;\r\n suffixText = (this.enableTranslateLabel && suffixText && typeof suffixText === 'string') ? this._translate.instant(suffixText || ' ') : suffixText;\r\n\r\n if (isIncludingPrefixSuffix) {\r\n const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text); // add to a temp array for joining purpose and filter out empty text\r\n return tmpOptionArray.join(separatorBetweenLabels);\r\n }\r\n return labelText;\r\n });\r\n }\r\n\r\n\r\n /**\r\n * The current selected values (single select) from the collection\r\n */\r\n get currentValue() {\r\n // collection of strings, just return the filtered string that are equals\r\n if (this.collection.every(x => typeof x === 'string')) {\r\n return findOrDefault(this.collection, (c: any) => c.toString() === this.$editorElm.val());\r\n }\r\n\r\n // collection of label/value pair\r\n const separatorBetweenLabels = this.collectionOptions && this.collectionOptions.separatorBetweenTextLabels || '';\r\n const isIncludingPrefixSuffix = this.collectionOptions && this.collectionOptions.includePrefixSuffixToSelectedValues || false;\r\n const itemFound = findOrDefault(this.collection, (c: any) => c[this.valueName].toString() === this.$editorElm.val());\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n if (fieldNameFromComplexObject && typeof itemFound === 'object') {\r\n return itemFound;\r\n } else if (itemFound) {\r\n const labelText = itemFound[this.valueName];\r\n\r\n if (isIncludingPrefixSuffix) {\r\n let prefixText = itemFound[this.labelPrefixName] || '';\r\n let suffixText = itemFound[this.labelSuffixName] || '';\r\n\r\n // also translate prefix/suffix if enableTranslateLabel is true and text is a string\r\n prefixText = (this.enableTranslateLabel && prefixText && typeof prefixText === 'string') ? this._translate.instant(prefixText || ' ') : prefixText;\r\n suffixText = (this.enableTranslateLabel && suffixText && typeof suffixText === 'string') ? this._translate.instant(suffixText || ' ') : suffixText;\r\n\r\n // add to a temp array for joining purpose and filter out empty text\r\n const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text);\r\n return tmpOptionArray.join(separatorBetweenLabels);\r\n }\r\n\r\n return labelText;\r\n }\r\n\r\n return '';\r\n }\r\n\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init() {\r\n if (!this.args) {\r\n throw new Error('[Angular-SlickGrid] An editor must always have an \"init()\" with valid arguments.');\r\n }\r\n\r\n if (!this.columnDef || !this.columnDef.internalColumnEditor || (!this.columnDef.internalColumnEditor.collection && !this.columnDef.internalColumnEditor.collectionAsync)) {\r\n throw new Error(`[Angular-SlickGrid] You need to pass a \"collection\" (or \"collectionAsync\") inside Column Definition Editor for the MultipleSelect/SingleSelect Editor to work correctly.\r\n Also each option should include a value/label pair (or value/labelKey when using Locale).\r\n For example: { editor: { collection: [{ value: true, label: 'True' },{ value: false, label: 'False'}] } }`);\r\n }\r\n\r\n this._collectionService = new CollectionService(this._translate);\r\n this.enableTranslateLabel = (this.columnDef.internalColumnEditor.enableTranslateLabel) ? this.columnDef.internalColumnEditor.enableTranslateLabel : false;\r\n this.labelName = this.customStructure && this.customStructure.label || 'label';\r\n this.labelPrefixName = this.customStructure && this.customStructure.labelPrefix || 'labelPrefix';\r\n this.labelSuffixName = this.customStructure && this.customStructure.labelSuffix || 'labelSuffix';\r\n this.optionLabel = this.customStructure && this.customStructure.optionLabel || 'value';\r\n this.valueName = this.customStructure && this.customStructure.value || 'value';\r\n\r\n if (this.enableTranslateLabel && (!this._translate || typeof this._translate.instant !== 'function')) {\r\n throw new Error(`[select-editor] The ngx-translate TranslateService is required for the Select Editor to work correctly`);\r\n }\r\n\r\n // always render the Select (dropdown) DOM element, even if user passed a \"collectionAsync\",\r\n // if that is the case, the Select will simply be without any options but we still have to render it (else SlickGrid would throw an error)\r\n this.renderDomElement(this.collection);\r\n }\r\n\r\n applyValue(item: any, state: any): void {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n const fieldType = this.columnDef && this.columnDef.type;\r\n let newValue = state;\r\n\r\n // when the provided user defined the column field type as a possible number then try parsing the state value as that\r\n if (fieldType === FieldType.number || fieldType === FieldType.integer || fieldType === FieldType.boolean) {\r\n newValue = parseFloat(state);\r\n }\r\n\r\n // when set as a multiple selection, we can assume that the 3rd party lib multiple-select will return a CSV string\r\n // we need to re-split that into an array to be the same as the original column\r\n if (this.isMultipleSelect && typeof state === 'string' && state.indexOf(',') >= 0) {\r\n newValue = state.split(',');\r\n }\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(newValue);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? newValue : '';\r\n }\r\n\r\n destroy() {\r\n this._destroying = true;\r\n if (this.$editorElm && typeof this.$editorElm.multipleSelect === 'function') {\r\n this.$editorElm.multipleSelect('destroy');\r\n this.$editorElm.remove();\r\n const elementClassName = this.elementName.toString().replace('.', '\\\\.'); // make sure to escape any dot \".\" from CSS class to avoid console error\r\n $(`[name=${elementClassName}].ms-drop`).remove();\r\n } else if (this.$editorElm && typeof this.$editorElm.remove === 'function') {\r\n this.$editorElm.remove();\r\n }\r\n this._subscriptions = unsubscribeAllObservables(this._subscriptions);\r\n }\r\n\r\n loadValue(item: any): void {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n const currentValue = item[fieldNameFromComplexObject || fieldName];\r\n const loadValue = fieldNameFromComplexObject && currentValue.hasOwnProperty(this.valueName) ? currentValue[this.valueName] : currentValue;\r\n if (this.isMultipleSelect && Array.isArray(loadValue)) {\r\n this.loadMultipleValues(loadValue);\r\n } else {\r\n this.loadSingleValue(loadValue);\r\n }\r\n this.refresh();\r\n }\r\n }\r\n\r\n loadMultipleValues(currentValues: any[]) {\r\n // convert to string because that is how the DOM will return these values\r\n if (Array.isArray(currentValues)) {\r\n // keep the default values in memory for references\r\n this.defaultValue = currentValues.map((i: any) => i);\r\n\r\n // compare all the array values but as string type since multiple-select always return string\r\n const currentStringValues = currentValues.map((i: any) => i.toString());\r\n this.$editorElm.find('option').each((i: number, $e: any) => {\r\n $e.selected = (currentStringValues.indexOf($e.value) !== -1);\r\n });\r\n }\r\n }\r\n\r\n loadSingleValue(currentValue: any) {\r\n // keep the default value in memory for references\r\n this.defaultValue = currentValue;\r\n\r\n // make sure the prop exists first\r\n this.$editorElm.find('option').each((i: number, $e: any) => {\r\n // check equality after converting defaultValue to string since the DOM value will always be of type string\r\n $e.selected = (currentValue.toString() === $e.value);\r\n });\r\n }\r\n\r\n serializeValue(): any {\r\n return (this.isMultipleSelect) ? this.currentValues : this.currentValue;\r\n }\r\n\r\n focus() {\r\n if (this.$editorElm && this.$editorElm.multipleSelect) {\r\n this.$editorElm.multipleSelect('focus');\r\n }\r\n }\r\n\r\n isValueChanged(): boolean {\r\n if (this.isMultipleSelect) {\r\n return !charArraysEqual(this.$editorElm.val(), this.defaultValue);\r\n }\r\n return this.$editorElm.val() !== this.defaultValue;\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const isRequired = this.columnEditor.required;\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$editorElm && this.$editorElm.val && this.$editorElm.val();\r\n const errorMsg = this.columnEditor.errorMessage;\r\n\r\n if (this.validator) {\r\n const value = (inputValue !== undefined) ? inputValue : (this.isMultipleSelect ? this.currentValues : this.currentValue);\r\n return this.validator(value, this.args);\r\n }\r\n\r\n // by default the editor is almost always valid (except when it's required but not provided)\r\n if (isRequired && (elmValue === '' || (Array.isArray(elmValue) && elmValue.length === 0))) {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n\r\n //\r\n // protected functions\r\n // ------------------\r\n\r\n /**\r\n * user might want to filter certain items of the collection\r\n * @param inputCollection\r\n * @return outputCollection filtered and/or sorted collection\r\n */\r\n protected filterCollection(inputCollection) {\r\n let outputCollection = inputCollection;\r\n\r\n // user might want to filter certain items of the collection\r\n if (this.columnEditor && this.columnEditor.collectionFilterBy) {\r\n const filterBy = this.columnEditor.collectionFilterBy;\r\n const filterCollectionBy = this.columnEditor.collectionOptions && this.columnEditor.collectionOptions.filterResultAfterEachPass || null;\r\n outputCollection = this._collectionService.filterCollection(outputCollection, filterBy, filterCollectionBy);\r\n }\r\n\r\n return outputCollection;\r\n }\r\n\r\n /**\r\n * user might want to sort the collection in a certain way\r\n * @param inputCollection\r\n * @return outputCollection sorted collection\r\n */\r\n protected sortCollection(inputCollection) {\r\n let outputCollection = inputCollection;\r\n\r\n // user might want to sort the collection\r\n if (this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor.collectionSortBy) {\r\n const sortBy = this.columnDef.internalColumnEditor.collectionSortBy;\r\n outputCollection = this._collectionService.sortCollection(this.columnDef, outputCollection, sortBy, this.enableTranslateLabel);\r\n }\r\n\r\n return outputCollection;\r\n }\r\n\r\n protected renderDomElement(collection: any[]) {\r\n if (!Array.isArray(collection) && this.collectionOptions && this.collectionOptions.collectionInObjectProperty) {\r\n collection = getDescendantProperty(collection, this.collectionOptions.collectionInObjectProperty);\r\n }\r\n if (!Array.isArray(collection)) {\r\n throw new Error('The \"collection\" passed to the Select Editor is not a valid array');\r\n }\r\n\r\n // user can optionally add a blank entry at the beginning of the collection\r\n if (this.collectionOptions && this.collectionOptions.addBlankEntry) {\r\n collection.unshift(this.createBlankEntry());\r\n }\r\n\r\n let newCollection = collection || [];\r\n\r\n // user might want to filter and/or sort certain items of the collection\r\n newCollection = this.filterCollection(newCollection);\r\n newCollection = this.sortCollection(newCollection);\r\n\r\n // step 1, create HTML string template\r\n const editorTemplate = this.buildTemplateHtmlString(newCollection);\r\n\r\n // step 2, create the DOM Element of the editor\r\n // also subscribe to the onClose event\r\n this.createDomElement(editorTemplate);\r\n }\r\n\r\n protected buildTemplateHtmlString(collection: any[]) {\r\n let options = '';\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const separatorBetweenLabels = this.collectionOptions && this.collectionOptions.separatorBetweenTextLabels || '';\r\n const isRenderHtmlEnabled = this.columnDef.internalColumnEditor.enableRenderHtml || false;\r\n const sanitizedOptions = this.gridOptions && this.gridOptions.sanitizeHtmlOptions || {};\r\n\r\n // collection could be an Array of Strings OR Objects\r\n if (collection.every(x => typeof x === 'string')) {\r\n collection.forEach((option: string) => {\r\n options += `<option value=\"${option}\" label=\"${option}\">${option}</option>`;\r\n });\r\n } else {\r\n // array of objects will require a label/value pair unless a customStructure is passed\r\n collection.forEach((option: SelectOption) => {\r\n if (!option || (option[this.labelName] === undefined && option.labelKey === undefined)) {\r\n throw new Error(`[select-editor] A collection with value/label (or value/labelKey when using Locale) is required to populate the Select list, for example: { collection: [ { value: '1', label: 'One' } ])`);\r\n }\r\n const labelKey = (option.labelKey || option[this.labelName]) as string;\r\n const labelText = ((option.labelKey || this.enableTranslateLabel) && labelKey) ? this._translate.instant(labelKey || ' ') : labelKey;\r\n let prefixText = option[this.labelPrefixName] || '';\r\n let suffixText = option[this.labelSuffixName] || '';\r\n let optionLabel = option[this.optionLabel] || '';\r\n optionLabel = optionLabel.toString().replace(/\\\"/g, '\\''); // replace double quotes by single quotes to avoid interfering with regular html\r\n\r\n // also translate prefix/suffix if enableTranslateLabel is true and text is a string\r\n prefixText = (this.enableTranslateLabel && prefixText && typeof prefixText === 'string') ? this._translate.instant(prefixText || ' ') : prefixText;\r\n suffixText = (this.enableTranslateLabel && suffixText && typeof suffixText === 'string') ? this._translate.instant(suffixText || ' ') : suffixText;\r\n optionLabel = (this.enableTranslateLabel && optionLabel && typeof optionLabel === 'string') ? this._translate.instant(optionLabel || ' ') : optionLabel;\r\n\r\n // add to a temp array for joining purpose and filter out empty text\r\n const tmpOptionArray = [prefixText, labelText, suffixText].filter((text) => text);\r\n let optionText = tmpOptionArray.join(separatorBetweenLabels);\r\n\r\n // if user specifically wants to render html text, he needs to opt-in else it will stripped out by default\r\n // also, the 3rd party lib will saninitze any html code unless it's encoded, so we'll do that\r\n if (isRenderHtmlEnabled) {\r\n // sanitize any unauthorized html tags like script and others\r\n // for the remaining allowed tags we'll permit all attributes\r\n const sanitizedText = DOMPurify.sanitize(optionText, sanitizedOptions);\r\n optionText = htmlEncode(sanitizedText);\r\n }\r\n\r\n options += `<option value=\"${option[this.valueName]}\" label=\"${optionLabel}\">${optionText}</option>`;\r\n });\r\n }\r\n\r\n return `<select id=\"${this.elementName}\" class=\"ms-filter search-filter editor-${fieldId}\" ${this.isMultipleSelect ? 'multiple=\"multiple\"' : ''}>${options}</select>`;\r\n }\r\n\r\n /** Create a blank entry that can be added to the collection. It will also reuse the same customStructure if need be */\r\n protected createBlankEntry() {\r\n const blankEntry = {\r\n [this.labelName]: '',\r\n [this.valueName]: ''\r\n };\r\n if (this.labelPrefixName) {\r\n blankEntry[this.labelPrefixName] = '';\r\n }\r\n if (this.labelSuffixName) {\r\n blankEntry[this.labelSuffixName] = '';\r\n }\r\n return blankEntry;\r\n }\r\n\r\n /** Build the template HTML string */\r\n protected createDomElement(editorTemplate: string) {\r\n this.$editorElm = $(editorTemplate);\r\n\r\n if (this.$editorElm && typeof this.$editorElm.appendTo === 'function') {\r\n this.$editorElm.appendTo(this.args.container);\r\n }\r\n\r\n if (typeof this.$editorElm.multipleSelect !== 'function') {\r\n // fallback to bootstrap\r\n this.$editorElm.addClass('form-control');\r\n } else {\r\n const elementOptions = (this.columnDef.internalColumnEditor) ? this.columnDef.internalColumnEditor.elementOptions : {};\r\n this.editorElmOptions = { ...this.defaultOptions, ...elementOptions };\r\n this.$editorElm = this.$editorElm.multipleSelect(this.editorElmOptions);\r\n setTimeout(() => {\r\n if (this.$editorElm && typeof this.$editorElm.multipleSelect === 'function') {\r\n this.$editorElm.multipleSelect('open');\r\n }\r\n });\r\n }\r\n }\r\n\r\n // refresh the jquery object because the selected checkboxes were already set\r\n // prior to this method being called\r\n protected refresh() {\r\n if (typeof this.$editorElm.multipleSelect === 'function') {\r\n this.$editorElm.multipleSelect('refresh');\r\n }\r\n }\r\n}\r\n","import { SelectEditor } from './selectEditor';\r\n\r\nexport class MultipleSelectEditor extends SelectEditor {\r\n /**\r\n * Initialize the Editor\r\n */\r\n constructor(protected args: any) {\r\n super(args, true);\r\n }\r\n}\r\n","import { SelectEditor } from './selectEditor';\r\n\r\nexport class SingleSelectEditor extends SelectEditor {\r\n /**\r\n * Initialize the Editor\r\n */\r\n constructor(protected args: any) {\r\n super(args, false);\r\n }\r\n}\r\n","import { Constants } from '../constants';\r\nimport { Column, Editor, EditorValidator, EditorValidatorOutput, KeyCode, ColumnEditor } from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\nconst DEFAULT_MIN_VALUE = 0;\r\nconst DEFAULT_MAX_VALUE = 100;\r\nconst DEFAULT_STEP = 1;\r\n\r\nexport class SliderEditor implements Editor {\r\n private _lastInputEvent: KeyboardEvent;\r\n private _elementRangeInputId: string;\r\n private _elementRangeOutputId: string;\r\n $editorElm: any;\r\n $input: any;\r\n $sliderNumber: any;\r\n defaultValue: any;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n /** Getter for the Editor Generic Params */\r\n private get editorParams(): any {\r\n return this.columnEditor.params || {};\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init(): void {\r\n const container = this.args && this.args.container;\r\n\r\n // define the input & slider number IDs\r\n const itemId = this.args && this.args.item && this.args.item.id;\r\n this._elementRangeInputId = `rangeInput_${this.columnDef.field}_${itemId}`;\r\n this._elementRangeOutputId = `rangeOutput_${this.columnDef.field}_${itemId}`;\r\n\r\n // create HTML string template\r\n const editorTemplate = this.buildTemplateHtmlString();\r\n this.$editorElm = $(editorTemplate);\r\n this.$input = this.$editorElm.children('input');\r\n this.$sliderNumber = this.$editorElm.children('div.input-group-addon.input-group-append').children();\r\n\r\n // watch on change event\r\n this.$editorElm\r\n .appendTo(container)\r\n .on('mouseup', () => this.save());\r\n\r\n // if user chose to display the slider number on the right side, then update it every time it changes\r\n // we need to use both \"input\" and \"change\" event to be all cross-browser\r\n if (!this.editorParams.hideSliderNumber) {\r\n this.$editorElm.on('input change', (event: KeyboardEvent & { target: HTMLInputElement }) => {\r\n this._lastInputEvent = event;\r\n const value = event && event.target && event.target.value || '';\r\n if (value) {\r\n document.getElementById(this._elementRangeOutputId).innerHTML = event.target.value;\r\n }\r\n });\r\n }\r\n }\r\n\r\n destroy() {\r\n this.$editorElm.off('input change mouseup').remove();\r\n }\r\n\r\n focus() {\r\n this.$editorElm.focus();\r\n }\r\n\r\n save() {\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.args.grid.getOptions().autoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n }\r\n\r\n cancel() {\r\n this.$input.val(this.defaultValue);\r\n this.args.cancelChanges();\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultValue = item[fieldNameFromComplexObject || fieldName];\r\n this.$input.val(this.defaultValue);\r\n this.$input[0].defaultValue = this.defaultValue;\r\n this.$sliderNumber.html(this.defaultValue);\r\n }\r\n }\r\n\r\n serializeValue() {\r\n return parseInt(this.$input.val() as string, 10) || 0;\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(state);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';\r\n }\r\n\r\n isValueChanged() {\r\n const elmValue = this.$input.val();\r\n const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;\r\n if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {\r\n return true;\r\n }\r\n return (!(elmValue === '' && this.defaultValue === null)) && (elmValue !== this.defaultValue);\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();\r\n const isRequired = this.columnEditor.required;\r\n const minValue = this.columnEditor.minValue;\r\n const maxValue = this.columnEditor.maxValue;\r\n const errorMsg = this.columnEditor.errorMessage;\r\n const mapValidation = {\r\n '{{minValue}}': minValue,\r\n '{{maxValue}}': maxValue\r\n };\r\n\r\n if (this.validator) {\r\n return this.validator(elmValue, this.args);\r\n } else if (isRequired && elmValue === '') {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n } else if (minValue !== undefined && (elmValue < minValue || elmValue > maxValue)) {\r\n // when decimal value is bigger than 0, we only accept the decimal values as that value set\r\n // for example if we set decimalPlaces to 2, we will only accept numbers between 0 and 2 decimals\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_EDITOR_NUMBER_BETWEEN.replace(/{{minValue}}|{{maxValue}}/gi, (matched) => {\r\n return mapValidation[matched];\r\n })\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n\r\n /**\r\n * Create the HTML template as a string\r\n */\r\n private buildTemplateHtmlString() {\r\n const fieldId = this.columnDef && this.columnDef.id;\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n const minValue = this.columnEditor.hasOwnProperty('minValue') ? this.columnEditor.minValue : DEFAULT_MIN_VALUE;\r\n const maxValue = this.columnEditor.hasOwnProperty('maxValue') ? this.columnEditor.maxValue : DEFAULT_MAX_VALUE;\r\n const defaultValue = this.editorParams.hasOwnProperty('sliderStartValue') ? this.editorParams.sliderStartValue : minValue;\r\n const step = this.columnEditor.hasOwnProperty('valueStep') ? this.columnEditor.valueStep : DEFAULT_STEP;\r\n\r\n if (this.editorParams.hideSliderNumber) {\r\n return `\r\n <div class=\"slider-editor\">\r\n <input type=\"range\" id=\"${this._elementRangeInputId}\"\r\n name=\"${this._elementRangeInputId}\"\r\n title=\"${title}\"\r\n defaultValue=\"${defaultValue}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${step}\"\r\n class=\"form-control slider-editor-input editor-${fieldId} range\" />\r\n </div>`;\r\n }\r\n\r\n return `\r\n <div class=\"input-group slider-editor\">\r\n <input type=\"range\" id=\"${this._elementRangeInputId}\"\r\n name=\"${this._elementRangeInputId}\"\r\n title=\"${title}\"\r\n defaultValue=\"${defaultValue}\" min=\"${minValue}\" max=\"${maxValue}\" step=\"${step}\"\r\n class=\"form-control slider-editor-input editor-${fieldId} range\" />\r\n <div class=\"input-group-addon input-group-append slider-value\"><span class=\"input-group-text\" id=\"${this._elementRangeOutputId}\">${defaultValue}</span></div>\r\n </div>`;\r\n }\r\n}\r\n","import { Constants } from '../constants';\r\nimport { Column, ColumnEditor, Editor, EditorValidator, EditorValidatorOutput, KeyCode } from './../models/index';\r\n\r\n// using external non-typed js libraries\r\ndeclare var $: any;\r\n\r\n/*\r\n * An example of a 'detached' editor.\r\n * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.\r\n */\r\nexport class TextEditor implements Editor {\r\n private _lastInputEvent: KeyboardEvent;\r\n $input: any;\r\n defaultValue: any;\r\n\r\n constructor(private args: any) {\r\n this.init();\r\n }\r\n\r\n /** Get Column Definition object */\r\n get columnDef(): Column {\r\n return this.args && this.args.column || {};\r\n }\r\n\r\n /** Get Column Editor object */\r\n get columnEditor(): ColumnEditor {\r\n return this.columnDef && this.columnDef.internalColumnEditor && this.columnDef.internalColumnEditor || {};\r\n }\r\n\r\n get hasAutoCommitEdit() {\r\n return this.args.grid.getOptions().autoCommitEdit;\r\n }\r\n\r\n /** Get the Validator function, can be passed in Editor property or Column Definition */\r\n get validator(): EditorValidator {\r\n return this.columnEditor.validator || this.columnDef.validator;\r\n }\r\n\r\n init(): void {\r\n const columnId = this.columnDef && this.columnDef.id;\r\n const placeholder = this.columnEditor && this.columnEditor.placeholder || '';\r\n const title = this.columnEditor && this.columnEditor.title || '';\r\n\r\n this.$input = $(`<input type=\"text\" role=\"presentation\" autocomplete=\"off\" class=\"editor-text editor-${columnId}\" placeholder=\"${placeholder}\" title=\"${title}\" />`)\r\n .appendTo(this.args.container)\r\n .on('keydown.nav', (event: KeyboardEvent) => {\r\n this._lastInputEvent = event;\r\n if (event.keyCode === KeyCode.LEFT || event.keyCode === KeyCode.RIGHT) {\r\n event.stopImmediatePropagation();\r\n }\r\n });\r\n\r\n // the lib does not get the focus out event for some reason\r\n // so register it here\r\n if (this.hasAutoCommitEdit) {\r\n this.$input.on('focusout', () => this.save());\r\n }\r\n\r\n setTimeout(() => {\r\n this.$input.focus().select();\r\n }, 50);\r\n }\r\n\r\n destroy() {\r\n this.$input.off('keydown.nav focusout').remove();\r\n }\r\n\r\n focus() {\r\n this.$input.focus();\r\n }\r\n\r\n getValue() {\r\n return this.$input.val();\r\n }\r\n\r\n setValue(val: string) {\r\n this.$input.val(val);\r\n }\r\n\r\n loadValue(item: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n\r\n if (item && this.columnDef && (item.hasOwnProperty(fieldName) || item.hasOwnProperty(fieldNameFromComplexObject))) {\r\n this.defaultValue = item[fieldNameFromComplexObject || fieldName] || '';\r\n this.$input.val(this.defaultValue);\r\n this.$input[0].defaultValue = this.defaultValue;\r\n this.$input.select();\r\n }\r\n }\r\n\r\n serializeValue() {\r\n return this.$input.val();\r\n }\r\n\r\n applyValue(item: any, state: any) {\r\n const fieldName = this.columnDef && this.columnDef.field;\r\n // when it's a complex object, then pull the object name only, e.g.: \"user.firstName\" => \"user\"\r\n const fieldNameFromComplexObject = fieldName.indexOf('.') ? fieldName.substring(0, fieldName.indexOf('.')) : '';\r\n const validation = this.validate(state);\r\n item[fieldNameFromComplexObject || fieldName] = (validation && validation.valid) ? state : '';\r\n }\r\n\r\n isValueChanged() {\r\n const lastEvent = this._lastInputEvent && this._lastInputEvent.keyCode;\r\n if (this.columnEditor && this.columnEditor.alwaysSaveOnEnterKey && lastEvent === KeyCode.ENTER) {\r\n return true;\r\n }\r\n return (!(this.$input.val() === '' && this.defaultValue === null)) && (this.$input.val() !== this.defaultValue);\r\n }\r\n\r\n save() {\r\n const validation = this.validate();\r\n if (validation && validation.valid) {\r\n if (this.hasAutoCommitEdit) {\r\n this.args.grid.getEditorLock().commitCurrentEdit();\r\n } else {\r\n this.args.commitChanges();\r\n }\r\n }\r\n }\r\n\r\n validate(inputValue?: any): EditorValidatorOutput {\r\n const isRequired = this.columnEditor.required;\r\n const elmValue = (inputValue !== undefined) ? inputValue : this.$input && this.$input.val && this.$input.val();\r\n const errorMsg = this.columnEditor.errorMessage;\r\n\r\n if (this.validator) {\r\n const value = this.$input && this.$input.val && this.$input.val();\r\n return this.validator(value, this.args);\r\n }\r\n\r\n // by default the editor is almost always valid (except when it's required but not provided)\r\n if (isRequired && elmValue === '') {\r\n return {\r\n valid: false,\r\n msg: errorMsg || Constants.VALIDATION_REQUIRED_FIELD\r\n };\r\n }\r\n\r\n return {\r\n valid: true,\r\n msg: null\r\n };\r\n }\r\n}\r\n","import { AutoCompleteEditor } from './autoCompleteEditor';\r\nimport { CheckboxEditor } from './checkboxEditor';\r\nimport { DateEditor } from './dateEditor';\r\nimport { FloatEditor } from './floatEditor';\r\nimport { IntegerEditor } from './integerEditor';\r\nimport { LongTextEditor } from './longTextEditor';\r\nimport { MultipleSelectEditor } from './multipleSelectEditor';\r\nimport { SingleSelectEditor } from './singleSelectEditor';\r\nimport { SliderEditor } from './sliderEditor';\r\nimport { TextEditor } from './textEditor';\r\n\r\nexport const Editors = {\r\n /** AutoComplete Editor (using jQuery UI autocomplete feature) */\r\n autoComplete: AutoCompleteEditor,\r\n\r\n /** Checkbox Editor (uses native checkbox DOM element) */\r\n checkbox: CheckboxEditor,\r\n\r\n /** Date Picker Editor (which uses 3rd party lib \"flatpickr\") */\r\n date: DateEditor,\r\n\r\n /** Float Number Editor */\r\n float: FloatEditor,\r\n\r\n /** Integer Editor */\r\n integer: IntegerEditor,\r\n\r\n /** Long Text Editor (uses a textarea) */\r\n longText: LongTextEditor,\r\n\r\n /** Multiple Select editor (which uses 3rd party lib \"multiple-select.js\") */\r\n multipleSelect: MultipleSelectEditor,\r\n\r\n /** Single Select editor (which uses 3rd party lib \"multiple-select.js\") */\r\n singleSelect: SingleSelectEditor,\r\n\r\n /** Slider Editor */\r\n slider: SliderEditor,\r\n\r\n /** Text Editor */\r\n text: TextEditor\r\n};\r\n","import { Column, FieldType, Formatter, GridOption } from '../models/index';\nimport { mapMomentDateFormatWithFieldType } from '../services/utilities';\nimport * as moment_ from 'moment-mini';\nconst moment = moment_; // patch to fix rollup \"moment has no default export\" issue, document here https://github.com/rollup/rollup/issues/670\n\n/**\n * Find the option value from the following (in order of execution)\n * 1- Column Definition \"params\"\n * 2- Grid Options \"formatterOptions\"\n * 3- nothing found, return default value provided\n */\nexport function getValueFromParamsOrGridOptions(optionName: string, columnDef: Column, grid: any, defaultValue?: any) {\n const gridOptions = ((grid && typeof grid.getOptions === 'function') ? grid.getOptions() : {}) as GridOption;\n const params = columnDef && columnDef.params;\n\n if (params && params.hasOwnProperty(optionName)) {\n return params[optionName];\n } else if (gridOptions.formatterOptions && gridOptions.formatterOptions.hasOwnProperty(optionName)) {\n return gridOptions.formatterOptions[optionName];\n }\n return defaultValue;\n}\n\n/** From a FieldType, return the associated date Formatter */\nexport function getAssociatedDateFormatter(fieldType: FieldType, defaultSeparator: string): Formatter {\n const defaultDateFormat = mapMomentDateFormatWithFieldType(fieldType);\n\n return (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\n const gridOptions = ((grid && typeof grid.getOptions === 'function') ? grid.getOptions() : {}) as GridOption;\n const customSeparator = gridOptions && gridOptions.formatterOptions && gridOptions.formatterOptions.dateSeparator || defaultSeparator;\n\n const isDateValid = moment(value, defaultDateFormat, false).isValid();\n let outputDate = (value && isDateValid) ? moment(value).format(defaultDateFormat) : value;\n\n // user can customize the separator through the \"formatterOptions\"\n // if that is the case we need to replace the default \"/\" to the new separator\n if (outputDate && customSeparator !== defaultSeparator) {\n const regex = new RegExp(defaultSeparator, 'ig'); // find separator globally\n outputDate = outputDate.replace(regex, customSeparator);\n }\n\n return outputDate;\n };\n}\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\n\r\nexport const arrayObjectToCsvFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\r\n const columnParams = columnDef && columnDef.params || {};\r\n const propertyNames = columnParams.propertyNames;\r\n let parentObjectKeyName = columnParams.dataContextProperty;\r\n if (!parentObjectKeyName) {\r\n parentObjectKeyName = columnDef && columnDef.field && columnDef.field.split('.')[0]; // e.g. \"users.roles\" would be \"users\"\r\n }\r\n\r\n if (!propertyNames || !Array.isArray(propertyNames) || !parentObjectKeyName) {\r\n throw new Error(`Formatters.arrayObjectToCsv requires you to pass an array of \"propertyNames\" (declared in \"params\") that you want to pull the data from.\r\n For example, if we have an array of user objects that have the property of firstName & lastName then we need to pass in your column definition:: { params: { propertyNames: ['firtName'] }}.\r\n Optionally, you can also pass the \"dataContextProperty\" if you wish to run this on another completely different field of the dataContext object.`);\r\n }\r\n\r\n // the dataContext holds all the data, so we can find the values we want even when \"value\" argument might be null\r\n // e.g. if we want to use the propertyNames of ['firstName', 'lastName'] from the \"users\" array of objects\r\n if (dataContext[parentObjectKeyName] && Array.isArray(dataContext[parentObjectKeyName])) {\r\n // we will 1st get the object from the dataContext, then\r\n if (Array.isArray(dataContext[parentObjectKeyName]) && dataContext[parentObjectKeyName].length > 0) {\r\n const outputStrings = [];\r\n dataContext[parentObjectKeyName].forEach((data: any) => {\r\n const strings = [];\r\n\r\n // 2nd from that data loop through all propertyNames we want to use (e.g.: ['firstName', 'lastName'])\r\n propertyNames.forEach((prop) => {\r\n strings.push(data[prop]);\r\n });\r\n // we will join these strings with spaces (e.g. 'John Doe' where 'John' was firstName and 'Doe' was lastName)\r\n outputStrings.push(strings.join(' '));\r\n });\r\n\r\n // finally join all the output strings by CSV (e.g.: 'John Doe, Jane Doe')\r\n const output = outputStrings.join(', ');\r\n return `<span title=\"${output}\">${output}</span>`;\r\n }\r\n }\r\n return value;\r\n};\r\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\n\nexport const arrayToCsvFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\n if (value && Array.isArray(value) && value.length > 0) {\n const values = value.join(', ');\n return `<span title=\"${values}\">${values}</span>`;\n }\n return value;\n};\n","import { Column, Formatter } from './../models/index';\n\nexport const boldFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\n return value ? `<b>${value}</b>` : '';\n};\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\n\r\nexport const checkboxFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) =>\r\n value ? '&#x2611;' : '';\r\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\nimport { parseBoolean } from '../services/utilities';\r\n\r\nexport const checkmarkFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\r\n return parseBoolean(value) ? `<i class=\"fa fa-check checkmark-icon\" aria-hidden=\"true\"></i>` : '';\r\n}\r\n","import { arrayToCsvFormatter } from './arrayToCsvFormatter';\r\nimport { Column, Formatter } from './../models/index';\r\nimport { findOrDefault } from '../services/utilities';\r\n\r\n/**\r\n * A formatter to show the label property value of a params collection\r\n */\r\nexport const collectionFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\r\n if (!value || !columnDef || !columnDef.params || !columnDef.params.collection\r\n || !columnDef.params.collection.length) {\r\n return value;\r\n }\r\n\r\n const { params, params: { collection } } = columnDef;\r\n const labelName = (params.customStructure) ? params.customStructure.label : 'label';\r\n const valueName = (params.customStructure) ? params.customStructure.value : 'value';\r\n\r\n if (Array.isArray(value)) {\r\n return arrayToCsvFormatter(row,\r\n cell,\r\n value.map((v: any) => findOrDefault(collection, (c: any) => c[valueName] === v)[labelName]),\r\n columnDef,\r\n dataContext);\r\n }\r\n\r\n return findOrDefault(collection, (c: any) => c[valueName] === value)[labelName] || '';\r\n};\r\n","import { arrayToCsvFormatter } from './arrayToCsvFormatter';\r\nimport { Column, Formatter } from './../models/index';\r\nimport { findOrDefault } from '../services/utilities';\r\n\r\n/**\r\n * A formatter to show the label property value of an editor collection\r\n */\r\nexport const collectionEditorFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\r\n if (!value || !columnDef || !columnDef.internalColumnEditor || !columnDef.internalColumnEditor.collection\r\n || !columnDef.internalColumnEditor.collection.length) {\r\n return value;\r\n }\r\n\r\n const { internalColumnEditor, internalColumnEditor: { collection } } = columnDef;\r\n const labelName = (internalColumnEditor.customStructure) ? internalColumnEditor.customStructure.label : 'label';\r\n const valueName = (internalColumnEditor.customStructure) ? internalColumnEditor.customStructure.value : 'value';\r\n\r\n if (Array.isArray(value)) {\r\n if (collection.every(x => typeof x === 'string')) {\r\n return arrayToCsvFormatter(row,\r\n cell,\r\n value.map((v: any) => findOrDefault(collection, (c: any) => c === v)),\r\n columnDef,\r\n dataContext);\r\n } else {\r\n return arrayToCsvFormatter(row,\r\n cell,\r\n value.map((v: any) => findOrDefault(collection, (c: any) => c[valueName] === v)[labelName]),\r\n columnDef,\r\n dataContext);\r\n }\r\n }\r\n\r\n return findOrDefault(collection, (c: any) => c[valueName] === value)[labelName] || '';\r\n};\r\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\n\nexport const complexObjectFormatter: Formatter = (row: number, cell: number, cellValue: any, columnDef: Column, dataContext: any) => {\n if (!columnDef) {\n return '';\n }\n\n const columnParams = columnDef.params || {};\n const complexFieldLabel = columnParams && columnParams.complexFieldLabel || columnDef.field;\n\n if (!complexFieldLabel) {\n throw new Error(`For the Formatters.complexObject to work properly, you need to tell it which property of the complex object to use.\n There are 3 ways to provide it:\n 1- via the generic \"params\" with a \"complexFieldLabel\" property on your Column Definition, example: this.columnDefs = [{ id: 'user', field: 'user', params: { complexFieldLabel: 'user.firstName' } }]\n 2- via the generic \"params\" with a \"complexFieldLabel\" and a \"labelKey\" property on your Column Definition, example: this.columnDefs = [{ id: 'user', field: 'user', labelKey: 'firstName' params: { complexFieldLabel: 'user' } }]\n 3- via the field name that includes a dot notation, example: this.columnDefs = [{ id: 'user', field: 'user.firstName'}] `);\n }\n\n if (columnDef.labelKey && dataContext.hasOwnProperty(complexFieldLabel)) {\n return dataContext[complexFieldLabel] && dataContext[complexFieldLabel][columnDef.labelKey];\n }\n\n // when complexFieldLabel includes the dot \".\", we will do the split and get the value from the complex object\n // however we also need to make sure that the complex objet exist, else we'll return the cell value (original value)\n if (typeof complexFieldLabel === 'string' && complexFieldLabel.indexOf('.') > 0) {\n return complexFieldLabel.split('.').reduce((obj, i) => (obj && obj.hasOwnProperty(i) ? obj[i] : cellValue), dataContext);\n }\n return cellValue;\n};\n","import { Column, Formatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const decimalFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const params = columnDef.params || {};\r\n let minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n let maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 2);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n // @deprecated: decimalPlaces, minDecimalPlaces, maxDecimalPlaces\r\n // add these extra checks to support previous way of passing the decimal count\r\n if ((params.minDecimalPlaces !== null && params.minDecimalPlaces) || (params.decimalPlaces !== null && params.decimalPlaces)) {\r\n minDecimal = (params.minDecimalPlaces !== null && params.minDecimalPlaces) || (params.decimalPlaces !== null && params.decimalPlaces);\r\n }\r\n if (params.maxDecimalPlaces !== null && params.maxDecimalPlaces) {\r\n maxDecimal = (params.maxDecimalPlaces !== null && params.maxDecimalPlaces);\r\n }\r\n\r\n if (isNumber) {\r\n return formatNumber(value, minDecimal, maxDecimal, displayNegativeNumberWithParentheses);\r\n }\r\n return value;\r\n};\r\n\r\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\n\r\nexport const deleteIconFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) =>\r\n `<i class=\"fa fa-trash pointer delete-icon\" aria-hidden=\"true\"></i>`;\r\n","import { Column, Formatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const dollarColoredBoldFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (isNumber) {\r\n const colorStyle = (value >= 0) ? 'green' : 'red';\r\n const formattedNumber = formatNumber(value, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `<span style=\"color:${colorStyle}; font-weight:bold;\">${formattedNumber}</span>`;\r\n }\r\n return value;\r\n};\r\n","import { Column, Formatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const dollarColoredFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (isNumber) {\r\n const colorStyle = (value >= 0) ? 'green' : 'red';\r\n const formattedNumber = formatNumber(value, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `<span style=\"color:${colorStyle}\">${formattedNumber}</span>`;\r\n }\r\n return value;\r\n};\r\n","import { Column, Formatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const dollarFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (isNumber) {\r\n return formatNumber(value, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n }\r\n return value;\r\n};\r\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\n\r\nexport const editIconFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) =>\r\n `<i class=\"fa fa-pencil pointer edit-icon\" aria-hidden=\"true\"></i>`;\r\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\nimport * as DOMPurify_ from 'dompurify';\nconst DOMPurify = DOMPurify_; // patch to fix rollup to work\n\n/**\n * Takes an hyperlink cell value and transforms it into a real hyperlink, given that the value starts with 1 of these (http|ftp|https).\n * The structure will be \"<a href=\"hyperlink\">hyperlink</a>\"\n *\n * You can optionally change the hyperlink text displayed by using the generic params \"hyperlinkText\" in the column definition\n * For example: { id: 'link', field: 'link', params: { hyperlinkText: 'Company Website' } } will display \"<a href=\"link\">Company Website</a>\"\n *\n * You can also optionally provide the hyperlink URL by using the generic params \"hyperlinkUrl\" in the column definition\n * For example: { id: 'link', field: 'link', params: { hyperlinkText: 'Company Website', hyperlinkUrl: 'http://www.somewhere.com' } } will display \"<a href=\"http://www.somewhere.com\">Company Website</a>\"\n */\nexport const hyperlinkFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\n const columnParams = columnDef && columnDef.params || {};\n\n let displayedText = columnParams.hyperlinkText ? columnParams.hyperlinkText : value;\n displayedText = DOMPurify.sanitize(displayedText || '');\n\n let outputLink = columnParams.hyperlinkUrl ? columnParams.hyperlinkUrl : value;\n outputLink = DOMPurify.sanitize(outputLink || '');\n\n const matchUrl = outputLink.match(/^(http|ftp|https):\\/\\/[\\w\\-_]+(\\.[\\w\\-_]+)+([\\w\\-\\.,@?^=%&amp;:\\/~\\+#]*[\\w\\-\\@?^=%&amp;\\/~\\+#])?/i);\n\n if (matchUrl && Array.isArray(matchUrl) && matchUrl.length > 0) {\n const finalUrl = matchUrl[0];\n return `<a href=\"${finalUrl}\">${displayedText}</a>`;\n }\n\n return value;\n};\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\n\nexport const iconFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\n const columnParams = columnDef && columnDef.params || {};\n const icon = columnParams.icon || columnParams.formatterIcon;\n\n if (!icon) {\n throw new Error(`You must provide the \"icon\" or \"formatterIcon\" via the generic \"params\" options (e.g.: { formatter: Formatters.icon, params: { formatterIcon: 'fa fa-search' }}`);\n }\n return `<i class=\"${icon}\" aria-hidden=\"true\"></i>`;\n};\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\n\r\nexport const infoIconFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) =>\r\n `<i class=\"fa fa-info-circle pointer info-icon\" aria-hidden=\"true\"></i>`;\r\n","import { Column, Formatter } from './../models/index';\r\n\r\nexport const italicFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\r\n return value ? `<i>${value}</i>` : '';\r\n};\r\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\n\nexport const lowercaseFormatter: Formatter = (row: number, cell: number, value: string | any, columnDef: Column, dataContext: any): string => {\n // make sure the value is a string\n if (value !== undefined && typeof value !== 'string') {\n value = value + '';\n }\n return value ? value.toLowerCase() : '';\n};\n","\r\nimport { Column, Formatter } from './../models/index';\r\n\r\n/**\r\n * Takes a value display it according to a mask provided\r\n * e.: 1234567890 with mask \"(000) 000-0000\" will display \"(123) 456-7890\"\r\n */\r\nexport const maskFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any) => {\r\n const params = columnDef.params || {};\r\n const mask = params.mask;\r\n\r\n if (!mask) {\r\n throw new Error(`You must provide a \"mask\" via the generic \"params\" options (e.g.: { formatter: Formatters.mask, params: { mask: '000-000' }}`);\r\n }\r\n\r\n if (value) {\r\n let i = 0;\r\n const v = value.toString();\r\n return mask.replace(/[09A]/gi, () => v[i++] || '');\r\n }\r\n return value;\r\n};\r\n","import { Column, Formatter } from './../models/index';\r\n\r\nexport const multipleFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\r\n const params = columnDef.params || {};\r\n if (!params.formatters || !Array.isArray(params.formatters)) {\r\n throw new Error(`The multiple formatter requires the \"formatters\" to be provided as a column params.\r\n For example: this.columnDefinitions = [{ id: title, field: title, formatter: Formatters.multiple, params: { formatters: [Formatters.lowercase, Formatters.uppercase] }`);\r\n }\r\n const formatters: Formatter[] = params.formatters;\r\n\r\n // loop through all Formatters, the value of 1st formatter will be used by 2nd formatter and so on.\r\n // they are piped and executed in sequences\r\n let currentValue = value;\r\n for (const formatter of formatters) {\r\n currentValue = formatter(row, cell, currentValue, columnDef, dataContext, grid);\r\n }\r\n return currentValue;\r\n};\r\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const percentFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any): string => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (isNumber) {\r\n const percentValue = value * 100;\r\n return formatNumber(percentValue, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '', '%');\r\n }\r\n return value;\r\n};\r\n","import { Column, Formatter } from './../models/index';\n\nexport const percentCompleteBarFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any): string => {\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\n if (!isNumber) {\n return '';\n }\n\n let color = '';\n let inputNumber = parseFloat(value);\n if (inputNumber > 100) {\n inputNumber = 100;\n }\n\n if (inputNumber < 30) {\n color = 'red';\n } else if (inputNumber < 70) {\n color = 'silver';\n } else {\n color = 'green';\n }\n\n return `<span class=\"percent-complete-bar\" style=\"background:${color}; width:${inputNumber}%\"></span>`;\n};\n","import { Column, Formatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const percentCompleteFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any): string => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (isNumber) {\r\n const colorStyle = (value < 50) ? 'red' : 'green';\r\n const formattedNumber = formatNumber(value, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '', '%');\r\n const outputFormattedValue = value > 100 ? '100%' : formattedNumber;\r\n return `<span style='color:${colorStyle}'>${outputFormattedValue}</span>`;\r\n }\r\n return value;\r\n};\r\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from './formatterUtilities';\r\n\r\nexport const percentSymbolFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any): string => {\r\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (isNumber) {\r\n return formatNumber(value, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '', '%');\r\n }\r\n return value;\r\n};\r\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\n\nexport const progressBarFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any): string => {\n const isNumber = (value === null || value === undefined || value === '') ? false : !isNaN(+value);\n if (!isNumber) {\n return '';\n }\n\n let color = '';\n let inputNumber = parseFloat(value);\n if (inputNumber > 100) {\n inputNumber = 100;\n }\n\n if (inputNumber < 30) {\n color = 'danger';\n } else if (inputNumber < 70) {\n color = 'warning';\n } else {\n color = 'success';\n }\n\n const output = `<div class=\"progress\">\n <div class=\"progress-bar progress-bar-${color} bg-${color}\" role=\"progressbar\" aria-valuenow=\"${inputNumber}\" aria-valuemin=\"0\" aria-valuemax=\"100\" style=\"min-width: 2em; width: ${inputNumber}%;\">\n ${inputNumber}%\n </div>\n </div>`;\n\n return output.replace(/\\s{2,}/g, ' ').trim();\n};\n","import { Column, Formatter } from './../models/index';\n\n/** Takes a cell value and translates it with the \"ngx-translate\" service */\nexport const translateFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\n const gridOptions = (grid && typeof grid.getOptions === 'function') ? grid.getOptions() : {};\n const translate = gridOptions.i18n || (columnDef && columnDef.params && columnDef.params.i18n);\n\n if (!translate || typeof translate.instant !== 'function') {\n throw new Error(`The translate formatter requires the \"ngx-translate\" Service to be provided as a Grid Options or Column Definition \"i18n\".\n For example: this.gridOptions = { enableTranslate: true, i18n: this.translate }`);\n }\n\n // make sure the value is a string (for example a boolean value would throw an error)\n if (value !== undefined && value !== null && typeof value !== 'string') {\n value = value + '';\n }\n\n return value ? translate.instant(value) : '';\n};\n","import { Column, Formatter } from './../models/index';\n\n/** Takes a boolean value, cast it to upperCase string and finally translates it with the \"ngx-translate\" service */\nexport const translateBooleanFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any, grid: any) => {\n const gridOptions = (grid && typeof grid.getOptions === 'function') ? grid.getOptions() : {};\n const translate = gridOptions.i18n || (columnDef && columnDef.params && columnDef.params.i18n);\n\n if (!translate || typeof translate.instant !== 'function') {\n throw new Error(`The translate formatter requires the \"ngx-translate\" Service to be provided as a Grid Options or Column Definition \"i18n\".\n For example: this.gridOptions = { enableTranslate: true, i18n: this.translate }`);\n }\n\n // make sure the value is a string (for example a boolean value would throw an error)\n if (value !== undefined && value !== null && typeof value !== 'string') {\n value = value + '';\n }\n return value ? translate.instant(value.toUpperCase() as string) : '';\n};\n","import { Column } from './../models/column.interface';\nimport { Formatter } from './../models/formatter.interface';\n\nexport const uppercaseFormatter: Formatter = (row: number, cell: number, value: string | any, columnDef: Column, dataContext: any): string => {\n // make sure the value is a string\n if (value !== undefined && typeof value !== 'string') {\n value = value + '';\n }\n return value ? value.toUpperCase() : '';\n};\n","import { Column } from './../models/column.interface';\r\nimport { Formatter } from './../models/formatter.interface';\r\n\r\nexport const yesNoFormatter: Formatter = (row: number, cell: number, value: any, columnDef: Column, dataContext: any): string =>\r\n value ? 'Yes' : 'No';\r\n","import { FieldType } from '../models/index';\nimport { getAssociatedDateFormatter } from './formatterUtilities';\nimport { arrayObjectToCsvFormatter } from './arrayObjectToCsvFormatter';\nimport { arrayToCsvFormatter } from './arrayToCsvFormatter';\nimport { boldFormatter } from './boldFormatter';\nimport { checkboxFormatter } from './checkboxFormatter';\nimport { checkmarkFormatter } from './checkmarkFormatter';\nimport { collectionFormatter } from './collectionFormatter';\nimport { collectionEditorFormatter } from './collectionEditorFormatter';\nimport { complexObjectFormatter } from './complexObjectFormatter';\nimport { decimalFormatter } from './decimalFormatter';\nimport { deleteIconFormatter } from './deleteIconFormatter';\nimport { dollarColoredBoldFormatter } from './dollarColoredBoldFormatter';\nimport { dollarColoredFormatter } from './dollarColoredFormatter';\nimport { dollarFormatter } from './dollarFormatter';\nimport { editIconFormatter } from './editIconFormatter';\nimport { hyperlinkFormatter } from './hyperlinkFormatter';\nimport { iconFormatter } from './iconFormatter';\nimport { infoIconFormatter } from './infoIconFormatter';\nimport { italicFormatter } from './italicFormatter';\nimport { lowercaseFormatter } from './lowercaseFormatter';\nimport { maskFormatter } from './maskFormatter';\nimport { multipleFormatter } from './multipleFormatter';\nimport { percentFormatter } from './percentFormatter';\nimport { percentCompleteBarFormatter } from './percentCompleteBarFormatter';\nimport { percentCompleteFormatter } from './percentCompleteFormatter';\nimport { percentSymbolFormatter } from './percentSymbolFormatter';\nimport { progressBarFormatter } from './progressBarFormatter';\nimport { translateFormatter } from './translateFormatter';\nimport { translateBooleanFormatter } from './translateBooleanFormatter';\nimport { uppercaseFormatter } from './uppercaseFormatter';\nimport { yesNoFormatter } from './yesNoFormatter';\n\n/** Provides a list of different Formatters that will change the cell value displayed in the UI */\nexport const Formatters = {\n /**\n * Takes an array of complex objects converts it to a comma delimited string.\n * Requires to pass an array of \"propertyNames\" in the column definition the generic \"params\" property\n * For example, if we have an array of user objects that have the property of firstName & lastName then we need to pass in your column definition::\n * { params: { propertyNames: ['firtName'] }}\n */\n arrayObjectToCsv: arrayObjectToCsvFormatter,\n\n /** Takes an array of string and converts it to a comma delimited string */\n arrayToCsv: arrayToCsvFormatter,\n\n /** show value in bold font weight */\n bold: boldFormatter,\n\n /** When value is filled (true), it will display a checkbox Unicode icon */\n checkbox: checkboxFormatter,\n\n /** When value is filled (true), it will display a Font-Awesome icon (fa-check) */\n checkmark: checkmarkFormatter,\n\n /**\n * Takes a complex data object and return the data under that property (for example: \"user.firstName\" will return the first name \"John\")\n * You can pass the complex structure in the \"field\" or the \"params: { complexField: string }\" properties.\n * For example::\n * this.columnDefs = [{ id: 'username', field: 'user.firstName', ... }]\n * OR this.columnDefs = [{ id: 'username', field: 'user', params: { complexField: 'user.firstName' }, ... }]\n */\n complexObject: complexObjectFormatter,\n\n /**\n * Looks up values from the columnDefinition.params.collection property and displays the label in CSV or string format\n * @example\n * // the grid will display 'foo' and 'bar' and not 1 and 2 from your dataset\n * { params: { collection: [{ value: 1, label: 'foo'}, {value: 2, label: 'bar' }] }}\n * const dataset = [1, 2];\n */\n collection: collectionFormatter,\n\n /**\n * Roughly the same as the \"collectionFormatter\" except that it\n * looks up values from the columnDefinition.editor.collection (instead of params) property and displays the label in CSV or string format\n * @example\n * // the grid will display 'foo' and 'bar' and not 1 and 2 from your dataset\n * { editor: { collection: [{ value: 1, label: 'foo'}, {value: 2, label: 'bar' }] }}\n * const dataset = [1, 2];\n */\n collectionEditor: collectionEditorFormatter,\n\n /** Takes a Date object and displays it as an ISO Date format (YYYY-MM-DD) */\n dateIso: getAssociatedDateFormatter(FieldType.dateIso, '-'),\n\n /** Takes a Date object and displays it as an ISO Date+Time format (YYYY-MM-DD HH:mm:ss) */\n dateTimeIso: getAssociatedDateFormatter(FieldType.dateTimeIso, '-'),\n\n /** Takes a Date object and displays it as an ISO Date+Time (without seconds) format (YYYY-MM-DD HH:mm) */\n dateTimeShortIso: getAssociatedDateFormatter(FieldType.dateTimeShortIso, '-'),\n\n /** Takes a Date object and displays it as an ISO Date+Time+(am/pm) format (YYYY-MM-DD h:mm:ss a) */\n dateTimeIsoAmPm: getAssociatedDateFormatter(FieldType.dateTimeIsoAmPm, '-'),\n\n /** Takes a Date object and displays it as an Euro Date format (DD/MM/YYYY) */\n dateEuro: getAssociatedDateFormatter(FieldType.dateEuro, '/'),\n\n /** Takes a Date object and displays it as an Euro Date+Time format (DD/MM/YYYY HH:mm:ss) */\n dateTimeEuro: getAssociatedDateFormatter(FieldType.dateTimeEuro, '/'),\n\n /** Takes a Date object and displays it as an Euro Date+Time (without seconds) format (DD/MM/YYYY HH:mm) */\n dateTimeShortEuro: getAssociatedDateFormatter(FieldType.dateTimeShortEuro, '/'),\n\n /** Takes a Date object and displays it as an Euro Date+Time+(am/pm) format (DD/MM/YYYY hh:mm:ss a) */\n dateTimeEuroAmPm: getAssociatedDateFormatter(FieldType.dateTimeEuroAmPm, '/'),\n\n /** Takes a Date object and displays it as an US Date format (MM/DD/YYYY) */\n dateUs: getAssociatedDateFormatter(FieldType.dateUs, '/'),\n\n /** Takes a Date object and displays it as an US Date+Time format (MM/DD/YYYY HH:mm:ss) */\n dateTimeUs: getAssociatedDateFormatter(FieldType.dateTimeUs, '/'),\n\n /** Takes a Date object and displays it as an US Date+Time (without seconds) format (MM/DD/YYYY HH:mm:ss) */\n dateTimeShortUs: getAssociatedDateFormatter(FieldType.dateTimeShortUs, '/'),\n\n /** Takes a Date object and displays it as an US Date+Time+(am/pm) format (MM/DD/YYYY hh:mm:ss a) */\n dateTimeUsAmPm: getAssociatedDateFormatter(FieldType.dateTimeUsAmPm, '/'),\n\n /** Displays a Font-Awesome delete icon (fa-trash) */\n deleteIcon: deleteIconFormatter,\n\n /**\n * Display the value as x decimals formatted, defaults to 2 decimals.\n * You can pass \"decimalPlaces\" or \"minDecimalPlaces\" and/or \"maxDecimalPlaces\" to the \"params\" property.\n * For example:: `{ formatter: Formatters.decimal, params: { decimalPlaces: 3 }}`\n * The property \"decimalPlaces\" is an alias of \"minDecimalPlaces\"\n */\n decimal: decimalFormatter,\n\n /** Display the value as 2 decimals formatted with dollar sign '$' at the end of of the value */\n dollar: dollarFormatter,\n\n /** Display the value as 2 decimals formatted with dollar sign '$' at the end of of the value, change color of text to red/green on negative/positive value */\n dollarColored: dollarColoredFormatter,\n\n /** Display the value as 2 decimals formatted with dollar sign '$' at the end of of the value, change color of text to red/green on negative/positive value, show it in bold font weight as well */\n dollarColoredBold: dollarColoredBoldFormatter,\n\n /** Displays a Font-Awesome edit icon (fa-pencil) */\n editIcon: editIconFormatter,\n\n /**\n * Takes an hyperlink cell value and transforms it into a real hyperlink, given that the value starts with 1 of these (http|ftp|https).\n * The structure will be \"<a href=\"hyperlink\">hyperlink</a>\"\n * You can optionally change the hyperlink text displayed by using the generic params \"hyperlinkText\" in the column definition\n * For example: { id: 'link', field: 'link', params: { hyperlinkText: 'Company Website' } } will display \"<a href=\"link\">Company Website</a>\"\n */\n hyperlink: hyperlinkFormatter,\n\n /** Display whichever icon you want (library agnostic, it could be Font-Awesome or any other) */\n icon: iconFormatter,\n\n /** Displays a Font-Awesome edit icon (fa-info-circle) */\n infoIcon: infoIconFormatter,\n\n /** show input text value as italic text */\n italic: italicFormatter,\n\n /** Takes a value and displays it all lowercase */\n lowercase: lowercaseFormatter,\n\n /**\n * Takes a value display it according to a mask provided\n * e.: 1234567890 with mask \"(000) 000-0000\" will display \"(123) 456-7890\"\n */\n mask: maskFormatter,\n\n /**\n * You can pipe multiple formatters (executed in sequence), use params to pass the list of formatters.\n * Requires to pass an array of \"formatters\" in the column definition the generic \"params\" property\n * For example::\n * { field: 'title', formatter: Formatters.multiple, params: { formatters: [ Formatters.lowercase, Formatters.uppercase ] }\n */\n multiple: multipleFormatter,\n\n /** Takes a cell value number (between 0.0-1.0) and displays a red (<50) or green (>=50) bar */\n percent: percentFormatter,\n\n /** Takes a cell value number (between 0.0-100) and displays a red (<50) or green (>=50) bar */\n percentComplete: percentCompleteFormatter,\n\n /** Takes a cell value number (between 0-100) and displays Bootstrap \"percent-complete-bar\" a red (<30), silver (>30 & <70) or green (>=70) bar */\n percentCompleteBar: percentCompleteBarFormatter,\n\n /** Takes a cell value number (between 0-100) and add the \"%\" after the number */\n percentSymbol: percentSymbolFormatter,\n\n /** Takes a cell value number (between 0-100) and displays Bootstrap \"progress-bar\" a red (<30), silver (>30 & <70) or green (>=70) bar */\n progressBar: progressBarFormatter,\n\n /** Takes a cell value and translates it (i18n). Requires an instance of the Translate Service:: `i18n: this.translate */\n translate: translateFormatter,\n\n /** Takes a boolean value, cast it to upperCase string and finally translates it (i18n). */\n translateBoolean: translateBooleanFormatter,\n\n /** Takes a value and displays it all uppercase */\n uppercase: uppercaseFormatter,\n\n /** Takes a boolean value and display a string 'Yes' or 'No' */\n yesNo: yesNoFormatter\n};\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { decimalFormatted } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const avgTotalsPercentageFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n let val = totals.avg && totals.avg[field];\r\n const params = columnDef && columnDef.params;\r\n let prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n if (val < 0) {\r\n val = Math.abs(val);\r\n if (!displayNegativeNumberWithParentheses) {\r\n prefix += '-';\r\n } else {\r\n if (isNaN(minDecimal) && isNaN(maxDecimal)) {\r\n return `${prefix}(${Math.round(val)}%)${suffix}`;\r\n }\r\n return `${prefix}(${decimalFormatted(val, minDecimal, maxDecimal)}%)${suffix}`;\r\n }\r\n }\r\n\r\n if (isNaN(minDecimal) && isNaN(maxDecimal)) {\r\n return `${prefix}${Math.round(val)}%${suffix}`;\r\n }\r\n return `${prefix}${decimalFormatted(val, minDecimal, maxDecimal)}%${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const avgTotalsDollarFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.avg && totals.avg[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `${prefix}${formattedNumber}${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { decimalFormatted } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const avgTotalsFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n let val = totals.avg && totals.avg[field];\r\n const params = columnDef && columnDef.params;\r\n let prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n if (val < 0) {\r\n val = Math.abs(val);\r\n if (!displayNegativeNumberWithParentheses) {\r\n prefix += '-';\r\n } else {\r\n if (isNaN(minDecimal) && isNaN(maxDecimal)) {\r\n return `${prefix}(${Math.round(val)})${suffix}`;\r\n }\r\n return `${prefix}(${decimalFormatted(val, minDecimal, maxDecimal)})${suffix}`;\r\n }\r\n }\r\n\r\n if (isNaN(minDecimal) && isNaN(maxDecimal)) {\r\n return `${prefix}${Math.round(val)}${suffix}`;\r\n }\r\n return `${prefix}${decimalFormatted(val, minDecimal, maxDecimal)}${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const minTotalsFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.min && totals.min[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses);\r\n return `${prefix}${formattedNumber}${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const maxTotalsFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.max && totals.max[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses);\r\n return `${prefix}${formattedNumber}${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsColoredFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const colorStyle = (val >= 0) ? 'green' : 'red';\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses);\r\n return `<span style=\"color:${colorStyle}\">${prefix}${formattedNumber}${suffix}</span>`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsDollarColoredBoldFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const colorStyle = (val >= 0) ? 'green' : 'red';\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `<span style=\"color:${colorStyle}; font-weight: bold;\">${prefix}${formattedNumber}${suffix}</span>`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsDollarColoredFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const colorStyle = (val >= 0) ? 'green' : 'red';\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `<span style=\"color:${colorStyle}\">${prefix}${formattedNumber}${suffix}</span>`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsDollarBoldFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `<b>${prefix}${formattedNumber}${suffix}</b>`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from './../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsDollarFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid, 2);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid, 4);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses, '$');\r\n return `${prefix}${formattedNumber}${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses);\r\n return `${prefix}${formattedNumber}${suffix}`;\r\n }\r\n return '';\r\n};\r\n","import { Column, GroupTotalsFormatter } from './../models/index';\r\nimport { formatNumber } from '../services/utilities';\r\nimport { getValueFromParamsOrGridOptions } from '../formatters/formatterUtilities';\r\n\r\nexport const sumTotalsBoldFormatter: GroupTotalsFormatter = (totals: any, columnDef: Column, grid?: any) => {\r\n const field = columnDef.field || '';\r\n const val = totals.sum && totals.sum[field];\r\n const params = columnDef && columnDef.params;\r\n const prefix = params && params.groupFormatterPrefix || '';\r\n const suffix = params && params.groupFormatterSuffix || '';\r\n const minDecimal = getValueFromParamsOrGridOptions('minDecimal', columnDef, grid);\r\n const maxDecimal = getValueFromParamsOrGridOptions('maxDecimal', columnDef, grid);\r\n const displayNegativeNumberWithParentheses = getValueFromParamsOrGridOptions('displayNegativeNumberWithParentheses', columnDef, grid, false);\r\n\r\n if (val != null && !isNaN(+val)) {\r\n const formattedNumber = formatNumber(val, minDecimal, maxDecimal, displayNegativeNumberWithParentheses);\r\n return `<b>${prefix}${formattedNumber}${suffix}</b>`;\r\n }\r\n return '';\r\n};\r\n","import { Column } from './../models/index';\r\nimport { avgTotalsPercentageFormatter } from './avgTotalsPercentageFormatter';\r\nimport { avgTotalsDollarFormatter } from './avgTotalsDollarFormatter';\r\nimport { avgTotalsFormatter } from './avgTotalsFormatter';\r\nimport { minTotalsFormatter } from './minTotalsFormatter';\r\nimport { maxTotalsFormatter } from './maxTotalsFormatter';\r\nimport { sumTotalsColoredFormatter } from './sumTotalsColoredFormatter';\r\nimport { sumTotalsDollarColoredBoldFormatter } from './sumTotalsDollarColoredBoldFormatter';\r\nimport { sumTotalsDollarColoredFormatter } from './sumTotalsDollarColoredFormatter';\r\nimport { sumTotalsDollarBoldFormatter } from './sumTotalsDollarBoldFormatter';\r\nimport { sumTotalsDollarFormatter } from './sumTotalsDollarFormatter';\r\nimport { sumTotalsFormatter } from './sumTotalsFormatter';\r\nimport { sumTotalsBoldFormatter } from './sumTotalsBoldFormatter';\r\n\r\n/** Provides a list of different Formatters that will change the cell value displayed in the UI */\r\nexport const GroupTotalFormatters = {\r\n /**\r\n * Average all the column totals\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g.: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n avgTotals: avgTotalsFormatter,\r\n\r\n /**\r\n * Average all the column totals and display '$' at the end of the value\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g.: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n avgTotalsDollar: avgTotalsDollarFormatter,\r\n\r\n /**\r\n * Average all the column totals and display '%' at the end of the value\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g.: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n avgTotalsPercentage: avgTotalsPercentageFormatter,\r\n\r\n /**\r\n * Show max value of all the column totals\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g.: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n maxTotals: maxTotalsFormatter,\r\n\r\n /**\r\n * Show min value of all the column totals\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g.: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n minTotals: minTotalsFormatter,\r\n\r\n /**\r\n * Sums up all the column totals\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g.: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotals: sumTotalsFormatter,\r\n\r\n /**\r\n * Sums up all the column totals and display it in bold font weight\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotalsBold: sumTotalsBoldFormatter,\r\n\r\n /**\r\n * Sums up all the column totals, change color of text to red/green on negative/positive value\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotalsColored: sumTotalsColoredFormatter,\r\n\r\n /**\r\n * Sums up all the column totals and display dollar sign\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotalsDollar: sumTotalsDollarFormatter,\r\n\r\n /**\r\n * Sums up all the column totals and display dollar sign and show it in bold font weight\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotalsDollarBold: sumTotalsDollarBoldFormatter,\r\n\r\n /**\r\n * Sums up all the column totals, change color of text to red/green on negative/positive value\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotalsDollarColored: sumTotalsDollarColoredFormatter,\r\n\r\n /**\r\n * Sums up all the column totals, change color of text to red/green on negative/positive value, show it in bold font weight as well\r\n * Extra options available in \"params\":: \"groupFormatterPrefix\" and \"groupFormatterSuffix\", e.g: params: { groupFormatterPrefix: '<i>Total</i>: ', groupFormatterSuffix: '$' }\r\n */\r\n sumTotalsDollarColoredBold: sumTotalsDollarColoredBoldFormatter,\r\n};\r\n","import { AfterViewInit, Component, EventEmitter, Injectable, Input, OnDestroy, Output } from '@angular/core';\r\nimport { GraphqlResult, GridOption, Pagination } from './../models/index';\r\nimport { executeBackendProcessesCallback, onBackendError } from '../services/backend-utilities';\r\nimport { FilterService } from './../services/filter.service';\r\nimport { GridService } from './../services/grid.service';\r\nimport { isObservable, Subscription } from 'rxjs';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\n\r\n@Component({\r\n selector: 'slick-pagination',\r\n templateUrl: './slick-pagination.component.html'\r\n})\r\n@Injectable()\r\nexport class SlickPaginationComponent implements AfterViewInit, OnDestroy {\r\n private _eventHandler = new Slick.EventHandler();\r\n private _filterSubcription: Subscription;\r\n private _gridPaginationOptions: GridOption;\r\n private _isFirstRender = true;\r\n @Output() onPaginationChanged = new EventEmitter<Pagination>();\r\n @Input() dataView: any;\r\n @Input()\r\n set gridPaginationOptions(gridPaginationOptions: GridOption) {\r\n this._gridPaginationOptions = gridPaginationOptions;\r\n if (this._isFirstRender || !gridPaginationOptions || !gridPaginationOptions.pagination || (gridPaginationOptions.pagination.totalItems !== this.totalItems)) {\r\n this.refreshPagination();\r\n this._isFirstRender = false;\r\n }\r\n }\r\n get gridPaginationOptions(): GridOption {\r\n return this._gridPaginationOptions;\r\n }\r\n @Input() grid: any;\r\n dataFrom = 1;\r\n dataTo = 1;\r\n itemsPerPage: number;\r\n pageCount = 0;\r\n pageNumber = 1;\r\n totalItems = 0;\r\n paginationCallback: Function;\r\n paginationPageSizes = [25, 75, 100];\r\n fromToParams: any = { from: this.dataFrom, to: this.dataTo, totalItems: this.totalItems };\r\n\r\n /** Constructor */\r\n constructor(private filterService: FilterService, private gridService: GridService) {}\r\n\r\n ngOnDestroy() {\r\n this.dispose();\r\n }\r\n\r\n ngAfterViewInit() {\r\n this._gridPaginationOptions = this._gridPaginationOptions;\r\n if (!this._gridPaginationOptions || !this._gridPaginationOptions.pagination || (this._gridPaginationOptions.pagination.totalItems !== this.totalItems)) {\r\n this.refreshPagination();\r\n }\r\n\r\n // Subscribe to Filter Clear & Changed and go back to page 1 when that happen\r\n this._filterSubcription = this.filterService.onFilterChanged.subscribe(() => this.refreshPagination(true));\r\n this._filterSubcription = this.filterService.onFilterCleared.subscribe(() => this.refreshPagination(true));\r\n\r\n // Subscribe to any dataview row count changed so that when Adding/Deleting item(s) through the DataView\r\n // that would trigger a refresh of the pagination numbers\r\n if (this.dataView) {\r\n this.gridService.onItemAdded.subscribe((items: any | any[]) => this.onItemAddedOrRemoved(items, true));\r\n this.gridService.onItemDeleted.subscribe((items: any | any[]) => this.onItemAddedOrRemoved(items, false));\r\n }\r\n }\r\n\r\n ceil(number: number) {\r\n return Math.ceil(number);\r\n }\r\n\r\n changeToFirstPage(event: any) {\r\n this.pageNumber = 1;\r\n this.onPageChanged(event, this.pageNumber);\r\n }\r\n\r\n changeToLastPage(event: any) {\r\n this.pageNumber = this.pageCount;\r\n this.onPageChanged(event, this.pageNumber);\r\n }\r\n\r\n changeToNextPage(event: any) {\r\n if (this.pageNumber < this.pageCount) {\r\n this.pageNumber++;\r\n this.onPageChanged(event, this.pageNumber);\r\n }\r\n }\r\n\r\n changeToPreviousPage(event: any) {\r\n if (this.pageNumber > 0) {\r\n this.pageNumber--;\r\n this.onPageChanged(event, this.pageNumber);\r\n }\r\n }\r\n\r\n changeToCurrentPage(event: any) {\r\n this.pageNumber = +event.currentTarget.value;\r\n if (this.pageNumber < 1) {\r\n this.pageNumber = 1;\r\n } else if (this.pageNumber > this.pageCount) {\r\n this.pageNumber = this.pageCount;\r\n }\r\n\r\n this.onPageChanged(event, this.pageNumber);\r\n }\r\n\r\n dispose() {\r\n this.onPaginationChanged.unsubscribe();\r\n if (this._filterSubcription) {\r\n this._filterSubcription.unsubscribe();\r\n }\r\n\r\n // unsubscribe all SlickGrid events\r\n this._eventHandler.unsubscribeAll();\r\n }\r\n\r\n onChangeItemPerPage(event: any) {\r\n const itemsPerPage = +event.target.value;\r\n this.pageCount = Math.ceil(this.totalItems / itemsPerPage);\r\n this.pageNumber = (this.totalItems > 0) ? 1 : 0;\r\n this.itemsPerPage = itemsPerPage;\r\n this.onPageChanged(event, this.pageNumber);\r\n }\r\n\r\n refreshPagination(isPageNumberReset: boolean = false) {\r\n const backendApi = this._gridPaginationOptions.backendServiceApi;\r\n if (!backendApi || !backendApi.service || !backendApi.process) {\r\n throw new Error(`BackendServiceApi requires at least a \"process\" function and a \"service\" defined`);\r\n }\r\n\r\n if (this._gridPaginationOptions && this._gridPaginationOptions.pagination) {\r\n const pagination = this._gridPaginationOptions.pagination;\r\n // set the number of items per page if not already set\r\n if (!this.itemsPerPage) {\r\n this.itemsPerPage = +((backendApi && backendApi.options && backendApi.options.paginationOptions && backendApi.options.paginationOptions.first) ? backendApi.options.paginationOptions.first : this._gridPaginationOptions.pagination.pageSize);\r\n }\r\n\r\n // if totalItems changed, we should always go back to the first page and recalculation the From-To indexes\r\n if (isPageNumberReset || this.totalItems !== pagination.totalItems) {\r\n if (this._isFirstRender && pagination.pageNumber && pagination.pageNumber > 1) {\r\n this.pageNumber = pagination.pageNumber || 1;\r\n } else {\r\n this.pageNumber = 1;\r\n }\r\n\r\n // when page number is set to 1 then also reset the \"offset\" of backend service\r\n if (this.pageNumber === 1) {\r\n backendApi.service.resetPaginationOptions();\r\n }\r\n }\r\n\r\n // calculate and refresh the multiple properties of the pagination UI\r\n this.paginationPageSizes = this._gridPaginationOptions.pagination.pageSizes;\r\n this.totalItems = this._gridPaginationOptions.pagination.totalItems;\r\n this.recalculateFromToIndexes();\r\n }\r\n this.pageCount = Math.ceil(this.totalItems / this.itemsPerPage);\r\n }\r\n\r\n onPageChanged(event: Event | undefined, pageNumber: number) {\r\n this.recalculateFromToIndexes();\r\n\r\n const backendApi = this._gridPaginationOptions.backendServiceApi;\r\n if (!backendApi || !backendApi.service || !backendApi.process) {\r\n throw new Error(`BackendServiceApi requires at least a \"process\" function and a \"service\" defined`);\r\n }\r\n\r\n if (this.dataTo > this.totalItems) {\r\n this.dataTo = this.totalItems;\r\n } else if (this.totalItems < this.itemsPerPage) {\r\n this.dataTo = this.totalItems;\r\n }\r\n if (backendApi) {\r\n try {\r\n const itemsPerPage = +this.itemsPerPage;\r\n\r\n // keep start time & end timestamps & return it after process execution\r\n const startTime = new Date();\r\n\r\n // run any pre-process, if defined, for example a spinner\r\n if (backendApi.preProcess) {\r\n backendApi.preProcess();\r\n }\r\n\r\n const query = backendApi.service.processOnPaginationChanged(event, { newPage: pageNumber, pageSize: itemsPerPage });\r\n\r\n // the processes can be Observables (like HttpClient) or Promises\r\n const process = backendApi.process(query);\r\n if (process instanceof Promise && process.then) {\r\n process.then((processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this._gridPaginationOptions));\r\n } else if (isObservable(process)) {\r\n process.subscribe(\r\n (processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this._gridPaginationOptions),\r\n (error: any) => onBackendError(error, backendApi)\r\n );\r\n }\r\n } catch (error) {\r\n onBackendError(error, backendApi);\r\n }\r\n } else {\r\n throw new Error('Pagination with a backend service requires \"BackendServiceApi\" to be defined in your grid options');\r\n }\r\n\r\n // emit the changes to the parent component\r\n this.onPaginationChanged.emit({\r\n pageNumber: this.pageNumber,\r\n pageSizes: this.paginationPageSizes,\r\n pageSize: this.itemsPerPage,\r\n totalItems: this.totalItems\r\n });\r\n }\r\n\r\n recalculateFromToIndexes() {\r\n if (this.totalItems === 0) {\r\n this.dataFrom = 0;\r\n this.dataTo = 0;\r\n this.pageNumber = 0;\r\n } else {\r\n this.dataFrom = (this.pageNumber * this.itemsPerPage) - this.itemsPerPage + 1;\r\n this.dataTo = (this.totalItems < this.itemsPerPage) ? this.totalItems : (this.pageNumber * this.itemsPerPage);\r\n }\r\n }\r\n\r\n /**\r\n * When item is added or removed, we will refresh the numbers on the pagination however we won't trigger a backend change\r\n * This will have a side effect though, which is that the \"To\" count won't be matching the \"items per page\" count,\r\n * that is a necessary side effect to avoid triggering a backend query just to refresh the paging,\r\n * basically we assume that this offset is fine for the time being,\r\n * until user does an action which will refresh the data hence the pagination which will then become normal again\r\n */\r\n private onItemAddedOrRemoved(items: any | any[], isItemAdded = true) {\r\n if (items !== null) {\r\n const previousDataTo = this.dataTo;\r\n const itemCount = Array.isArray(items) ? items.length : 1;\r\n const itemCountWithDirection = isItemAdded ? +itemCount : -itemCount;\r\n\r\n // refresh the total count in the pagination and in the UI\r\n this.totalItems += itemCountWithDirection;\r\n this.recalculateFromToIndexes();\r\n\r\n // finally refresh the \"To\" count and we know it might be different than the \"items per page\" count\r\n // but this is necessary since we don't want an actual backend refresh\r\n this.dataTo = previousDataTo + itemCountWithDirection;\r\n }\r\n }\r\n}\r\n","// import 3rd party vendor libs\r\n// only import the necessary core lib, each will be imported on demand when enabled (via require)\r\nimport 'jquery-ui-dist/jquery-ui';\r\nimport 'slickgrid/lib/jquery.event.drag-2.3.0';\r\nimport 'slickgrid/slick.core';\r\nimport 'slickgrid/slick.grid';\r\nimport 'slickgrid/slick.dataview';\r\n\r\n// ...then everything else...\r\nimport { AfterViewInit, Component, ElementRef, EventEmitter, Inject, Injectable, Input, Output, OnDestroy, OnInit } from '@angular/core';\r\nimport { TranslateService } from '@ngx-translate/core';\r\nimport { GlobalGridOptions } from './../global-grid-options';\r\nimport { titleCase, unsubscribeAllObservables } from './../services/utilities';\r\nimport { executeBackendProcessesCallback, onBackendError } from '../services/backend-utilities';\r\nimport {\r\n AngularGridInstance,\r\n BackendServiceOption,\r\n Column,\r\n ExtensionName,\r\n GraphqlResult,\r\n GridOption,\r\n GridStateChange,\r\n GridStateType,\r\n Pagination,\r\n} from './../models/index';\r\nimport { FilterFactory } from '../filters/filterFactory';\r\nimport { SlickgridConfig } from '../slickgrid-config';\r\nimport { isObservable, Observable, Subscription } from 'rxjs';\r\n\r\n// Services\r\nimport { AngularUtilService } from '../services/angularUtil.service';\r\nimport { ExportService } from './../services/export.service';\r\nimport { ExtensionService } from '../services/extension.service';\r\nimport { ExtensionUtility } from '../extensions/extensionUtility';\r\nimport { FilterService } from './../services/filter.service';\r\nimport { GraphqlService } from './../services/graphql.service';\r\nimport { GridEventService } from './../services/gridEvent.service';\r\nimport { GridService } from './../services/grid.service';\r\nimport { GridStateService } from './../services/gridState.service';\r\nimport { GroupingAndColspanService } from './../services/groupingAndColspan.service';\r\nimport { ResizerService } from './../services/resizer.service';\r\nimport { SharedService } from '../services/shared.service';\r\nimport { SortService } from './../services/sort.service';\r\n\r\n// Extensions (SlickGrid Controls & Plugins)\r\nimport { AutoTooltipExtension } from '../extensions/autoTooltipExtension';\r\nimport { CellExternalCopyManagerExtension } from '../extensions/cellExternalCopyManagerExtension';\r\nimport { CheckboxSelectorExtension } from '../extensions/checkboxSelectorExtension';\r\nimport { ColumnPickerExtension } from '../extensions/columnPickerExtension';\r\nimport { DraggableGroupingExtension } from '../extensions/draggableGroupingExtension';\r\nimport { GridMenuExtension } from '../extensions/gridMenuExtension';\r\nimport { GroupItemMetaProviderExtension } from '../extensions/groupItemMetaProviderExtension';\r\nimport { HeaderButtonExtension } from '../extensions/headerButtonExtension';\r\nimport { HeaderMenuExtension } from '../extensions/headerMenuExtension';\r\nimport { RowDetailViewExtension } from '../extensions/rowDetailViewExtension';\r\nimport { RowMoveManagerExtension } from '../extensions/rowMoveManagerExtension';\r\nimport { RowSelectionExtension } from '../extensions/rowSelectionExtension';\r\n\r\n// using external non-typed js libraries\r\ndeclare var Slick: any;\r\ndeclare var $: any;\r\n\r\nconst slickgridEventPrefix = 'sg';\r\n\r\n@Injectable()\r\n@Component({\r\n selector: 'angular-slickgrid',\r\n templateUrl: './angular-slickgrid.component.html',\r\n providers: [\r\n // make everything transient (non-singleton)\r\n AngularUtilService,\r\n AutoTooltipExtension,\r\n CellExternalCopyManagerExtension,\r\n CheckboxSelectorExtension,\r\n ColumnPickerExtension,\r\n DraggableGroupingExtension,\r\n ExtensionService,\r\n ExportService,\r\n ExtensionUtility,\r\n FilterFactory,\r\n FilterService,\r\n GraphqlService,\r\n GridEventService,\r\n GridMenuExtension,\r\n GridService,\r\n GridStateService,\r\n GroupingAndColspanService,\r\n GroupItemMetaProviderExtension,\r\n HeaderButtonExtension,\r\n HeaderMenuExtension,\r\n ResizerService,\r\n RowDetailViewExtension,\r\n RowMoveManagerExtension,\r\n RowSelectionExtension,\r\n SharedService,\r\n SortService,\r\n SlickgridConfig\r\n ]\r\n})\r\nexport class AngularSlickgridComponent implements AfterViewInit, OnDestroy, OnInit {\r\n private _dataset: any[];\r\n private _columnDefinitions: Column[];\r\n private _eventHandler: any = new Slick.EventHandler();\r\n private _fixedHeight: number | null;\r\n private _fixedWidth: number | null;\r\n private _hideHeaderRowAfterPageLoad = false;\r\n dataView: any;\r\n grid: any;\r\n gridPaginationOptions: GridOption;\r\n gridHeightString: string;\r\n gridWidthString: string;\r\n groupingDefinition: any = {};\r\n groupItemMetadataProvider: any;\r\n showPagination = false;\r\n isGridInitialized = false;\r\n subscriptions: Subscription[] = [];\r\n\r\n @Output() onAngularGridCreated = new EventEmitter<AngularGridInstance>();\r\n @Output() onDataviewCreated = new EventEmitter<any>();\r\n @Output() onGridCreated = new EventEmitter<any>();\r\n @Output() onGridInitialized = new EventEmitter<any>();\r\n @Output() onBeforeGridCreate = new EventEmitter<boolean>();\r\n @Output() onBeforeGridDestroy = new EventEmitter<any>();\r\n @Output() onAfterGridDestroyed = new EventEmitter<boolean>();\r\n @Output() onGridStateChanged = new EventEmitter<GridStateChange>();\r\n @Input() customDataView: any;\r\n @Input() gridId: string;\r\n @Input() gridOptions: GridOption;\r\n\r\n @Input()\r\n set gridHeight(height: number) {\r\n this._fixedHeight = height;\r\n }\r\n @Input()\r\n set gridWidth(width: number) {\r\n this._fixedWidth = width;\r\n }\r\n\r\n @Input()\r\n set columnDefinitions(columnDefinitions: Column[]) {\r\n this._columnDefinitions = columnDefinitions;\r\n if (this.isGridInitialized) {\r\n this.updateColumnDefinitionsList(columnDefinitions);\r\n }\r\n }\r\n get columnDefinitions(): Column[] {\r\n return this._columnDefinitions;\r\n }\r\n @Input()\r\n set dataset(dataset: any[]) {\r\n this._dataset = dataset;\r\n this.refreshGridData(dataset);\r\n }\r\n get dataset(): any[] {\r\n return this.dataView.getItems();\r\n }\r\n\r\n constructor(\r\n private elm: ElementRef,\r\n private exportService: ExportService,\r\n private extensionService: ExtensionService,\r\n private extensionUtility: ExtensionUtility,\r\n private filterService: FilterService,\r\n private gridService: GridService,\r\n private gridEventService: GridEventService,\r\n private gridStateService: GridStateService,\r\n private groupingAndColspanService: GroupingAndColspanService,\r\n private resizer: ResizerService,\r\n private sharedService: SharedService,\r\n private sortService: SortService,\r\n private translate: TranslateService,\r\n @Inject('config') private forRootConfig: GridOption\r\n ) { }\r\n\r\n ngOnInit(): void {\r\n this.onBeforeGridCreate.emit(true);\r\n\r\n if (this.gridOptions && !this.gridOptions.enableAutoResize && (this._fixedHeight || this._fixedWidth)) {\r\n this.gridHeightString = `${this._fixedHeight}px`;\r\n this.gridWidthString = `${this._fixedWidth}px`;\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.onBeforeGridDestroy.emit(this.grid);\r\n this.destroy();\r\n this.onAfterGridDestroyed.emit(true);\r\n }\r\n\r\n destroy(emptyDomElementContainer = false) {\r\n const gridContainerId = this.gridOptions && this.gridOptions.gridContainerId;\r\n this.dataView = undefined;\r\n this.gridOptions = {};\r\n this.extensionService.dispose();\r\n this.filterService.dispose();\r\n this.gridEventService.dispose();\r\n this.gridStateService.dispose();\r\n this.groupingAndColspanService.dispose();\r\n this.resizer.dispose();\r\n this.sortService.dispose();\r\n if (this._eventHandler && this._eventHandler.unsubscribeAll) {\r\n this._eventHandler.unsubscribeAll();\r\n }\r\n if (this.grid && this.grid.destroy) {\r\n this.grid.destroy();\r\n }\r\n\r\n if (emptyDomElementContainer) {\r\n $(gridContainerId).empty();\r\n }\r\n\r\n // also unsubscribe all RxJS subscriptions\r\n this.subscriptions = unsubscribeAllObservables(this.subscriptions);\r\n }\r\n\r\n ngAfterViewInit() {\r\n this.initialization();\r\n this.isGridInitialized = true;\r\n\r\n // user must provide a \"gridHeight\" or use \"autoResize: true\" in the grid options\r\n if (!this._fixedHeight && !this.gridOptions.enableAutoResize) {\r\n throw new Error(\r\n `[Angular-Slickgrid] requires a \"grid-height\" or the \"enableAutoResize\" grid option to be enabled.\r\n Without that the grid will seem empty while in fact it just does not have any height define.`\r\n );\r\n }\r\n }\r\n\r\n initialization() {\r\n // make sure the dataset is initialized (if not it will throw an error that it cannot getLength of null)\r\n this._dataset = this._dataset || [];\r\n this.gridOptions = this.mergeGridOptions(this.gridOptions);\r\n this.createBackendApiInternalPostProcessCallback(this.gridOptions);\r\n\r\n if (!this.customDataView) {\r\n if (this.gridOptions.draggableGrouping || this.gridOptions.enableGrouping) {\r\n this.extensionUtility.loadExtensionDynamically(ExtensionName.groupItemMetaProvider);\r\n this.groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider();\r\n this.sharedService.groupItemMetadataProvider = this.groupItemMetadataProvider;\r\n this.dataView = new Slick.Data.DataView({ groupItemMetadataProvider: this.groupItemMetadataProvider });\r\n } else {\r\n this.dataView = new Slick.Data.DataView();\r\n }\r\n }\r\n\r\n // for convenience to the user, we provide the property \"editor\" as an Angular-Slickgrid editor complex object\r\n // however \"editor\" is used internally by SlickGrid for it's own Editor Factory\r\n // so in our lib we will swap \"editor\" and copy it into a new property called \"internalColumnEditor\"\r\n // then take back \"editor.model\" and make it the new \"editor\" so that SlickGrid Editor Factory still works\r\n this._columnDefinitions = this.swapInternalEditorToSlickGridFactoryEditor(this._columnDefinitions);\r\n\r\n // save reference for all columns before they optionally become hidden/visible\r\n this.sharedService.allColumns = this._columnDefinitions;\r\n this.sharedService.visibleColumns = this._columnDefinitions;\r\n this.extensionService.createExtensionsBeforeGridCreation(this._columnDefinitions, this.gridOptions);\r\n\r\n // build SlickGrid Grid, also user might optionally pass a custom dataview (e.g. remote model)\r\n this.grid = new Slick.Grid(`#${this.gridId}`, this.customDataView || this.dataView, this._columnDefinitions, this.gridOptions);\r\n\r\n this.sharedService.dataView = this.dataView;\r\n this.sharedService.grid = this.grid;\r\n\r\n this.extensionService.bindDifferentExtensions();\r\n this.bindDifferentHooks(this.grid, this.gridOptions, this.dataView);\r\n\r\n // emit the Grid & DataView object to make them available in parent component\r\n this.onGridCreated.emit(this.grid);\r\n\r\n // initialize the SlickGrid grid\r\n this.grid.init();\r\n\r\n if (!this.customDataView && (this.dataView && this.dataView.beginUpdate && this.dataView.setItems && this.dataView.endUpdate)) {\r\n this.onDataviewCreated.emit(this.dataView);\r\n this.dataView.beginUpdate();\r\n this.dataView.setItems(this._dataset, this.gridOptions.datasetIdPropertyName);\r\n this.dataView.endUpdate();\r\n\r\n // if you don't want the items that are not visible (due to being filtered out or being on a different page)\r\n // to stay selected, pass 'false' to the second arg\r\n if (this.gridOptions && this.gridOptions.dataView && this.gridOptions.dataView.hasOwnProperty('syncGridSelection')) {\r\n const syncGridSelection = this.gridOptions.dataView.syncGridSelection;\r\n if (typeof syncGridSelection === 'boolean') {\r\n this.dataView.syncGridSelection(this.grid, this.gridOptions.dataView.syncGridSelection);\r\n } else {\r\n this.dataView.syncGridSelection(this.grid, syncGridSelection.preserveHidden, syncGridSelection.preserveHiddenOnSelectionChange);\r\n }\r\n }\r\n }\r\n\r\n // user might want to hide the header row on page load but still have `enableFiltering: true`\r\n // if that is the case, we need to hide the headerRow ONLY AFTER all filters got created & dataView exist\r\n if (this._hideHeaderRowAfterPageLoad) {\r\n this.showHeaderRow(false);\r\n }\r\n\r\n // after the DataView is created & updated execute some processes\r\n this.executeAfterDataviewCreated(this.grid, this.gridOptions, this.dataView);\r\n\r\n // bind resize ONLY after the dataView is ready\r\n this.bindResizeHook(this.grid, this.gridOptions);\r\n\r\n // bind & initialize grouping and header grouping colspan service\r\n if (this.gridOptions.createPreHeaderPanel && !this.gridOptions.enableDraggableGrouping) {\r\n this.groupingAndColspanService.init(this.grid, this.dataView);\r\n }\r\n\r\n // bind & initialize the grid service\r\n this.gridService.init(this.grid, this.dataView);\r\n\r\n // when user enables translation, we need to translate Headers on first pass & subsequently in the bindDifferentHooks\r\n if (this.gridOptions.enableTranslate) {\r\n this.extensionService.translateColumnHeaders();\r\n }\r\n\r\n // if Export is enabled, initialize the service with the necessary grid and other objects\r\n if (this.gridOptions.enableExport) {\r\n this.exportService.init(this.grid, this.dataView);\r\n }\r\n\r\n // once all hooks are in placed and the grid is initialized, we can emit an event\r\n this.onGridInitialized.emit(this.grid);\r\n\r\n // bind the Backend Service API callback functions only after the grid is initialized\r\n // because the preProcess() and onInit() might get triggered\r\n if (this.gridOptions && this.gridOptions.backendServiceApi) {\r\n this.bindBackendCallbackFunctions(this.gridOptions);\r\n }\r\n\r\n this.gridStateService.init(this.grid, this.extensionService, this.filterService, this.sortService);\r\n\r\n this.onAngularGridCreated.emit({\r\n // Slick Grid & DataView objects\r\n dataView: this.dataView,\r\n slickGrid: this.grid,\r\n\r\n // public methods\r\n destroy: this.destroy.bind(this),\r\n\r\n // return all available Services (non-singleton)\r\n backendService: this.gridOptions && this.gridOptions.backendServiceApi && this.gridOptions.backendServiceApi.service,\r\n exportService: this.exportService,\r\n extensionService: this.extensionService,\r\n filterService: this.filterService,\r\n gridEventService: this.gridEventService,\r\n gridStateService: this.gridStateService,\r\n gridService: this.gridService,\r\n groupingService: this.groupingAndColspanService,\r\n resizerService: this.resizer,\r\n sortService: this.sortService,\r\n\r\n /** @deprecated please use \"extensionService\" instead */\r\n pluginService: this.extensionService,\r\n });\r\n }\r\n\r\n /**\r\n * Commits the current edit to the grid\r\n */\r\n commitEdit(target: Element) {\r\n if (this.grid.getOptions().autoCommitEdit) {\r\n const activeNode = this.grid.getActiveCellNode();\r\n\r\n // a timeout must be set or this could come into conflict when slickgrid\r\n // tries to commit the edit when going from one editor to another on the grid\r\n // through the click event. If the timeout was not here it would\r\n // try to commit/destroy the editor twice, which would throw a jquery\r\n // error about the element not being in the DOM\r\n setTimeout(() => {\r\n // make sure the target is the active editor so we do not\r\n // commit prematurely\r\n if (activeNode && activeNode.contains(target) && this.grid.getEditorLock().isActive()) {\r\n this.grid.getEditorLock().commitCurrentEdit();\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Define our internal Post Process callback, it will execute internally after we get back result from the Process backend call\r\n * For now, this is GraphQL Service ONLY feature and it will basically refresh the Dataset & Pagination without having the user to create his own PostProcess every time\r\n */\r\n createBackendApiInternalPostProcessCallback(gridOptions: GridOption) {\r\n if (gridOptions && gridOptions.backendServiceApi) {\r\n const backendApi = gridOptions.backendServiceApi;\r\n\r\n // internalPostProcess only works with a GraphQL Service, so make sure it is that type\r\n if (backendApi && backendApi.service && backendApi.service instanceof GraphqlService) {\r\n backendApi.internalPostProcess = (processResult: any) => {\r\n const datasetName = (backendApi && backendApi.service && typeof backendApi.service.getDatasetName === 'function') ? backendApi.service.getDatasetName() : '';\r\n if (processResult && processResult.data && processResult.data[datasetName]) {\r\n this._dataset = processResult.data[datasetName].nodes;\r\n this.refreshGridData(this._dataset, processResult.data[datasetName].totalCount);\r\n } else {\r\n this._dataset = [];\r\n }\r\n };\r\n }\r\n }\r\n }\r\n\r\n bindDifferentHooks(grid: any, gridOptions: GridOption, dataView: any) {\r\n // on locale change, we have to manually translate the Headers, GridMenu\r\n this.subscriptions.push(\r\n this.translate.onLangChange.subscribe((event) => {\r\n if (gridOptions.enableTranslate) {\r\n this.extensionService.translateColumnHeaders();\r\n this.extensionService.translateColumnPicker();\r\n this.extensionService.translateGridMenu();\r\n this.extensionService.translateHeaderMenu();\r\n }\r\n })\r\n );\r\n\r\n // if user entered some Columns \"presets\", we need to reflect them all in the grid\r\n if (gridOptions.presets && Array.isArray(gridOptions.presets.columns) && gridOptions.presets.columns.length > 0) {\r\n const gridColumns: Column[] = this.gridStateService.getAssociatedGridColumns(grid, gridOptions.presets.columns);\r\n if (gridColumns && Array.isArray(gridColumns) && gridColumns.length > 0) {\r\n // make sure that the checkbox selector is also visible if it is enabled\r\n if (gridOptions.enableCheckboxSelector) {\r\n const checkboxColumn = (Array.isArray(this._columnDefinitions) && this._columnDefinitions.length > 0) ? this._columnDefinitions[0] : null;\r\n if (checkboxColumn && checkboxColumn.id === '_checkbox_selector' && gridColumns[0].id !== '_checkbox_selector') {\r\n gridColumns.unshift(checkboxColumn);\r\n }\r\n }\r\n\r\n // finally set the new presets columns (including checkbox selector if need be)\r\n grid.setColumns(gridColumns);\r\n }\r\n }\r\n\r\n // bind external sorting (backend) when available or default onSort (dataView)\r\n if (gridOptions.enableSorting && !this.customDataView) {\r\n gridOptions.backendServiceApi ? this.sortService.bindBackendOnSort(grid, dataView) : this.sortService.bindLocalOnSort(grid, dataView);\r\n }\r\n\r\n // bind external filter (backend) when available or default onFilter (dataView)\r\n if (gridOptions.enableFiltering && !this.customDataView) {\r\n this.filterService.init(grid);\r\n\r\n // if user entered some Filter \"presets\", we need to reflect them all in the DOM\r\n if (gridOptions.presets && Array.isArray(gridOptions.presets.filters) && gridOptions.presets.filters.length > 0) {\r\n this.filterService.populateColumnFilterSearchTerms();\r\n }\r\n gridOptions.backendServiceApi ? this.filterService.bindBackendOnFilter(grid, this.dataView) : this.filterService.bindLocalOnFilter(grid, this.dataView);\r\n }\r\n\r\n // if user set an onInit Backend, we'll run it right away (and if so, we also need to run preProcess, internalPostProcess & postProcess)\r\n if (gridOptions.backendServiceApi) {\r\n const backendApi = gridOptions.backendServiceApi;\r\n\r\n if (backendApi && backendApi.service && backendApi.service.init) {\r\n backendApi.service.init(backendApi.options, gridOptions.pagination, this.grid);\r\n }\r\n }\r\n\r\n // expose all Slick Grid Events through dispatch\r\n for (const prop in grid) {\r\n if (grid.hasOwnProperty(prop) && prop.startsWith('on')) {\r\n this._eventHandler.subscribe(grid[prop], (e: any, args: any) => {\r\n return this.dispatchCustomEvent(`${slickgridEventPrefix}${titleCase(prop)}`, { eventData: e, args });\r\n });\r\n }\r\n }\r\n\r\n // expose all Slick DataView Events through dispatch\r\n for (const prop in dataView) {\r\n if (dataView.hasOwnProperty(prop) && prop.startsWith('on')) {\r\n this._eventHandler.subscribe(dataView[prop], (e: any, args: any) => {\r\n return this.dispatchCustomEvent(`${slickgridEventPrefix}${titleCase(prop)}`, { eventData: e, args });\r\n });\r\n }\r\n }\r\n\r\n // expose GridState Service changes event through dispatch\r\n this.subscriptions.push(\r\n this.gridStateService.onGridStateChanged.subscribe((gridStateChange: GridStateChange) => {\r\n this.onGridStateChanged.emit(gridStateChange);\r\n })\r\n );\r\n\r\n\r\n // on cell click, mainly used with the columnDef.action callback\r\n this.gridEventService.bindOnCellChange(grid, dataView);\r\n this.gridEventService.bindOnClick(grid, dataView);\r\n\r\n if (dataView && grid) {\r\n this._eventHandler.subscribe(dataView.onRowCountChanged, (e: any, args: any) => {\r\n grid.invalidate();\r\n });\r\n\r\n // without this, filtering data with local dataset will not always show correctly\r\n // also don't use \"invalidateRows\" since it destroys the entire row and as bad user experience when updating a row\r\n // see commit: https://github.com/ghiscoding/Angular-Slickgrid/commit/bb62c0aa2314a5d61188ff005ccb564577f08805\r\n if (gridOptions && gridOptions.enableFiltering && !gridOptions.enableRowDetailView) {\r\n this._eventHandler.subscribe(dataView.onRowsChanged, (e: any, args: any) => {\r\n if (args && args.rows && Array.isArray(args.rows)) {\r\n args.rows.forEach((row) => grid.updateRow(row));\r\n grid.render();\r\n }\r\n });\r\n }\r\n }\r\n\r\n // does the user have a colspan callback?\r\n if (gridOptions.colspanCallback) {\r\n this.dataView.getItemMetadata = (rowNumber: number) => {\r\n const item = this.dataView.getItem(rowNumber);\r\n return gridOptions.colspanCallback(item);\r\n };\r\n }\r\n }\r\n\r\n bindBackendCallbackFunctions(gridOptions: GridOption) {\r\n const backendApi = gridOptions.backendServiceApi;\r\n const serviceOptions: BackendServiceOption = (backendApi && backendApi.service && backendApi.service.options) ? backendApi.service.options : {};\r\n const isExecuteCommandOnInit = (!serviceOptions) ? false : ((serviceOptions && serviceOptions.hasOwnProperty('executeProcessCommandOnInit')) ? serviceOptions['executeProcessCommandOnInit'] : true);\r\n\r\n // update backend filters (if need be) before the query runs\r\n if (backendApi) {\r\n const backendService = backendApi.service;\r\n\r\n // if user entered some any \"presets\", we need to reflect them all in the grid\r\n if (gridOptions && gridOptions.presets) {\r\n // Filters \"presets\"\r\n if (backendService && backendService.updateFilters && Array.isArray(gridOptions.presets.filters) && gridOptions.presets.filters.length > 0) {\r\n backendService.updateFilters(gridOptions.presets.filters, true);\r\n }\r\n // Sorters \"presets\"\r\n if (backendService && backendService.updateSorters && Array.isArray(gridOptions.presets.sorters) && gridOptions.presets.sorters.length > 0) {\r\n backendService.updateSorters(undefined, gridOptions.presets.sorters);\r\n }\r\n // Pagination \"presets\"\r\n if (backendService && backendService.updatePagination && gridOptions.presets.pagination) {\r\n backendService.updatePagination(gridOptions.presets.pagination.pageNumber, gridOptions.presets.pagination.pageSize);\r\n }\r\n } else {\r\n const columnFilters = this.filterService.getColumnFilters();\r\n if (columnFilters && backendService && backendService.updateFilters) {\r\n backendService.updateFilters(columnFilters, false);\r\n }\r\n }\r\n }\r\n\r\n if (backendApi && backendApi.service && (backendApi.onInit || isExecuteCommandOnInit)) {\r\n const query = (typeof backendApi.service.buildQuery === 'function') ? backendApi.service.buildQuery() : '';\r\n const process = (isExecuteCommandOnInit) ? backendApi.process(query) : backendApi.onInit(query);\r\n\r\n // wrap this inside a setTimeout to avoid timing issue since the gridOptions needs to be ready before running this onInit\r\n setTimeout(() => {\r\n // keep start time & end timestamps & return it after process execution\r\n const startTime = new Date();\r\n\r\n // run any pre-process, if defined, for example a spinner\r\n if (backendApi.preProcess) {\r\n backendApi.preProcess();\r\n }\r\n\r\n try {\r\n // the processes can be Observables (like HttpClient) or Promises\r\n if (process instanceof Promise && process.then) {\r\n process.then((processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this.gridOptions));\r\n } else if (isObservable(process)) {\r\n process.subscribe(\r\n (processResult: GraphqlResult | any) => executeBackendProcessesCallback(startTime, processResult, backendApi, this.gridOptions),\r\n (error: any) => onBackendError(error, backendApi)\r\n );\r\n }\r\n } catch (error) {\r\n onBackendError(error, backendApi);\r\n }\r\n });\r\n }\r\n }\r\n\r\n bindResizeHook(grid: any, options: GridOption) {\r\n // expand/autofit columns on first page load\r\n if (grid && options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns) {\r\n grid.autosizeColumns();\r\n\r\n // compensate anytime SlickGrid measureScrollbar is incorrect (only seems to happen in Chrome 1/5 computers)\r\n this.resizer.compensateHorizontalScroll(this.grid, this.gridOptions);\r\n }\r\n\r\n // auto-resize grid on browser resize\r\n if (this._fixedHeight || this._fixedWidth) {\r\n this.resizer.init(grid, { height: this._fixedHeight, width: this._fixedWidth });\r\n } else {\r\n this.resizer.init(grid);\r\n }\r\n if (options.enableAutoResize) {\r\n this.resizer.bindAutoResizeDataGrid();\r\n if (grid && options.autoFitColumnsOnFirstLoad && options.enableAutoSizeColumns) {\r\n grid.autosizeColumns();\r\n }\r\n }\r\n }\r\n\r\n executeAfterDataviewCreated(grid: any, gridOptions: GridOption, dataView: any) {\r\n // if user entered some Sort \"presets\", we need to reflect them all in the DOM\r\n if (gridOptions.enableSorting) {\r\n if (gridOptions.presets && Array.isArray(gridOptions.presets.sorters) && gridOptions.presets.sorters.length > 0) {\r\n this.sortService.loadLocalGridPresets(grid, dataView);\r\n }\r\n }\r\n }\r\n\r\n mergeGridOptions(gridOptions): GridOption {\r\n gridOptions.gridId = this.gridId;\r\n gridOptions.gridContainerId = `slickGridContainer-${this.gridId}`;\r\n\r\n // use jquery extend to deep merge & copy to avoid immutable properties being changed in GlobalGridOptions after a route change\r\n const options = $.extend(true, {}, GlobalGridOptions, this.forRootConfig, gridOptions);\r\n\r\n // using jQuery extend to do a deep clone has an unwanted side on objects and pageSizes but ES6 spread has other worst side effects\r\n // so we will just overwrite the pageSizes when needed, this is the only one causing issues so far.\r\n // jQuery wrote this on their docs:: On a deep extend, Object and Array are extended, but object wrappers on primitive types such as String, Boolean, and Number are not.\r\n if (gridOptions && gridOptions.backendServiceApi) {\r\n if (gridOptions.pagination && Array.isArray(gridOptions.pagination.pageSizes) && gridOptions.pagination.pageSizes.length > 0) {\r\n options.pagination.pageSizes = gridOptions.pagination.pageSizes;\r\n }\r\n }\r\n\r\n // also make sure to show the header row if user have enabled filtering\r\n this._hideHeaderRowAfterPageLoad = (options.showHeaderRow === false);\r\n if (options.enableFiltering && !options.showHeaderRow) {\r\n options.showHeaderRow = options.enableFiltering;\r\n }\r\n return options;\r\n }\r\n\r\n /**\r\n * On a Pagination changed, we will trigger a Grid State changed with the new pagination info\r\n * Also if we use Row Selection or the Checkbox Selector, we need to reset any selection\r\n */\r\n paginationChanged(pagination: Pagination) {\r\n if (this.gridOptions.enableRowSelection || this.gridOptions.enableCheckboxSelector) {\r\n this.gridService.setSelectedRows([]);\r\n }\r\n\r\n this.gridStateService.onGridStateChanged.next({\r\n change: { newValues: pagination, type: GridStateType.pagination },\r\n gridState: this.gridStateService.getCurrentGridState()\r\n });\r\n }\r\n\r\n /**\r\n * When dataset changes, we need to refresh the entire grid UI & possibly resize it as well\r\n * @param dataset\r\n */\r\n refreshGridData(dataset: any[], totalCount?: number) {\r\n if (Array.isArray(dataset) && this.grid && this.dataView && typeof this.dataView.setItems === 'function') {\r\n this.dataView.setItems(dataset, this.gridOptions.datasetIdPropertyName);\r\n if (!this.gridOptions.backendServiceApi) {\r\n this.dataView.reSort();\r\n }\r\n\r\n if (dataset) {\r\n this.grid.invalidate();\r\n this.grid.render();\r\n }\r\n\r\n if (this.gridOptions.backendServiceApi) {\r\n // do we want to show pagination?\r\n // if we have a backendServiceApi and the enablePagination is undefined, we'll assume that we do want to see it, else get that defined value\r\n this.showPagination = ((this.gridOptions.backendServiceApi && this.gridOptions.enablePagination === undefined) ? true : this.gridOptions.enablePagination) || false;\r\n\r\n // before merging the grid options, make sure that it has the totalItems count\r\n // once we have that, we can merge and pass all these options to the pagination component\r\n if (!this.gridOptions.pagination) {\r\n this.gridOptions.pagination = (this.gridOptions.pagination) ? this.gridOptions.pagination : undefined;\r\n }\r\n if (this.gridOptions.pagination && totalCount !== undefined) {\r\n this.gridOptions.pagination.totalItems = totalCount;\r\n }\r\n if (this.gridOptions.presets && this.gridOptions.presets.pagination && this.gridOptions.pagination) {\r\n this.gridOptions.pagination.pageSize = this.gridOptions.presets.pagination.pageSize;\r\n this.gridOptions.pagination.pageNumber = this.gridOptions.presets.pagination.pageNumber;\r\n }\r\n this.gridPaginationOptions = this.mergeGridOptions(this.gridOptions);\r\n }\r\n\r\n // resize the grid inside a slight timeout, in case other DOM element changed prior to the resize (like a filter/pagination changed)\r\n if (this.grid && this.gridOptions.enableAutoResize) {\r\n const delay = this.gridOptions.autoResize && this.gridOptions.autoResize.delay;\r\n this.resizer.resizeGrid(delay || 10);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Dynamically change or update the column definitions list.\r\n * We will re-render the grid so that the new header and data shows up correctly.\r\n * If using i18n, we also need to trigger a re-translate of the column headers\r\n */\r\n updateColumnDefinitionsList(newColumnDefinitions) {\r\n // map/swap the internal library Editor to the SlickGrid Editor factory\r\n newColumnDefinitions = this.swapInternalEditorToSlickGridFactoryEditor(newColumnDefinitions);\r\n\r\n if (this.gridOptions.enableTranslate) {\r\n this.extensionService.translateColumnHeaders(false, newColumnDefinitions);\r\n } else {\r\n this.extensionService.renderColumnHeaders(newColumnDefinitions);\r\n }\r\n\r\n if (this.gridOptions && this.gridOptions.enableAutoSizeColumns) {\r\n this.grid.autosizeColumns();\r\n }\r\n }\r\n\r\n /** Toggle the filter row displayed on first row\r\n * @param isShowing\r\n */\r\n showHeaderRow(isShowing: boolean) {\r\n this.grid.setHeaderRowVisibility(isShowing);\r\n return isShowing;\r\n }\r\n\r\n /** Toggle the filter row displayed on first row */\r\n toggleHeaderRow() {\r\n const isShowing = !this.grid.getOptions().showHeaderRow;\r\n this.grid.setHeaderRowVisibility(isShowing);\r\n return isShowing;\r\n }\r\n\r\n //\r\n // private functions\r\n // ------------------\r\n\r\n /** Dispatch of Custom Event, which by default will bubble & is cancelable */\r\n private dispatchCustomEvent(eventName: string, data?: any, isBubbling: boolean = true, isCancelable: boolean = true) {\r\n const eventInit: CustomEventInit = { bubbles: isBubbling, cancelable: isCancelable };\r\n if (data) {\r\n eventInit.detail = data;\r\n }\r\n return this.elm.nativeElement.dispatchEvent(new CustomEvent(eventName, eventInit));\r\n }\r\n\r\n /** Load the Editor Collection asynchronously and replace the \"collection\" property when Observable resolves */\r\n private loadEditorCollectionAsync(column: Column) {\r\n const collectionAsync = column && column.editor && column.editor.collectionAsync;\r\n if (collectionAsync instanceof Observable) {\r\n this.subscriptions.push(\r\n collectionAsync.subscribe((resolvedCollection) => this.updateEditorCollection(column, resolvedCollection))\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * For convenience to the user, we provide the property \"editor\" as an Angular-Slickgrid editor complex object\r\n * however \"editor\" is used internally by SlickGrid for it's own Editor Factory\r\n * so in our lib we will swap \"editor\" and copy it into a new property called \"internalColumnEditor\"\r\n * then take back \"editor.model\" and make it the new \"editor\" so that SlickGrid Editor Factory still works\r\n */\r\n private swapInternalEditorToSlickGridFactoryEditor(columnDefinitions: Column[]) {\r\n return columnDefinitions.map((column: Column | any) => {\r\n // on every Editor that have a \"collectionAsync\", resolve the data and assign it to the \"collection\" property\r\n if (column.editor && column.editor.collectionAsync) {\r\n this.loadEditorCollectionAsync(column);\r\n }\r\n return { ...column, editor: column.editor && column.editor.model, internalColumnEditor: { ...column.editor } };\r\n });\r\n }\r\n\r\n /**\r\n * Update the Editor \"collection\" property from an async call resolved\r\n * Since this is called after the async call resolves, the pointer will not be the same as the \"column\" argument passed.\r\n * Once we found the new pointer, we will reassign the \"editor\" and \"collection\" to the \"internalColumnEditor\" so it has newest collection\r\n */\r\n private updateEditorCollection(column: Column, newCollection: any[]) {\r\n column.editor.collection = newCollection;\r\n\r\n // find the new column reference pointer\r\n const columns = this.grid.getColumns();\r\n if (Array.isArray(columns)) {\r\n const columnRef: Column = columns.find((col: Column) => col.id === column.id);\r\n columnRef.internalColumnEditor = column.editor;\r\n }\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { NgModule } from '@angular/core';\r\nimport { TranslateModule } from '@ngx-translate/core';\r\nimport { AngularUtilService } from '../services/angularUtil.service';\r\nimport { AngularSlickgridComponent } from './../components/angular-slickgrid.component';\r\nimport { CollectionService } from './../services/collection.service';\r\nimport { FilterFactory } from '../filters/filterFactory';\r\nimport { GraphqlService } from './../services/graphql.service';\r\nimport { GridOdataService } from './../services/grid-odata.service';\r\nimport { GridOption } from './../models/gridOption.interface';\r\nimport { SlickPaginationComponent } from './../components/slick-pagination.component';\r\n\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n TranslateModule\r\n ],\r\n declarations: [\r\n AngularSlickgridComponent,\r\n SlickPaginationComponent\r\n ],\r\n exports: [\r\n AngularSlickgridComponent,\r\n SlickPaginationComponent\r\n ],\r\n entryComponents: [AngularSlickgridComponent]\r\n})\r\nexport class AngularSlickgridModule {\r\n static forRoot(config: GridOption = {}) {\r\n return {\r\n ngModule: AngularSlickgridModule,\r\n providers: [\r\n { provide: 'config', useValue: config },\r\n AngularUtilService,\r\n CollectionService,\r\n FilterFactory,\r\n GraphqlService,\r\n GridOdataService\r\n ]\r\n };\r\n }\r\n}\r\n"]}
\No newline at end of file