├── .editorconfig ├── .gitignore ├── .npmignore ├── .vscode ├── settings.json └── tasks.json ├── LICENSE ├── README.md ├── angular2Migration.md ├── bootstrapper ├── app.html ├── app.ng2.ts ├── app.routing.ts ├── app.ts ├── bootstrapper.css ├── buttons │ ├── buttonBootstrapper.ts │ ├── buttonRoot.ts │ ├── buttons.html │ ├── buttonsNg1.html │ ├── buttonsNg2.html │ └── buttonsNg2Bootstrapper.ts ├── cards │ ├── cardContainerBootstrapper.ts │ ├── cardRoot.ts │ ├── cards.html │ ├── cardsNg1.html │ ├── cardsNg2.html │ ├── cardsNg2Bootstrapper.ts │ ├── cardsSmartData.html │ └── cardsSmartDataBootstrapper.ts ├── forms │ ├── forms.html │ ├── formsBootstrapper.ts │ ├── formsNg1.html │ ├── formsNg2.html │ ├── formsNg2Bootstrapper.ts │ └── formsRoot.ts ├── inputs │ ├── inputBootstrapper.ts │ ├── inputRoot.ts │ ├── inputs.html │ ├── inputsNg1.html │ ├── inputsNg2.html │ └── inputsNg2Bootstrapper.ts ├── main.ts ├── messageLog │ ├── messageLogNg1Bootstrapper.ts │ ├── messageLogNg1Test.html │ ├── messageLogNg2Bootstrapper.html │ ├── messageLogNg2Bootstrapper.ts │ ├── messageLogRoot.html │ └── messageLogRoot.ts ├── misc │ ├── misc.html │ ├── miscBootstrapper.ts │ ├── miscNg1.html │ ├── miscNg2.html │ ├── miscNg2Context.html │ ├── miscNg2Context.ts │ └── miscRoot.ts ├── msi │ ├── msi.ng2.html │ └── msiBootstrapper.ng2.ts ├── popup │ ├── popup.html │ ├── popupBootstrapper.ts │ ├── popupNg1.html │ ├── popupNg2.html │ ├── popupNg2Bootstrapper.ts │ └── popupRoot.ts ├── tabs │ ├── tabRoot.ts │ ├── tabs.html │ ├── tabsBootstrapper.ts │ ├── tabsNg1.html │ ├── tabsNg2.html │ └── tabsNg2Bootstrapper.ts ├── text │ └── text.ts └── welcome.component.ts ├── gulpfile.js ├── index.html ├── karma-test-setup.js ├── karma.conf.js ├── karma.debug.conf.js ├── karma.full.conf.js ├── karma.shared.conf.js ├── karma.tc.conf.js ├── libraries ├── angular-bootstrap-slider │ ├── bootstrap-slider.min.css │ ├── bootstrap-slider.min.js │ └── slider.js ├── bootstrap-datetimepicker │ ├── bootstrap-datetimepicker.css │ ├── bootstrap-datetimepicker.js │ └── index.js ├── bootstrap-touchspin │ ├── index.js │ ├── jquery.bootstrap-touchspin.css │ └── jquery.bootstrap-touchspin.js └── jSignature │ └── jSignature.min.js ├── package.json ├── source ├── animations │ ├── index.ts │ └── slide │ │ └── slide.animate.ts ├── behaviors │ ├── alias │ │ ├── alias.md │ │ ├── alias.tests.ts │ │ └── alias.ts │ ├── alternatingClass │ │ └── alternatingClass.ts │ ├── autosave │ │ ├── autosave.md │ │ ├── autosave.ng1.tests.ts │ │ ├── autosave.ng1.ts │ │ ├── autosave.tests.ts │ │ └── autosave.ts │ ├── behaviors.module.ts │ ├── focusOn │ │ └── focusOn.ng1.ts │ ├── index.ts │ ├── offClick │ │ ├── offClick.ng1.ts │ │ └── offClick.ts │ ├── popover │ │ ├── popover.md │ │ └── popover.ts │ ├── required │ │ ├── required.md │ │ └── required.ts │ └── stopEventPropagation │ │ ├── stopEventPropagation.md │ │ └── stopEventPropagation.ts ├── componentProviders.module.ts ├── components │ ├── busy │ │ ├── busy.css │ │ ├── busy.html │ │ ├── busy.md │ │ ├── busy.module.ts │ │ ├── busy.ng1.ts │ │ ├── busy.tests.ts │ │ └── busy.ts │ ├── buttons │ │ ├── baseButton.tests.ts │ │ ├── baseButton.ts │ │ ├── button.module.ts │ │ ├── button │ │ │ ├── button.html │ │ │ ├── button.md │ │ │ ├── button.ng1.html │ │ │ ├── button.ng1.ts │ │ │ └── button.ts │ │ ├── buttonAsync │ │ │ ├── buttonAsync.html │ │ │ ├── buttonAsync.md │ │ │ ├── buttonAsync.ng1.html │ │ │ ├── buttonAsync.ng1.tests.ts │ │ │ ├── buttonAsync.ng1.ts │ │ │ ├── buttonAsync.tests.ts │ │ │ └── buttonAsync.ts │ │ ├── buttonLink │ │ │ ├── buttonLink.html │ │ │ ├── buttonLink.md │ │ │ ├── buttonLink.ng1.html │ │ │ ├── buttonLink.ng1.ts │ │ │ ├── buttonLink.tests.ts │ │ │ └── buttonLink.ts │ │ ├── buttonLongClick │ │ │ ├── buttonLongClick.html │ │ │ ├── buttonLongClick.md │ │ │ ├── buttonLongClick.ng1.html │ │ │ ├── buttonLongClick.ng1.ts │ │ │ ├── buttonLongClick.tests.ts │ │ │ └── buttonLongClick.ts │ │ ├── buttonRoute │ │ │ ├── buttonRoute.html │ │ │ ├── buttonRoute.tests.ts │ │ │ └── buttonRoute.ts │ │ ├── buttonSubmit │ │ │ ├── buttonSubmit.html │ │ │ ├── buttonSubmit.md │ │ │ ├── buttonSubmit.ng1.html │ │ │ ├── buttonSubmit.ng1.ts │ │ │ ├── buttonSubmit.tests.ts │ │ │ └── buttonSubmit.ts │ │ ├── buttonToggle │ │ │ ├── buttonToggle.html │ │ │ ├── buttonToggle.md │ │ │ ├── buttonToggle.ng1.html │ │ │ ├── buttonToggle.ng1.tests.ts │ │ │ ├── buttonToggle.ng1.ts │ │ │ ├── buttonToggle.tests.ts │ │ │ └── buttonToggle.ts │ │ ├── buttons.md │ │ └── index.ts │ ├── cardContainer │ │ ├── builder │ │ │ ├── cardContainerBuilder.service.ts │ │ │ ├── cardContainerBuilderOld.service.ts │ │ │ ├── dataSourceBuilderOld.service.ts │ │ │ ├── filterBuilderOld.service.ts │ │ │ └── index.ts │ │ ├── card │ │ │ ├── card.html │ │ │ ├── card.ng1.html │ │ │ ├── card.ng1.tests.ts │ │ │ ├── card.ng1.ts │ │ │ ├── card.tests.ts │ │ │ ├── card.ts │ │ │ ├── headerColumn │ │ │ │ ├── headerColumn.html │ │ │ │ ├── headerColumn.module.ts │ │ │ │ ├── headerColumn.ng1.ts │ │ │ │ ├── headerColumn.tests.ts │ │ │ │ ├── headerColumn.ts │ │ │ │ ├── sizeForBreakpoints.ng1.ts │ │ │ │ ├── sizeForBreakpoints.tests.ts │ │ │ │ └── sizeForBreakpoints.ts │ │ │ ├── selectableCard.html │ │ │ ├── selectableCard.tests.ts │ │ │ └── selectableCard.ts │ │ ├── cardContainer.css │ │ ├── cardContainer.html │ │ ├── cardContainer.module.ts │ │ ├── cardContainer.ng1.html │ │ ├── cardContainer.ng1.tests.ts │ │ ├── cardContainer.ng1.ts │ │ ├── cardContainer.tests.ts │ │ ├── cardContainer.ts │ │ ├── column.ts │ │ ├── container │ │ │ ├── cardSearch │ │ │ │ ├── cardSearch.html │ │ │ │ ├── cardSearch.ng1.html │ │ │ │ ├── cardSearch.ng1.tests.ts │ │ │ │ ├── cardSearch.ng1.ts │ │ │ │ ├── cardSearch.tests.ts │ │ │ │ └── cardSearch.ts │ │ │ ├── columnHeader │ │ │ │ ├── columnHeader.html │ │ │ │ ├── columnHeader.ng1.ts │ │ │ │ ├── columnHeader.tests.ts │ │ │ │ └── columnHeader.ts │ │ │ ├── containerFooter.component.html │ │ │ ├── containerFooter.component.ts │ │ │ ├── containerHeader.component.html │ │ │ ├── containerHeader.component.ts │ │ │ ├── defaultCardContainerFooter.html │ │ │ ├── defaultCardContainerHeader.html │ │ │ ├── defaultComponents.ts │ │ │ ├── index.ts │ │ │ ├── itemCount │ │ │ │ ├── itemCount.html │ │ │ │ ├── itemCount.ng1.html │ │ │ │ ├── itemCount.ng1.ts │ │ │ │ ├── itemCount.tests.ts │ │ │ │ └── itemCount.ts │ │ │ ├── selectableContainerFooter.component.html │ │ │ ├── selectableContainerFooter.component.ts │ │ │ └── selectionControl │ │ │ │ ├── selectionControl.html │ │ │ │ ├── selectionControl.ng1.html │ │ │ │ ├── selectionControl.ng1.tests.ts │ │ │ │ ├── selectionControl.ng1.ts │ │ │ │ ├── selectionControl.tests.ts │ │ │ │ └── selectionControl.ts │ │ ├── dataSources │ │ │ ├── asyncDataSource.service.tests.ts │ │ │ ├── asyncDataSource.service.ts │ │ │ ├── asyncTypes.ts │ │ │ ├── clientServerDataSource │ │ │ │ ├── clientServerDataSource.service.tests.ts │ │ │ │ └── clientServerDataSource.service.ts │ │ │ ├── dataServiceDataSource │ │ │ │ ├── dataServiceDataSource.service.tests.ts │ │ │ │ └── dataServiceDataSource.service.ts │ │ │ ├── dataSource.ts │ │ │ ├── dataSourceBase.service.tests.ts │ │ │ ├── dataSourceBase.service.ts │ │ │ ├── dataSourceBaseOld.service.tests.ts │ │ │ ├── dataSourceBaseOld.service.ts │ │ │ ├── index.ts │ │ │ ├── observableDataSource │ │ │ │ ├── observableDataSource.service.tests.ts │ │ │ │ └── observableDataSource.service.ts │ │ │ ├── processor │ │ │ │ ├── dataSourceProcessor.tests.ts │ │ │ │ ├── dataSourceProcessor.ts │ │ │ │ ├── dataSourceProcessorOld.service.tests.ts │ │ │ │ └── dataSourceProcessorOld.service.ts │ │ │ ├── serverSideDataSource │ │ │ │ ├── serverSideDataSource.service.tests.ts │ │ │ │ └── serverSideDataSource.service.ts │ │ │ ├── simpleDataSource │ │ │ │ ├── simpleDataSource.service.tests.ts │ │ │ │ └── simpleDataSource.service.ts │ │ │ └── smartDataSource │ │ │ │ ├── smartDataActions.tests.ts │ │ │ │ ├── smartDataActions.ts │ │ │ │ ├── smartDataSource.service.tests.ts │ │ │ │ ├── smartDataSource.service.ts │ │ │ │ ├── smartDataSourceOld.service.tests.ts │ │ │ │ └── smartDataSourceOld.service.ts │ │ ├── filters │ │ │ ├── cardContainerFilters.html │ │ │ ├── cardContainerFilters.ts │ │ │ ├── columnSearchFilter │ │ │ │ ├── columnSearchFilter.service.tests.ts │ │ │ │ └── columnSearchFilter.service.ts │ │ │ ├── dateFilter │ │ │ │ ├── dateFilter.component.ng1.ts │ │ │ │ ├── dateFilter.component.tests.ts │ │ │ │ ├── dateFilter.component.ts │ │ │ │ ├── dateFilter.html │ │ │ │ ├── dateFilter.module.ts │ │ │ │ ├── dateFilter.ng1.html │ │ │ │ ├── dateFilter.service.tests.ts │ │ │ │ ├── dateFilter.service.ts │ │ │ │ ├── dateFilterOld.service.tests.ts │ │ │ │ ├── dateFilterOld.service.ts │ │ │ │ └── index.ts │ │ │ ├── filter.tests.ts │ │ │ ├── filter.ts │ │ │ ├── filterGroup │ │ │ │ ├── filterGroup.component.html │ │ │ │ ├── filterGroup.component.tests.ts │ │ │ │ ├── filterGroup.component.ts │ │ │ │ ├── filterGroup.directive.ng1.html │ │ │ │ ├── filterGroup.directive.ng1.ts │ │ │ │ ├── filterGroup.module.ts │ │ │ │ ├── filterGroup.service.tests.ts │ │ │ │ ├── filterGroup.service.ts │ │ │ │ ├── filterGroupOld.service.tests.ts │ │ │ │ ├── filterGroupOld.service.ts │ │ │ │ ├── filterOption │ │ │ │ │ ├── filterOption.html │ │ │ │ │ ├── filterOption.ng1.html │ │ │ │ │ ├── filterOption.ng1.ts │ │ │ │ │ └── filterOption.ts │ │ │ │ ├── index.ts │ │ │ │ ├── modeFilterGroup │ │ │ │ │ ├── modeFilterGroup.service.tests.ts │ │ │ │ │ ├── modeFilterGroup.service.ts │ │ │ │ │ ├── modeFilterGroupOld.service.tests.ts │ │ │ │ │ └── modeFilterGroupOld.service.ts │ │ │ │ └── rangeFilterGroup │ │ │ │ │ ├── rangeFilterGroup.service.tests.ts │ │ │ │ │ ├── rangeFilterGroup.service.ts │ │ │ │ │ ├── rangeFilterGroupOld.service.tests.ts │ │ │ │ │ └── rangeFilterGroupOld.service.ts │ │ │ ├── filters.module.ts │ │ │ ├── index.ts │ │ │ ├── searchFilter │ │ │ │ ├── searchFilter.service.tests.ts │ │ │ │ └── searchFilter.service.ts │ │ │ └── selectFilter │ │ │ │ ├── index.ts │ │ │ │ ├── selectFilter.component.ng1.ts │ │ │ │ ├── selectFilter.component.ts │ │ │ │ ├── selectFilter.html │ │ │ │ ├── selectFilter.module.ts │ │ │ │ ├── selectFilter.ng1.html │ │ │ │ ├── selectFilter.service.tests.ts │ │ │ │ ├── selectFilter.service.ts │ │ │ │ ├── selectFilterOld.service.tests.ts │ │ │ │ └── selectFilterOld.service.ts │ │ ├── index.ts │ │ ├── paging │ │ │ ├── dataPager │ │ │ │ ├── dataPager.service.tests.ts │ │ │ │ ├── dataPager.service.ts │ │ │ │ ├── dataPagerOld.service.tests.ts │ │ │ │ └── dataPagerOld.service.ts │ │ │ ├── index.ts │ │ │ ├── pageSize │ │ │ │ ├── pageSize.html │ │ │ │ ├── pageSize.ng1.html │ │ │ │ ├── pageSize.ng1.ts │ │ │ │ ├── pageSize.tests.ts │ │ │ │ └── pageSize.ts │ │ │ └── pager │ │ │ │ ├── pager.html │ │ │ │ ├── pager.ng1.html │ │ │ │ ├── pager.ng1.tests.ts │ │ │ │ ├── pager.ng1.ts │ │ │ │ ├── pager.tests.ts │ │ │ │ └── pager.ts │ │ ├── selectableCardContainer.html │ │ ├── selectableCardContainer.tests.ts │ │ ├── selectableCardContainer.ts │ │ ├── sorts │ │ │ ├── index.ts │ │ │ ├── mergeSort │ │ │ │ ├── mergeSort.service.tests.ts │ │ │ │ └── mergeSort.service.ts │ │ │ ├── sort.ts │ │ │ ├── sortDirection.ts │ │ │ ├── sortManager │ │ │ │ ├── sortManager.service.tests.ts │ │ │ │ └── sortManager.service.ts │ │ │ └── sorter │ │ │ │ ├── sorter.service.tests.ts │ │ │ │ └── sorter.service.ts │ │ └── templates │ │ │ ├── columnContent.template.ts │ │ │ ├── columnHeader.template.ts │ │ │ ├── containerFooter.template.ts │ │ │ ├── containerHeader.template.ts │ │ │ └── index.ts │ ├── cards │ │ ├── cardContent.template.ts │ │ ├── cardFooter.template.ts │ │ ├── cardHeader.template.ts │ │ └── index.ts │ ├── commaList │ │ ├── commaList.html │ │ ├── commaList.md │ │ ├── commaList.ng1.tests.ts │ │ ├── commaList.ng1.ts │ │ ├── commaList.tests.ts │ │ └── commaList.ts │ ├── components.module.ts │ ├── componentsDefaultTheme.ts │ ├── dateTimeStatic │ │ ├── dateTimeStatic.html │ │ ├── dateTimeStatic.md │ │ └── dateTimeStatic.ts │ ├── defaultStyles.css │ ├── dialog │ │ ├── autosaveDialogFooter.html │ │ ├── dialog.md │ │ ├── dialog.ng1.html │ │ ├── dialog.ng1.ts │ │ ├── dialog.tests.ts │ │ ├── dialog.ts │ │ ├── dialogOutlet.html │ │ ├── dialogOutlet.tests.ts │ │ ├── dialogOutlet.ts │ │ ├── dialogRoot.service.tests.ts │ │ ├── dialogRoot.service.ts │ │ ├── index.ts │ │ ├── promptDialog.html │ │ ├── promptDialog.ts │ │ └── templates │ │ │ ├── dialogContent.template.ts │ │ │ ├── dialogFooter.template.ts │ │ │ ├── dialogHeader.template.ts │ │ │ └── index.ts │ ├── form │ │ ├── RecluseForm.ts │ │ ├── form.html │ │ ├── form.md │ │ ├── form.ng1.ts │ │ ├── form.tests.ts │ │ ├── form.ts │ │ └── index.ts │ ├── genericContainer │ │ ├── genericContainer.md │ │ ├── genericContainer.tests.ts │ │ └── genericContainer.ts │ ├── inputs │ │ ├── absoluteTime │ │ │ ├── absoluteTime.html │ │ │ ├── absoluteTime.tests.ts │ │ │ └── absoluteTime.ts │ │ ├── checkbox │ │ │ ├── checkbox.css │ │ │ ├── checkbox.html │ │ │ ├── checkbox.md │ │ │ ├── checkbox.ng1.html │ │ │ ├── checkbox.ng1.tests.ts │ │ │ ├── checkbox.ng1.ts │ │ │ ├── checkbox.tests.ts │ │ │ └── checkbox.ts │ │ ├── dateTime │ │ │ ├── dateTime.html │ │ │ ├── dateTime.md │ │ │ ├── dateTime.ng1.html │ │ │ ├── dateTime.ng1.ts │ │ │ └── dateTime.ts │ │ ├── index.ts │ │ ├── input.md │ │ ├── input.ng1.ts │ │ ├── input.tests.ts │ │ ├── input.ts │ │ ├── radio │ │ │ ├── index.ts │ │ │ ├── radio.css │ │ │ ├── radio.html │ │ │ ├── radio.md │ │ │ ├── radio.module.ts │ │ │ ├── radio.ng1.ts │ │ │ ├── radio.ts │ │ │ ├── radioGroup.ng1.ts │ │ │ └── radioGroup.ts │ │ ├── select │ │ │ ├── select.html │ │ │ ├── select.md │ │ │ ├── select.ng1.html │ │ │ ├── select.ng1.tests.ts │ │ │ ├── select.ng1.ts │ │ │ ├── select.tests.ts │ │ │ └── select.ts │ │ ├── signature │ │ │ ├── emptySignature.ts │ │ │ ├── signature.html │ │ │ ├── signature.tests.ts │ │ │ └── signature.ts │ │ ├── spinner │ │ │ ├── spinner.html │ │ │ ├── spinner.md │ │ │ ├── spinner.ng1.html │ │ │ ├── spinner.ng1.ts │ │ │ └── spinner.ts │ │ ├── textarea │ │ │ ├── textarea.html │ │ │ ├── textarea.md │ │ │ ├── textarea.ng1.html │ │ │ ├── textarea.ng1.ts │ │ │ └── textarea.ts │ │ ├── textbox │ │ │ ├── textbox.html │ │ │ ├── textbox.md │ │ │ ├── textbox.ng1.html │ │ │ ├── textbox.ng1.ts │ │ │ └── textbox.ts │ │ ├── typeahead │ │ │ ├── typeahead.html │ │ │ ├── typeahead.md │ │ │ ├── typeahead.ng1.html │ │ │ ├── typeahead.ng1.tests.ts │ │ │ ├── typeahead.ng1.ts │ │ │ ├── typeahead.tests.ts │ │ │ └── typeahead.ts │ │ ├── typeaheadList │ │ │ ├── defaultListItem.ng1.html │ │ │ ├── index.ts │ │ │ ├── templates │ │ │ │ ├── index.ts │ │ │ │ ├── listHeader.template.ts │ │ │ │ └── listItem.template.ts │ │ │ ├── typeaheadDataItem.ts │ │ │ ├── typeaheadItem.ng1.ts │ │ │ ├── typeaheadList.html │ │ │ ├── typeaheadList.ng1.html │ │ │ ├── typeaheadList.ng1.tests.ts │ │ │ ├── typeaheadList.ng1.ts │ │ │ ├── typeaheadList.tests.ts │ │ │ └── typeaheadList.ts │ │ ├── userRating │ │ │ ├── userRating.css │ │ │ ├── userRating.html │ │ │ ├── userRating.md │ │ │ ├── userRating.ng1.tests.ts │ │ │ ├── userRating.ng1.ts │ │ │ ├── userRating.tests.ts │ │ │ └── userRating.ts │ │ ├── validationInput.tests.ts │ │ └── validationInput.ts │ ├── lazyLoad │ │ ├── lazyLoad.md │ │ ├── lazyLoad.tests.ts │ │ └── lazyLoad.ts │ ├── messageLog │ │ ├── messageLog.component.html │ │ ├── messageLog.component.ts │ │ └── ng1 │ │ │ ├── editableMessageLog.tests.ts │ │ │ ├── editableMessageLog.ts │ │ │ ├── editedByPopover.html │ │ │ ├── messageLog.directive.tests.ts │ │ │ ├── messageLog.directive.ts │ │ │ ├── messageLog.html │ │ │ ├── messageLog.module.ts │ │ │ ├── messageLog.service.tests.ts │ │ │ ├── messageLog.service.ts │ │ │ └── messageLogEditDialog.html │ ├── multiStepIndicator │ │ ├── multiStepIndicator.html │ │ ├── multiStepIndicator.tests.ts │ │ ├── multiStepIndicator.ts │ │ ├── step.component.html │ │ ├── step.component.ts │ │ └── step.tests.ts │ ├── popoutList │ │ ├── index.ts │ │ ├── popoutItem.html │ │ ├── popoutItem.tests.ts │ │ ├── popoutItem.ts │ │ ├── popoutList.css │ │ ├── popoutList.html │ │ ├── popoutList.service.tests.ts │ │ ├── popoutList.service.ts │ │ ├── popoutList.tests.ts │ │ ├── popoutList.ts │ │ └── popoutTrigger.ts │ ├── ratingBar │ │ ├── ratingBar.css │ │ ├── ratingBar.html │ │ ├── ratingBar.ng1.tests.ts │ │ ├── ratingBar.ng1.ts │ │ ├── ratingBar.tests.ts │ │ ├── ratingBar.ts │ │ ├── ratingBarBackgrounds.service.ts │ │ └── ratingBarClass.service.ts │ ├── richTextEditor │ │ ├── editorButtons.css │ │ ├── headerButton.ts │ │ ├── paragraphButton.ts │ │ ├── richTextEditor.config.ts │ │ ├── richTextEditor.html │ │ └── richTextEditor.ts │ ├── simpleCardContainer │ │ ├── simpleCardContainer.html │ │ └── simpleCardContainer.ts │ ├── simpleCardList │ │ ├── index.ts │ │ ├── simpleCard.html │ │ ├── simpleCard.ng1.html │ │ ├── simpleCard.ng1.tests.ts │ │ ├── simpleCard.ng1.ts │ │ ├── simpleCard.tests.ts │ │ ├── simpleCard.ts │ │ ├── simpleCardList.module.ts │ │ ├── simpleCardList.ng1.tests.ts │ │ ├── simpleCardList.ng1.ts │ │ ├── simpleCardList.tests.ts │ │ └── simpleCardList.ts │ ├── stringWithWatermark │ │ ├── stringWithWatermark.html │ │ ├── stringWithWatermark.md │ │ ├── stringWithWatermark.ng1.ts │ │ └── stringWithWatermark.ts │ ├── tabs │ │ ├── ng1 │ │ │ ├── tab.css │ │ │ ├── tab.ng1.html │ │ │ ├── tab.ng1.ts │ │ │ ├── tabs.module.ts │ │ │ ├── tabset.ng1.html │ │ │ ├── tabset.ng1.tests.ts │ │ │ └── tabset.ng1.ts │ │ └── ng2 │ │ │ ├── index.ts │ │ │ ├── tab │ │ │ ├── tab.css │ │ │ ├── tab.html │ │ │ ├── tab.ts │ │ │ ├── tabContent │ │ │ │ ├── index.ts │ │ │ │ ├── tabContent.component.html │ │ │ │ ├── tabContent.component.tests.ts │ │ │ │ └── tabContent.component.ts │ │ │ ├── tabFooter │ │ │ │ ├── index.ts │ │ │ │ ├── tabFooter.component.html │ │ │ │ ├── tabFooter.component.tests.ts │ │ │ │ └── tabFooter.component.ts │ │ │ └── tabHeader │ │ │ │ ├── index.ts │ │ │ │ ├── tabHeader.component.html │ │ │ │ ├── tabHeader.component.tests.ts │ │ │ │ └── tabHeader.component.ts │ │ │ ├── tabset.html │ │ │ ├── tabset.tests.ts │ │ │ └── tabset.ts │ ├── templateRenderer │ │ └── templateRenderer.ng1.ts │ └── validationGroup │ │ ├── validationGroup.html │ │ ├── validationGroup.md │ │ ├── validationGroup.ng1.html │ │ ├── validationGroup.ng1.ts │ │ ├── validationGroup.tests.ts │ │ └── validationGroup.ts ├── componentsDowngrade.ts ├── pipes │ ├── date │ │ ├── date.pipe.md │ │ ├── date.pipe.tests.ts │ │ └── date.pipe.ts │ ├── index.ts │ ├── isEmpty │ │ ├── isEmpty.md │ │ ├── isEmpty.pipe.tests.ts │ │ └── isEmpty.pipe.ts │ ├── localizeStringDates │ │ ├── localizeStringDates.pipe.tests.ts │ │ └── localizeStringDates.pipe.ts │ └── truncate │ │ ├── truncate.md │ │ ├── truncate.pipe.tests.ts │ │ └── truncate.pipe.ts ├── services │ ├── async │ │ ├── async.service.tests.ts │ │ └── async.service.ts │ ├── autosave │ │ ├── autosave.service.tests.ts │ │ ├── autosave.service.ts │ │ └── triggers │ │ │ ├── onChangeTrigger.tests.ts │ │ │ ├── onChangeTrigger.ts │ │ │ ├── trigger.tests.ts │ │ │ ├── trigger.ts │ │ │ ├── triggers.md │ │ │ ├── triggers.service.tests.ts │ │ │ └── triggers.service.ts │ ├── autosaveAction │ │ ├── autosaveAction.service.tests.ts │ │ └── autosaveAction.service.ts │ ├── breakpoints │ │ ├── breakpoint.ts │ │ ├── breakpoints.module.ts │ │ ├── breakpoints.service.ng1.tests.ts │ │ ├── breakpoints.service.ng1.ts │ │ ├── breakpoints.service.tests.ts │ │ ├── breakpoints.service.ts │ │ ├── index.ts │ │ └── visibleBreakpoint.service.ts │ ├── componentValidator │ │ ├── componentValidator.service.ng1.tests.ts │ │ ├── componentValidator.service.ng1.ts │ │ ├── componentValidator.service.tests.ts │ │ └── componentValidator.service.ts │ ├── contentProvider │ │ ├── contentProvider.service.tests.ts │ │ └── contentProvider.service.ts │ ├── dialog │ │ ├── bootstrapModalDialog │ │ │ ├── bootstrapModalDialog.controller.tests.ts │ │ │ ├── bootstrapModalDialog.controller.ts │ │ │ ├── bootstrapModalDialog.module.ts │ │ │ ├── bootstrapModalDialog.service.tests.ts │ │ │ └── bootstrapModalDialog.service.ts │ │ ├── dialog.service.ng1.tests.ts │ │ ├── dialog.service.ng1.ts │ │ ├── dialogTypes.ts │ │ └── promptDialog.html │ ├── document │ │ └── document.provider.ts │ ├── documentWrapper │ │ └── documentWrapper.service.ts │ ├── form │ │ ├── form.service.ng1.tests.ts │ │ ├── form.service.ng1.ts │ │ ├── form.service.tests.ts │ │ └── form.service.ts │ ├── jquery │ │ ├── jquery.provider.ts │ │ ├── jquery.service.tests.ts │ │ └── jquery.service.ts │ ├── parentChild │ │ └── parentChild.service.ts │ ├── promise │ │ ├── promise.service.tests.ts │ │ └── promise.service.ts │ ├── services.module.ts │ ├── templateLoader │ │ └── templateLoader.service.ts │ └── windowWrapper │ │ └── windowWrapper.service.ts ├── types │ ├── changes.ts │ ├── formValidators.ts │ ├── types.module.ts │ └── viewData.ts ├── ui.module.ng1.ts └── ui.module.ts ├── system.config.js ├── tsconfig.json ├── tslint.json └── typings ├── angularExtensions.d.ts ├── angularUIBootstrap.d.ts ├── bootstrapDateTimePicker.d.ts ├── chaiAssertions.d.ts ├── commonjs.d.ts ├── jQuery.d.ts ├── jasmine.d.ts ├── moment.d.ts └── sinon.d.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | ; http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = tab 7 | indent_size = 4 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | indent_size = 4 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Don't commit the built files 2 | /dist/ 3 | /source/**/*.js 4 | /source/**/*.d.ts 5 | /bootstrapper/**/*.js 6 | /bootstrapper/**/*.d.ts 7 | /bootstrapper/**/*.js.map 8 | /tests/ 9 | 10 | # Node deps 11 | /node_modules/ 12 | 13 | # Bower deps 14 | /bower_components/ 15 | 16 | # Ignore git conflict / diff files 17 | *.orig 18 | 19 | # Typings files (resolved via typings) 20 | /typings/index.d.ts 21 | /typings/globals/ 22 | /typings/modules/ 23 | 24 | debug.log 25 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Ignore test files 2 | source/**/*.tests.js 3 | *.tests.d.ts 4 | karma* 5 | /tests/ 6 | 7 | # Bundles 8 | /bootstrapper/*.bundle* 9 | 10 | # NPM 11 | /node_modules/ 12 | npm-debug.log 13 | 14 | # Ignore webpack settings 15 | webpack.* 16 | 17 | # Git 18 | *.orig 19 | 20 | # Nuget bootstrap files 21 | /bootstrapper/nuget/*/ 22 | 23 | # Don't need external typings on npm 24 | /typings/ 25 | 26 | #exlude the .ts files from dist 27 | *.ts 28 | !*.d.ts -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.trimTrailingWhitespace": true, 4 | "editor.tabSize": 4, 5 | "editor.formatOnType": true, 6 | "files.exclude": { 7 | "**/.git": true, 8 | "**/.DS_Store": true, 9 | "**/tests/": true, 10 | "source/**/*.js": true, 11 | "source/**/*.js.map": true, 12 | "source/**/*.d.ts": true, 13 | "bootstrapper/**/*.js": true, 14 | "bootstrapper/**/*.js.map": true, 15 | "bootstrapper/**/*.d.ts": true 16 | } 17 | , 18 | "typescript.check.workspaceVersion": false 19 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "command": "npm", 4 | "isShellCommand": true, 5 | "args": [ 6 | "--no-color" 7 | ], 8 | "tasks": [ 9 | { 10 | "taskName": "build", 11 | "args": ["run"], 12 | "isBuildCommand": true, 13 | "isWatching": false, 14 | "problemMatcher": [ 15 | "$lessCompile", 16 | "$tsc", 17 | "$jshint" 18 | ] 19 | }, 20 | { 21 | "taskName": "test", 22 | "args": [], 23 | "isTestCommand": true 24 | }, 25 | { 26 | "taskName": "update", 27 | "args": ["run"] 28 | }, 29 | { 30 | "taskName": "clean", 31 | "args": ["run"] 32 | }, 33 | { 34 | "taskName": "publish.prep", 35 | "args": ["run"] 36 | }, 37 | { 38 | "taskName": "build.all", 39 | "args": ["run"] 40 | } 41 | ], 42 | "problemMatcher": "$tsc" 43 | } -------------------------------------------------------------------------------- /bootstrapper/app.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 15 |
16 | 17 |
18 | 19 |
20 |
21 | -------------------------------------------------------------------------------- /bootstrapper/app.ng2.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'ts-app', 5 | template: require('./app.html'), 6 | }) 7 | export class App {} 8 | -------------------------------------------------------------------------------- /bootstrapper/bootstrapper.css: -------------------------------------------------------------------------------- 1 | .rl-tab-item.error { 2 | color: red; 3 | } 4 | 5 | .rl-tab-item.current { 6 | color: blue; 7 | } 8 | -------------------------------------------------------------------------------- /bootstrapper/buttons/buttonRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsButtonsRoot', 5 | template: require('./buttons.html'), 6 | }) 7 | export class ButtonsRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/buttons/buttons.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/buttons/buttonsNg2Bootstrapper.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | @Component({ 5 | selector: 'tsButtonsBootstrapper', 6 | template: require('./buttonsNg2.html'), 7 | }) 8 | export class ButtonsNg2BootstrapperComponent { 9 | waitCallback: { (): Observable } = () => { 10 | return this.wait(this.action, 'Async button'); 11 | } 12 | 13 | action(name: string): void { 14 | console.log('Action: ' + name); 15 | } 16 | 17 | wait(callback, name): Observable { 18 | return Observable.of(null).do(() => callback(name)).delay(1000); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /bootstrapper/cards/cardRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsCardsRoot', 5 | template: require('./cards.html'), 6 | }) 7 | export class CardsRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/cards/cards.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /bootstrapper/cards/cardsSmartData.html: -------------------------------------------------------------------------------- 1 |

Smart Data Source

2 |
3 |
4 | 5 | 6 |
7 |
8 | 9 | 10 |
11 | Name: {{myItem.name}} 12 | Value: {{myItem.value}} 13 |
14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /bootstrapper/forms/forms.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/forms/formsNg1.html: -------------------------------------------------------------------------------- 1 |

Forms

2 | 3 | 4 | 5 | Submit 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | {{forms.count}} 14 |
15 |
16 | 17 |
18 | 19 | 20 | 21 | 22 |
-------------------------------------------------------------------------------- /bootstrapper/forms/formsRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsFormsRoot', 5 | template: require('./forms.html'), 6 | }) 7 | export class FormsRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/inputs/inputRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsInputsRoot', 5 | template: require('./inputs.html'), 6 | }) 7 | export class InputsRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/inputs/inputs.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { UpgradeModule } from '@angular/upgrade/static'; 3 | 4 | import { ComponentsBootstrapperModule, moduleName } from './app'; 5 | 6 | platformBrowserDynamic().bootstrapModule(ComponentsBootstrapperModule).then(platformRef => { 7 | const upgrade = platformRef.injector.get(UpgradeModule) as UpgradeModule; 8 | upgrade.bootstrap(document.documentElement, [moduleName]); 9 | }); 10 | -------------------------------------------------------------------------------- /bootstrapper/messageLog/messageLogNg1Test.html: -------------------------------------------------------------------------------- 1 |

Message log

2 |
3 | 4 |
5 | -------------------------------------------------------------------------------- /bootstrapper/messageLog/messageLogNg2Bootstrapper.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsMessageLogBootstrapper', 5 | template: require('./messageLogNg2Bootstrapper.html'), 6 | }) 7 | export class MessageLogNg2BootstrapperComponent { 8 | messages: any[]; 9 | pageSize = 8; 10 | hasNextPage = true; 11 | loading: boolean = false; 12 | 13 | ngOnInit(): void { 14 | this.messages = [ 15 | { 16 | id: 1, 17 | isSystemMessage: false, 18 | message: 'Cool', 19 | createdBy: { name: 'Jim Davis' }, 20 | createdDate: '2017-01-01T12:00:00', 21 | }, 22 | { 23 | id: 2, 24 | isSystemMessage: true, 25 | message: 'Event', 26 | createdBy: { name: 'System' }, 27 | createdDate: '2017-01-01T01:00:00', 28 | }, 29 | ]; 30 | } 31 | 32 | log = x => console.log(x); 33 | } 34 | -------------------------------------------------------------------------------- /bootstrapper/messageLog/messageLogRoot.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/messageLog/messageLogRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsMessageLogRoot', 5 | template: require('./messageLogRoot.html'), 6 | }) 7 | export class MessageLogRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/misc/misc.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/misc/miscNg2Context.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | -------------------------------------------------------------------------------- /bootstrapper/misc/miscNg2Context.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild } from '@angular/core'; 2 | import { Observable, Subject } from 'rxjs'; 3 | 4 | import { BusyComponent } from '../../source/components/busy/busy'; 5 | 6 | @Component({ 7 | selector: 'tsMiscNgContext', 8 | template: require('./miscNg2Context.html'), 9 | }) 10 | export class MiscNgContextBootstrapper { 11 | @ViewChild('busy2') busy2: BusyComponent; 12 | width: number = 100; 13 | value: number = 0; 14 | 15 | wait(): Observable { 16 | return Observable.of(null).delay(1000); 17 | } 18 | 19 | toggle(): void { 20 | this.busy2.waitOn(!this.busy2.loading); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bootstrapper/misc/miscRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsMiscRoot', 5 | template: require('./misc.html'), 6 | }) 7 | export class MiscRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/msi/msi.ng2.html: -------------------------------------------------------------------------------- 1 |

Multi Step Indicator Angular 2

2 | 6 | 7 |

rlStep

8 | 11 | 13 | -------------------------------------------------------------------------------- /bootstrapper/msi/msiBootstrapper.ng2.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { IStep } from '../../source/components/multiStepIndicator/multiStepIndicator'; 5 | 6 | @Component({ 7 | selector: 'tsMsiBootstrapper', 8 | template: require('./msi.ng2.html'), 9 | }) 10 | export class MsiBootstrapperComponent implements OnInit { 11 | steps: IStep[]; 12 | numbered: boolean; 13 | checked: boolean; 14 | 15 | constructor() { 16 | this.numbered = false; 17 | this.checked = true; 18 | } 19 | 20 | ngOnInit() { 21 | this.steps = [ 22 | { 23 | title: 'Step 1', 24 | routerLink: ['/msi/ng1'], 25 | subtitle: 'Angular 1', 26 | }, 27 | { 28 | title: 'Step 2', 29 | routerLink: ['/msi/ng2'], 30 | subtitle: 'Angular 2', 31 | }, 32 | { 33 | title: 'Step 3', 34 | subtitle: 'Do more work', 35 | onClick: (): Observable => { 36 | return Observable.of(null) 37 | .do(() => console.log('Processing step 3')) 38 | .delay(1000) 39 | .do(() => console.log('Step 3 processed')); 40 | }, 41 | }, 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /bootstrapper/popup/popup.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/popup/popupNg1.html: -------------------------------------------------------------------------------- 1 |

Popup content

2 |
3 | 4 | Show rl-popover 5 | Show simple popover 6 |
7 | 8 |
9 | 10 | Open prompt 11 | Open custom dialog 12 |
-------------------------------------------------------------------------------- /bootstrapper/popup/popupNg2Bootstrapper.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { IDialogClosingHandler } from '../../source/components/dialog/dialogRoot.service'; 5 | 6 | @Component({ 7 | selector: 'tsPopupBootstrapper', 8 | template: require('./popupNg2.html'), 9 | }) 10 | export class PopupBootstrapper { 11 | content: string = 'Some content'; 12 | onClosing: IDialogClosingHandler; 13 | options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; 14 | getOptions = () => Observable.of(this.options); 15 | 16 | constructor() { 17 | this.onClosing = () => { 18 | console.log('Trying to close...'); 19 | return false; 20 | }; 21 | } 22 | 23 | yes(): void { 24 | console.log('Yes'); 25 | } 26 | 27 | no(): void { 28 | console.log('No'); 29 | } 30 | 31 | save = (data) => { 32 | console.log(data); 33 | } 34 | 35 | create = x => x; 36 | } 37 | -------------------------------------------------------------------------------- /bootstrapper/popup/popupRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsPopupRoot', 5 | template: require('./popup.html'), 6 | }) 7 | export class PopupRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/tabs/tabRoot.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsTabsRoot', 5 | template: require('./tabs.html'), 6 | }) 7 | export class TabsRootComponent { } 8 | -------------------------------------------------------------------------------- /bootstrapper/tabs/tabs.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /bootstrapper/tabs/tabsBootstrapper.ts: -------------------------------------------------------------------------------- 1 | import { Component, Directive, ElementRef, Injector } from '@angular/core'; 2 | import { UpgradeComponent } from '@angular/upgrade/static'; 3 | import * as angular from 'angular'; 4 | 5 | import { IStep } from '../../source/components/multiStepIndicator/multiStepIndicator'; 6 | 7 | export const moduleName: string = 'TabTestModule'; 8 | 9 | @Component({ 10 | selector: 'tsTabsNg1Bootstrapper', 11 | template: '' 12 | }) 13 | export class TabsNg1BootstrapperComponent { } 14 | 15 | @Directive({ 16 | selector: 'tsTabsNg1' 17 | }) 18 | export class TabsNg1Directive extends UpgradeComponent { 19 | constructor(elementRef: ElementRef, injector: Injector) { 20 | super('tsTabsNg1', elementRef, injector); 21 | } 22 | } 23 | 24 | angular.module(moduleName, []) 25 | .component('tsTabsNg1', { 26 | template: require('./tabsNg1.html'), 27 | }); 28 | -------------------------------------------------------------------------------- /bootstrapper/tabs/tabsNg1.html: -------------------------------------------------------------------------------- 1 |

Tabs Ng 1

2 | 3 | 4 | 5 | Header 6 | Content 1 7 | Footer 1 8 | 9 | 10 | Header 2 11 | Content 2 12 | Footer 2 13 | 14 | 15 | -------------------------------------------------------------------------------- /bootstrapper/tabs/tabsNg2.html: -------------------------------------------------------------------------------- 1 |

Tabs Ng 2

2 | 3 | 4 | 5 | Header 6 | Content 1 7 | Footer 1 8 | 9 | 10 | Header 2 11 | Content 2 12 | Footer 2 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /bootstrapper/tabs/tabsNg2Bootstrapper.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsTabsBootstrapper', 5 | template: require('./tabsNg2.html'), 6 | }) 7 | export class TabsBootstrapper { 8 | validator: any; 9 | textboxValue: string = ""; 10 | 11 | constructor() { 12 | this.validator = { 13 | validate: () => this.textboxValue != null && this.textboxValue != "", 14 | errorMessage: "This field is required", 15 | }; 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /bootstrapper/text/text.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export const moduleName: string = 'TextModule'; 4 | 5 | class TextController { 6 | text: string; 7 | 8 | static $inject: string[] = ['$transclude']; 9 | constructor(private $transclude: angular.ITranscludeFunction) { } 10 | 11 | $onInit(): void { 12 | this.$transclude((content: JQuery): void => { 13 | this.text = angular.element('
').append(content).html(); 14 | }); 15 | } 16 | } 17 | 18 | const textComponent: angular.IComponentOptions = { 19 | transclude: true, 20 | template: '{{$ctrl.text}}', 21 | controller: TextController, 22 | }; 23 | 24 | angular.module(moduleName, []) 25 | .component('tsText', textComponent); 26 | -------------------------------------------------------------------------------- /bootstrapper/welcome.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'tsWelcome', 5 | template: '

Welcome to typescript-angular-components

', 6 | }) 7 | export class WelcomeComponent { } 8 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | 2 | // Karma default configuration 3 | 4 | var karmaSettings = require('@renovolive/gulp-utilities').karma.standard; 5 | var config = require('./karma.shared.conf'); 6 | 7 | module.exports = function (karma) { 8 | karmaSettings(karma, config.files, config.settings); 9 | }; 10 | -------------------------------------------------------------------------------- /karma.debug.conf.js: -------------------------------------------------------------------------------- 1 | // Karma debug configuration 2 | 3 | var karmaSettings = require('@renovolive/gulp-utilities').karma.debug; 4 | var config = require('./karma.shared.conf'); 5 | 6 | module.exports = function (karma) { 7 | karmaSettings(karma, config.files, config.settings); 8 | }; 9 | -------------------------------------------------------------------------------- /karma.full.conf.js: -------------------------------------------------------------------------------- 1 | // Karma full browser configuration 2 | 3 | var karmaSettings = require('@renovolive/gulp-utilities').karma.full; 4 | var config = require('./karma.shared.conf'); 5 | 6 | module.exports = function (karma) { 7 | karmaSettings(karma, config.files, config.settings); 8 | }; 9 | -------------------------------------------------------------------------------- /karma.shared.conf.js: -------------------------------------------------------------------------------- 1 | exports.files = [ 2 | 'tests/vendor.bundle.js', 3 | 'tests/renovo.bundle.js', 4 | 'tests/tests.bundle.js', 5 | ]; 6 | 7 | exports.settings = { 8 | appPath: '/source/', 9 | testsExtension: '.tests.js', 10 | configPath: 'system.config.js', 11 | testSetupPath: 'karma-test-setup.js', 12 | globalSettingsPath: 'tests/globalSettings.js', 13 | }; 14 | -------------------------------------------------------------------------------- /karma.tc.conf.js: -------------------------------------------------------------------------------- 1 | // Karma full browser configuration 2 | 3 | var karmaSettings = require('@renovolive/gulp-utilities').karma.tc; 4 | var config = require('./karma.shared.conf'); 5 | 6 | module.exports = function (karma) { 7 | karmaSettings(karma, config.files, config.settings); 8 | }; 9 | -------------------------------------------------------------------------------- /libraries/bootstrap-datetimepicker/index.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap-datetimepicker'); -------------------------------------------------------------------------------- /libraries/bootstrap-touchspin/index.js: -------------------------------------------------------------------------------- 1 | jQuery = require('jquery'); 2 | 3 | require('./jquery.bootstrap-touchspin'); -------------------------------------------------------------------------------- /source/animations/index.ts: -------------------------------------------------------------------------------- 1 | import * as slide from './slide/slide.animate'; 2 | 3 | export { 4 | slide, 5 | } -------------------------------------------------------------------------------- /source/animations/slide/slide.animate.ts: -------------------------------------------------------------------------------- 1 | import { AnimationEntryMetadata, trigger, state, style, transition, animate } from '@angular/core'; 2 | 3 | export const show: string = 'show'; 4 | export const hide: string = 'hide'; 5 | 6 | export const animation = trigger('slide', [ 7 | state(hide, style({ 8 | zIndex: 1, 9 | opacity: 0, 10 | transform: 'translateY(100%)', 11 | })), 12 | state(show, style({ 13 | opacity: 1, 14 | transform: 'translateY(0)', 15 | })), 16 | transition(`${hide} <=> ${show}`, animate('250ms ease')), 17 | ]); -------------------------------------------------------------------------------- /source/behaviors/alias/alias.md: -------------------------------------------------------------------------------- 1 | # Alias 2 | Behavior for aliasing a data object under a different name on the given scope. 3 | 4 | ### Usage 5 | ``` 6 |
...
7 | ``` 8 | ### Options 9 | 10 | #### `value` 11 | 12 | Binds to a value on the current scope 13 | 14 | #### `alias` 15 | 16 | Sets the name the value should be aliased under on the scope. Interpolation is permitted, but if used, one-time binding is recommended. Dynamically changing the alias value could result in memory leaks as the value will still be saved against the scope under a previous alias. 17 | 18 | ### Full example 19 | ``` 20 | // controller 21 | this.value = 5; 22 | 23 | // view (controller as test) 24 |
25 | {{foo}} // 5 26 |
27 | ``` -------------------------------------------------------------------------------- /source/behaviors/behaviors.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import * as alias from './alias/alias'; 4 | import * as alternatingClass from './alternatingClass/alternatingClass'; 5 | import * as autosave from './autosave/autosave.ng1'; 6 | import * as offClick from './offClick/offClick.ng1'; 7 | import * as popover from './popover/popover'; 8 | import * as required from './required/required'; 9 | import * as focusOn from './focusOn/focusOn.ng1'; 10 | 11 | export { alias, autosave, offClick, popover, required, focusOn }; 12 | 13 | export var moduleName: string = 'rl.ui.behaviors'; 14 | 15 | angular.module(moduleName, [ 16 | alias.moduleName, 17 | alternatingClass.moduleName, 18 | autosave.moduleName, 19 | offClick.moduleName, 20 | popover.moduleName, 21 | required.moduleName, 22 | focusOn.moduleName 23 | ]); 24 | -------------------------------------------------------------------------------- /source/behaviors/focusOn/focusOn.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export const moduleName: string = 'rl.ui.behaviors.focusOn'; 4 | export const directiveName: string = 'rlFocusOn'; 5 | 6 | focusOn.$inject = ['$timeout', '$parse']; 7 | export function focusOn($timeout, $parse): angular.IDirective { 8 | return { 9 | link: function(scope, element, attrs: any) { 10 | var model = $parse(attrs.rlFocusOn); 11 | scope.$watch(model, function (value) { 12 | if (value === true) { 13 | $timeout(function () { 14 | let thisElement = element[0]; 15 | if (thisElement.tagName.toLowerCase() == 'input') { 16 | thisElement.focus(); 17 | } 18 | else { 19 | let ngElement = angular.element(thisElement); 20 | ngElement.find('input').focus(); 21 | } 22 | }); 23 | } 24 | }); 25 | } 26 | }; 27 | } 28 | 29 | angular.module(moduleName, []) 30 | .directive(directiveName, focusOn); 31 | -------------------------------------------------------------------------------- /source/behaviors/index.ts: -------------------------------------------------------------------------------- 1 | import { AutosaveDirective } from './autosave/autosave'; 2 | import { OffClickDirective } from './offClick/offClick'; 3 | import { StopEventPropagationDirective } from './stopEventPropagation/stopEventPropagation'; 4 | 5 | export const BEHAVIOR_DIRECTIVES: any[] = [AutosaveDirective, OffClickDirective, StopEventPropagationDirective]; 6 | 7 | export * from './autosave/autosave'; 8 | export * from './offClick/offClick'; 9 | export * from './stopEventPropagation/stopEventPropagation'; 10 | -------------------------------------------------------------------------------- /source/behaviors/popover/popover.md: -------------------------------------------------------------------------------- 1 | # Popover 2 | Behavior that wraps angular-ui [popovers](https://angular-ui.github.io/bootstrap/#/popover) to hide some of the gimmicky behavior and allow for binding in a dynamic template. 3 | 4 | ### Usage 5 | ``` 6 |
...
7 | ``` 8 | ### Options 9 | 10 | #### `Default(rl-popover)` 11 | 12 | Binds in an html template from the scope. 13 | 14 | #### `text-only (default: false)` 15 | 16 | If true, uses the popover value as a simple text value for the popover rather than an html template binding. 17 | 18 | Example: `rl-popover="Hello world!" text-only="true"` outputs a popover with `Hello world!`. 19 | 20 | See [popover](https://angular-ui.github.io/bootstrap/#/popover) for additional options. All options under the `uib-popover-* settings` section apply. 21 | 22 | ### Full example 23 | ``` 24 | // controller 25 | this.template = '

Hello world!

; 26 | 27 | // view (controller as test) 28 |
29 | ``` 30 | Output (popover content): 31 | ``` 32 |

Hello world!

33 | ``` -------------------------------------------------------------------------------- /source/behaviors/required/required.md: -------------------------------------------------------------------------------- 1 | # Required 2 | Behavior that enables `required` validation with a corresponding error message. Can be used with any rl [input](../../components/input/input.md) component. 3 | 4 | ### Usage 5 | ``` 6 | 7 | ``` -------------------------------------------------------------------------------- /source/behaviors/required/required.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export const moduleName: string = 'rl.ui.behaviors.required'; 4 | export const directiveName: string = 'rlRequired'; 5 | export const controllerName: string = 'RequiredController'; 6 | 7 | export interface IRequiredAttributes extends angular.IAttributes { 8 | rlRequired: string; 9 | } 10 | 11 | export class RequiredController { 12 | static $inject: string[] = ['$scope', '$attrs', '$interpolate']; 13 | constructor(private $scope: angular.IScope 14 | , private $attrs: IRequiredAttributes 15 | , private $interpolate: angular.IInterpolateService) { 16 | this.message = this.$interpolate(this.$attrs.rlRequired)(this.$scope); 17 | } 18 | 19 | message: string; 20 | } 21 | 22 | function required(): angular.IDirective { 23 | return { 24 | restrict: 'A', 25 | controller: controllerName, 26 | }; 27 | } 28 | 29 | angular.module(moduleName, []) 30 | .directive(directiveName, required) 31 | .controller(controllerName, RequiredController); 32 | -------------------------------------------------------------------------------- /source/behaviors/stopEventPropagation/stopEventPropagation.md: -------------------------------------------------------------------------------- 1 | ## stopEventPropogation 2 | Absorbs the passed in DOM event so that it will not propogate outside of the current element. Generally useful for restricting click events within an element so that the click events on parent elements are not triggered. 3 | ``` 4 |
5 | 6 |
7 | ``` 8 | -------------------------------------------------------------------------------- /source/behaviors/stopEventPropagation/stopEventPropagation.ts: -------------------------------------------------------------------------------- 1 | import { Input, Directive, ElementRef, AfterContentInit } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[rl-stop-event-propagation]' 5 | }) 6 | export class StopEventPropagationDirective implements AfterContentInit { 7 | private element: ElementRef; 8 | 9 | @Input('rl-stop-event-propagation') 10 | private event: string; 11 | 12 | constructor(element: ElementRef) { 13 | this.element = element; 14 | } 15 | 16 | ngAfterContentInit(): void { 17 | this.element.nativeElement.on(this.event, (event: any): void => { 18 | event.preventDefault(); 19 | event.stopPropagation(); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /source/components/busy/busy.css: -------------------------------------------------------------------------------- 1 | .default-theme.busy { 2 | -webkit-animation: fa-spin 2s infinite linear; 3 | animation: fa-spin 2s infinite linear; 4 | display: inline-block; 5 | font-size: inherit; 6 | font-style: normal; 7 | font-family: FontAwesome; 8 | } 9 | 10 | .default-theme.busy:before { 11 | content: "\f110"; /* fa-spinner */ 12 | } -------------------------------------------------------------------------------- /source/components/busy/busy.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/busy/busy.md: -------------------------------------------------------------------------------- 1 | # Busy 2 | Component that conditionally shows a spinner when a flag is set. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `loading` 11 | 12 | If the loading expression evaluates to truthy, the spinner will be shown. 13 | 14 | #### `size` 15 | 16 | This will set the **size** of the spinner. We use the following sizes: `2x`, `3x`, `4x`, `5x`, `lg`. This option is applied to the spinner's class attribute and prefixed with `rl-`. 17 | 18 | ### API (Angular 2 ONLY) 19 | 20 | #### `trigger(waitOn: Observable | Promise | boolean): void` 21 | 22 | Programmatically triggers the spinner to show based on a set condition. If an observable or promise is specified, the spinner will show until an event is received, or the promise resolved. If a boolean is specified, the spinner will be shown or hidden accordingly, with no wait conditions. 23 | 24 | ### Full example 25 | A spinner with **loading** and **size**. 26 | ``` 27 | 28 | ``` 29 | Output: 30 | ``` 31 | 32 | ``` -------------------------------------------------------------------------------- /source/components/busy/busy.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { BusyComponent } from './busy'; 5 | 6 | @NgModule({ 7 | exports: [ 8 | BusyComponent 9 | ], 10 | declarations: [ 11 | BusyComponent 12 | ], 13 | }) 14 | export class BusyModule { } 15 | -------------------------------------------------------------------------------- /source/components/busy/busy.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { defaultThemeValueName } from '../componentsDefaultTheme'; 4 | 5 | export const moduleName: string = 'rl.ui.components.busy'; 6 | export const componentName: string = 'rlBusy'; 7 | 8 | class BusyController { 9 | static $inject: string[] = [defaultThemeValueName]; 10 | constructor(public useDefaultTheme: boolean) { } 11 | } 12 | 13 | const busy: angular.IComponentOptions = { 14 | template: ``, 15 | controller: BusyController, 16 | controllerAs: 'busy', 17 | bindings: { 18 | loading: '<', 19 | // Valid values are: 20 | // `lg`, `2x`, `3x`, `4x`, and `5x` 21 | size: '@', 22 | }, 23 | }; 24 | 25 | angular.module(moduleName, []) 26 | .component(componentName, busy); 27 | -------------------------------------------------------------------------------- /source/components/buttons/baseButton.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { each } from 'lodash'; 3 | 4 | export const baseInputs: string[] = ['type', 'disabled', 'size']; 5 | 6 | const buttonClassPrefix: string = 'btn-'; 7 | const defaultButtonType: string = 'default'; 8 | 9 | export abstract class BaseButtonComponent { 10 | type: string; 11 | disabled: boolean; 12 | size: string; 13 | 14 | get configuredSize(): string { 15 | return this.size != null && this.size !== '' 16 | ? buttonClassPrefix + this.size 17 | : null; 18 | } 19 | 20 | get configuredTypes(): string { 21 | let type: string = this.type || defaultButtonType; 22 | let typesList: string[] = type.split(' '); 23 | each(typesList, (type: string, index: number): void => { 24 | //the for each for places that used btn-block for example in the type attribute do not break 25 | if (type.indexOf(buttonClassPrefix) === -1) { 26 | type = buttonClassPrefix + type; 27 | } 28 | typesList[index] = type; 29 | }); 30 | return typesList.join(' '); 31 | } 32 | } -------------------------------------------------------------------------------- /source/components/buttons/button/button.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/button/button.md: -------------------------------------------------------------------------------- 1 | # Button 2 | Basic button with configurable options for **action**, **size**, **type**, and **disabling**. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | `action`, `size`, `type`, and `ng-disabled`. 11 | 12 | See [buttons](../buttons.md) for detail on the base options. 13 | 14 | ### Full Example 15 | A button with an **action**, **size**, **type**, and **disabling**. 16 | ``` 17 | ... 18 | ``` 19 | Output: 20 | ``` 21 | 22 | ``` -------------------------------------------------------------------------------- /source/components/buttons/button/button.ng1.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/button/button.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Output } from '@angular/core'; 2 | 3 | import { BaseButtonComponent, baseInputs } from '../baseButton'; 4 | 5 | @Component({ 6 | selector: 'rlButton', 7 | template: require('./button.html'), 8 | inputs: baseInputs, 9 | }) 10 | export class ButtonComponent extends BaseButtonComponent { 11 | @Output() trigger: EventEmitter = new EventEmitter(); 12 | } -------------------------------------------------------------------------------- /source/components/buttons/buttonAsync/buttonAsync.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonAsync/buttonAsync.ng1.html: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /source/components/buttons/buttonAsync/buttonAsync.tests.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | import { ButtonAsyncComponent } from './buttonAsync'; 4 | 5 | interface IMockBusy { 6 | waitOn: sinon.SinonSpy; 7 | } 8 | 9 | describe('ButtonAsyncComponent', () => { 10 | let button: ButtonAsyncComponent; 11 | let busy: IMockBusy; 12 | let action: sinon.SinonSpy; 13 | 14 | beforeEach(() => { 15 | button = new ButtonAsyncComponent(); 16 | 17 | busy = { 18 | waitOn: sinon.spy(() => Observable.empty()), 19 | }; 20 | button.busySpinner = busy; 21 | }); 22 | 23 | it('should trigger the action and pass the result to the spinner', (): void => { 24 | action = sinon.spy(() => 5); 25 | button.action = action; 26 | const event = { value: 2 }; 27 | 28 | button.triggerAction(event); 29 | 30 | sinon.assert.calledOnce(action); 31 | sinon.assert.calledWith(action, event); 32 | sinon.assert.calledOnce(busy.waitOn); 33 | sinon.assert.calledWith(busy.waitOn, 5); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /source/components/buttons/buttonAsync/buttonAsync.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ViewChild } from '@angular/core'; 2 | import { Observable, Subject } from 'rxjs'; 3 | 4 | import { BusyComponent, IWaitValue } from '../../busy/busy'; 5 | import { BaseButtonComponent, baseInputs } from '../baseButton'; 6 | 7 | export const asyncInputs = baseInputs.concat(['action']); 8 | 9 | export interface IAsyncAction { 10 | ($event: any): IWaitValue; 11 | } 12 | 13 | @Component({ 14 | selector: 'rlButtonAsync', 15 | template: require('./buttonAsync.html'), 16 | inputs: asyncInputs, 17 | }) 18 | export class ButtonAsyncComponent extends BaseButtonComponent { 19 | action: IAsyncAction; 20 | 21 | @ViewChild(BusyComponent) busySpinner: BusyComponent; 22 | 23 | constructor() { 24 | super(); 25 | if (!this.action) { 26 | this.action = () => Observable.empty(); 27 | } 28 | } 29 | 30 | triggerAction($event: any): void { 31 | // subscribes to kick off the action 32 | const waitValue: IWaitValue = this.action($event); 33 | this.busySpinner.waitOn(waitValue).subscribe(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /source/components/buttons/buttonLink/buttonLink.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /source/components/buttons/buttonLink/buttonLink.md: -------------------------------------------------------------------------------- 1 | # Button Link 2 | This component wraps a hyperlink that is styled like a button. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `link` 11 | 12 | Sets the url of the hyperlink. Interpolation is permitted. 13 | 14 | #### `new-tab (default: false)` 15 | 16 | If true, the link opens in another tab. (Equivalent to `target="_blank"`) 17 | 18 | `size`, `type`, and `ng-disabled`. 19 | 20 | See [buttons](../buttons.md) for detail on the base options. 21 | 22 | ### Full Example 23 | A button link with a **link**, **new-tab**, **size**, **type**, and **disabling**. 24 | ``` 25 | ... 26 | ``` 27 | Output: 28 | ``` 29 | ... 30 | ``` -------------------------------------------------------------------------------- /source/components/buttons/buttonLink/buttonLink.ng1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /source/components/buttons/buttonLink/buttonLink.ng1.ts: -------------------------------------------------------------------------------- 1 | // /// 2 | 3 | import * as angular from 'angular'; 4 | 5 | import { buildButton, ButtonController } from '../button/button.ng1'; 6 | 7 | export const moduleName: string = 'rl.ui.components.buttonLink'; 8 | export const componentName: string = 'rlButtonLink'; 9 | export const controllerName: string = 'ButtonLinkController'; 10 | 11 | export class ButtonLinkController extends ButtonController { 12 | // bindings 13 | link: string; 14 | newTab: boolean; 15 | 16 | target: string; 17 | 18 | constructor() { 19 | super(); 20 | this.target = this.newTab ? '_blank' : '_self'; 21 | } 22 | } 23 | 24 | const buttonLink: angular.IComponentOptions = buildButton({ 25 | template: require('./buttonLink.ng1.html'), 26 | bindings: { 27 | link: '@', 28 | newTab: ' { 4 | let buttonLink: ButtonLinkComponent; 5 | 6 | beforeEach((): void => { 7 | buttonLink = new ButtonLinkComponent(); 8 | }); 9 | 10 | it('should set the target to blank if newTab is set', (): void => { 11 | buttonLink.newTab = true; 12 | expect(buttonLink.target).to.equal('_blank'); 13 | }); 14 | 15 | it('should set the target to self by default', (): void => { 16 | expect(buttonLink.target).to.equal('_self'); 17 | }); 18 | }); -------------------------------------------------------------------------------- /source/components/buttons/buttonLink/buttonLink.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | import { BaseButtonComponent, baseInputs } from '../baseButton'; 4 | 5 | @Component({ 6 | selector: 'rlButtonLink', 7 | template: require('./buttonLink.html'), 8 | inputs: baseInputs, 9 | }) 10 | export class ButtonLinkComponent extends BaseButtonComponent { 11 | @Input() link: string; 12 | @Input() newTab: boolean; 13 | 14 | get target(): string { 15 | return this.newTab ? '_blank' : '_self'; 16 | } 17 | } -------------------------------------------------------------------------------- /source/components/buttons/buttonLongClick/buttonLongClick.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonLongClick/buttonLongClick.ng1.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonRoute/buttonRoute.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /source/components/buttons/buttonRoute/buttonRoute.tests.ts: -------------------------------------------------------------------------------- 1 | import { ButtonRouteComponent } from './buttonRoute'; 2 | 3 | describe('ButtonRouteComponent', (): void => { 4 | let buttonRoute: ButtonRouteComponent; 5 | 6 | beforeEach((): void => { 7 | buttonRoute = new ButtonRouteComponent(); 8 | }); 9 | 10 | it('should set the target to blank if newTab is set', (): void => { 11 | buttonRoute.newTab = true; 12 | expect(buttonRoute.target).to.equal('_blank'); 13 | }); 14 | 15 | it('should set the target to self by default', (): void => { 16 | expect(buttonRoute.target).to.equal('_self'); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /source/components/buttons/buttonRoute/buttonRoute.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | import { BaseButtonComponent, baseInputs } from '../baseButton'; 4 | 5 | @Component({ 6 | selector: 'rlButtonRoute', 7 | template: require('./buttonRoute.html'), 8 | inputs: baseInputs, 9 | }) 10 | export class ButtonRouteComponent extends BaseButtonComponent { 11 | @Input() link: string; 12 | @Input() queryParams: any; 13 | @Input() activeClass: string = 'active'; 14 | @Input() newTab: boolean; 15 | 16 | get target(): string { 17 | return this.newTab ? '_blank' : '_self'; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /source/components/buttons/buttonSubmit/buttonSubmit.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonSubmit/buttonSubmit.md: -------------------------------------------------------------------------------- 1 | # Button Submit 2 | This button can be placed on a form to trigger a submit action. 3 | 4 | ### Usage 5 | ``` 6 |
7 | ... 8 | 9 | ``` 10 | ### Options 11 | 12 | #### `saving` 13 | 14 | Shows a spinner if the expression evaluates to truthy. 15 | 16 | `right-aligned`, `size`, `type`, and `ng-disabled`. 17 | 18 | See [buttons](../buttons.md) for detail on the base options. 19 | 20 | ### Full Example 21 | A submit button with **saving**, **right-aligned**, **size**, **type**, and **disabling**. 22 | ``` 23 | ... 24 | ``` 25 | Output: 26 | ``` 27 | 31 | ``` -------------------------------------------------------------------------------- /source/components/buttons/buttonSubmit/buttonSubmit.ng1.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonSubmit/buttonSubmit.ng1.ts: -------------------------------------------------------------------------------- 1 | // /// 2 | 3 | import * as angular from 'angular'; 4 | 5 | import { buildButton } from '../button/button.ng1'; 6 | 7 | export const moduleName: string = 'rl.ui.components.buttonSubmit'; 8 | export const componentName: string = 'rlButtonSubmit'; 9 | 10 | const buttonSubmit: angular.IComponentOptions = buildButton({ 11 | template: require('./buttonSubmit.ng1.html'), 12 | bindings: { 13 | saving: ' { 17 | let buttonSubmit: ButtonSubmitComponent; 18 | let form: IMockForm; 19 | let busy: IMockBusy; 20 | 21 | beforeEach((): void => { 22 | form = { 23 | submitAndWait: sinon.spy(() => 5), 24 | }; 25 | buttonSubmit = new ButtonSubmitComponent(form); 26 | 27 | busy = { 28 | waitOn: sinon.spy(() => Observable.empty()), 29 | }; 30 | buttonSubmit.busySpinner = busy; 31 | }); 32 | 33 | it('should submit the form and pass the result to the spinner', (): void => { 34 | buttonSubmit.submit(); 35 | 36 | sinon.assert.calledOnce(form.submitAndWait); 37 | sinon.assert.calledOnce(busy.waitOn); 38 | sinon.assert.calledWith(busy.waitOn, 5); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /source/components/buttons/buttonSubmit/buttonSubmit.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ViewChild } from '@angular/core'; 2 | 3 | import { BusyComponent, IWaitValue } from '../../busy/busy'; 4 | import { BaseButtonComponent, baseInputs } from '../baseButton'; 5 | import { FormComponent } from '../../form/form'; 6 | 7 | @Component({ 8 | selector: 'rlButtonSubmit', 9 | template: require('./buttonSubmit.html'), 10 | inputs: baseInputs, 11 | }) 12 | export class ButtonSubmitComponent extends BaseButtonComponent { 13 | 14 | @ViewChild(BusyComponent) busySpinner: BusyComponent; 15 | 16 | private form: FormComponent; 17 | 18 | constructor(form: FormComponent) { 19 | super(); 20 | this.form = form; 21 | } 22 | 23 | submit(): void { 24 | // subscribes to kick off the action 25 | const request = this.form.submitAndWait(); 26 | this.busySpinner.waitOn(request).subscribe(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /source/components/buttons/buttonToggle/buttonToggle.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonToggle/buttonToggle.ng1.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/buttons/buttonToggle/buttonToggle.tests.ts: -------------------------------------------------------------------------------- 1 | import { ButtonToggleComponent } from './buttonToggle'; 2 | 3 | describe('ButtonToggleComponent', () => { 4 | let buttonToggle: ButtonToggleComponent; 5 | 6 | beforeEach(() => { 7 | buttonToggle = new ButtonToggleComponent(); 8 | }); 9 | 10 | it('should update the value and emit a change event when the button is toggled', (): void => { 11 | const changeSpy: sinon.SinonSpy = sinon.spy(); 12 | 13 | buttonToggle.change.emit = changeSpy; 14 | 15 | expect(buttonToggle.value).to.be.undefined; 16 | 17 | buttonToggle.toggle(); 18 | 19 | expect(buttonToggle.value).to.be.true; 20 | sinon.assert.calledOnce(changeSpy); 21 | sinon.assert.calledWith(changeSpy, true); 22 | 23 | buttonToggle.toggle(); 24 | 25 | expect(buttonToggle.value).to.be.false; 26 | sinon.assert.calledTwice(changeSpy); 27 | sinon.assert.calledWith(changeSpy, false); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /source/components/buttons/buttonToggle/buttonToggle.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, Input, Output, EventEmitter } from '@angular/core'; 2 | 3 | import { BaseButtonComponent, baseInputs } from '../baseButton'; 4 | 5 | @Component({ 6 | selector: 'rlButtonToggle', 7 | template: require('./buttonToggle.html'), 8 | inputs: baseInputs, 9 | }) 10 | export class ButtonToggleComponent extends BaseButtonComponent { 11 | @Input() value: boolean; 12 | @Output() change: EventEmitter = new EventEmitter(); 13 | @Output() valueChange: EventEmitter = this.change; 14 | 15 | toggle(): void { 16 | if (!this.disabled) { 17 | this.value = !this.value; 18 | this.change.emit(this.value); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /source/components/buttons/index.ts: -------------------------------------------------------------------------------- 1 | import { ButtonComponent } from './button/button'; 2 | import { ButtonAsyncComponent } from './buttonAsync/buttonAsync'; 3 | import { ButtonLinkComponent } from './buttonLink/buttonLink'; 4 | import { ButtonLongClickComponent } from './buttonLongClick/buttonLongClick'; 5 | import { ButtonRouteComponent } from './buttonRoute/buttonRoute'; 6 | import { ButtonSubmitComponent } from './buttonSubmit/buttonSubmit'; 7 | import { ButtonToggleComponent } from './buttonToggle/buttonToggle'; 8 | 9 | export * from './button/button'; 10 | export * from './buttonAsync/buttonAsync'; 11 | export * from './buttonLink/buttonLink'; 12 | export * from './buttonLongClick/buttonLongClick'; 13 | export * from './buttonRoute/buttonRoute'; 14 | export * from './buttonSubmit/buttonSubmit'; 15 | export * from './buttonToggle/buttonToggle'; 16 | -------------------------------------------------------------------------------- /source/components/cardContainer/builder/index.ts: -------------------------------------------------------------------------------- 1 | import { CardContainerBuilderService } from './cardContainerBuilder.service'; 2 | import { CardContainerBuilderOld } from './cardContainerBuilderOld.service'; 3 | import { DataSourceBuilderOld } from './dataSourceBuilderOld.service'; 4 | import { FilterBuilderOld } from './filterBuilderOld.service'; 5 | 6 | export const BUILDER_PROVIDERS: any[] = [CardContainerBuilderService, CardContainerBuilderOld, DataSourceBuilderOld, FilterBuilderOld]; 7 | 8 | export * from './cardContainerBuilder.service'; 9 | export * from './cardContainerBuilderOld.service'; 10 | export * from './dataSourceBuilderOld.service'; 11 | export * from './filterBuilderOld.service'; 12 | -------------------------------------------------------------------------------- /source/components/cardContainer/card/headerColumn/headerColumn.html: -------------------------------------------------------------------------------- 1 |
2 |
{{value}}
3 |
4 |
5 |
6 |
-------------------------------------------------------------------------------- /source/components/cardContainer/card/headerColumn/headerColumn.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { services, downgrade } from 'typescript-angular-utilities'; 4 | 5 | import { directiveName, headerColumn, controllerName, HeaderColumnController } from './headerColumn.ng1'; 6 | import { sizeForBreakpointsName, sizeForBreakpoints } from './sizeForBreakpoints.ng1'; 7 | 8 | export var moduleName: string = 'rl.ui.components.cardContainer.card.headerColumn'; 9 | 10 | angular.module(moduleName, [ 11 | downgrade.moduleName, 12 | ]) 13 | .directive(sizeForBreakpointsName, sizeForBreakpoints) 14 | .directive(directiveName, headerColumn) 15 | .controller(controllerName, HeaderColumnController); 16 | -------------------------------------------------------------------------------- /source/components/cardContainer/cardContainer.css: -------------------------------------------------------------------------------- 1 | .selection-control .selection-control-count 2 | , .selection-control .selection-control-buttons { 3 | margin-bottom: 5px; 4 | } 5 | 6 | .select-group .select-column .fa-check { 7 | margin-left: 6px; 8 | cursor: pointer; 9 | } -------------------------------------------------------------------------------- /source/components/cardContainer/column.ts: -------------------------------------------------------------------------------- 1 | import { IPartialSort } from './sorts/sort'; 2 | import { SortDirection } from './sorts/sortDirection'; 3 | 4 | export interface IBreakpointSize { 5 | xs?: number; 6 | sm?: number; 7 | md?: number; 8 | lg?: number; 9 | } 10 | 11 | export interface ISecondarySorts { 12 | ascending?: IPartialSort[]; 13 | descending?: IPartialSort[]; 14 | } 15 | 16 | export interface IColumn { 17 | name?: string; 18 | label: string; 19 | description?: string; 20 | displayColumnHeader?: boolean; 21 | size: IBreakpointSize | number; 22 | getValue: { (item: TItemType): number | string | boolean } | string; 23 | headerTemplateUrl?: string; 24 | headerTemplate?: string; 25 | templateUrl?: string; 26 | template?: string; 27 | secondarySorts?: ISecondarySorts; 28 | flipSort?: boolean; 29 | sortDirection?: SortDirection; 30 | styling?: string; 31 | fieldName?: string; 32 | } 33 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/cardSearch/cardSearch.html: -------------------------------------------------------------------------------- 1 |
6 | 9 |
10 | 12 | 13 | 14 |
15 |
16 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/cardSearch/cardSearch.ng1.html: -------------------------------------------------------------------------------- 1 |
2 | 4 |
5 | 8 |
9 |
-------------------------------------------------------------------------------- /source/components/cardContainer/container/columnHeader/columnHeader.html: -------------------------------------------------------------------------------- 1 |
5 |
6 |
7 |
8 |
{{column.label}}
9 | 10 | 11 |
-------------------------------------------------------------------------------- /source/components/cardContainer/container/columnHeader/columnHeader.tests.ts: -------------------------------------------------------------------------------- 1 | import { ColumnHeaderComponent } from './columnHeader'; 2 | 3 | interface ISizeForBreakpointsMock { 4 | getClass: sinon.SinonSpy; 5 | } 6 | 7 | describe('ColumnHeaderComponent', () => { 8 | let columnHeader: ColumnHeaderComponent; 9 | let sizeForBreakpoints: ISizeForBreakpointsMock; 10 | 11 | beforeEach(() => { 12 | sizeForBreakpoints = { 13 | getClass: sinon.spy(), 14 | }; 15 | columnHeader = new ColumnHeaderComponent(sizeForBreakpoints); 16 | }); 17 | 18 | it('should set the sizeClass based on the column size settings', () => { 19 | columnHeader.column = { 20 | size: 3, 21 | styling: 'my-class', 22 | }; 23 | sizeForBreakpoints.getClass = sinon.spy(() => 'test-class'); 24 | 25 | columnHeader.ngOnInit(); 26 | 27 | sinon.assert.calledOnce(sizeForBreakpoints.getClass); 28 | sinon.assert.calledWith(sizeForBreakpoints.getClass, 3, 'my-class'); 29 | expect(columnHeader.sizeClass).to.equal('test-class'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/containerFooter.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
9 |
10 | 11 |
-------------------------------------------------------------------------------- /source/components/cardContainer/container/containerFooter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | import { ContainerFooterTemplate } from '../templates/containerFooter.template'; 4 | 5 | @Component({ 6 | selector: 'rlContainerFooter', 7 | template: require('./containerFooter.component.html'), 8 | changeDetection: ChangeDetectionStrategy.OnPush, 9 | }) 10 | export class ContainerFooterComponent { 11 | @Input() footer: ContainerFooterTemplate; 12 | } 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/containerHeader.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 8 |
9 |
10 | 11 |
-------------------------------------------------------------------------------- /source/components/cardContainer/container/containerHeader.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | import { ContainerHeaderTemplate } from '../templates/containerHeader.template'; 4 | 5 | @Component({ 6 | selector: 'rlContainerHeader', 7 | template: require('./containerHeader.component.html'), 8 | changeDetection: ChangeDetectionStrategy.OnPush, 9 | }) 10 | export class ContainerHeaderComponent { 11 | @Input() header: ContainerHeaderTemplate; 12 | } 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/defaultCardContainerFooter.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 |
7 | 8 |
9 |
10 | 11 |
12 |
13 |
14 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/defaultCardContainerHeader.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 8 |
9 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/defaultComponents.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export let headerComponentName: string = 'rlDefaultCardContainerHeader'; 4 | export let footerComponentName: string = 'rlDefaultCardContainerFooter'; 5 | 6 | export let defaultContainerHeader: angular.IComponentOptions = { 7 | template: require('./defaultCardContainerHeader.html'), 8 | }; 9 | 10 | export let defaultContainerFooter: angular.IComponentOptions = { 11 | template: require('./defaultCardContainerFooter.html'), 12 | }; 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/index.ts: -------------------------------------------------------------------------------- 1 | import { CardSearchComponent } from './cardSearch/cardSearch'; 2 | import { ItemCountComponent } from './itemCount/itemCount'; 3 | import { SelectionComponent } from './selectionControl/selectionControl'; 4 | 5 | export const CONTAINER_DIRECTIVES: any[] = [CardSearchComponent, ItemCountComponent, SelectionComponent]; 6 | 7 | export * from './cardSearch/cardSearch'; 8 | export * from './itemCount/itemCount'; 9 | export * from './selectionControl/selectionControl'; -------------------------------------------------------------------------------- /source/components/cardContainer/container/itemCount/itemCount.html: -------------------------------------------------------------------------------- 1 |

2 | Showing {{visibleCount$ | async}} of {{totalCount$ | async}} total items 3 |

4 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/itemCount/itemCount.ng1.html: -------------------------------------------------------------------------------- 1 |

2 | Showing {{itemCount.cardContainer.dataSource.dataSet.length}} of {{itemCount.cardContainer.dataSource.count}} total items 3 |

-------------------------------------------------------------------------------- /source/components/cardContainer/container/itemCount/itemCount.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export let moduleName: string = 'rl.ui.components.cardContainer.itemCount'; 4 | export let componentName: string = 'rlItemCount'; 5 | 6 | let itemCount: angular.IComponentOptions = { 7 | require: { cardContainer: '?^^rlCardContainer' }, 8 | template: require('./itemCount.ng1.html'), 9 | controllerAs: 'itemCount', 10 | }; 11 | 12 | angular.module(moduleName, []) 13 | .component(componentName, itemCount); 14 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/selectableContainerFooter.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 |
13 | 14 |
15 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/selectableContainerFooter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | import { ContainerFooterTemplate } from '../templates/containerFooter.template'; 4 | 5 | @Component({ 6 | selector: 'rlSelectableContainerFooter', 7 | template: require('./selectableContainerFooter.component.html'), 8 | changeDetection: ChangeDetectionStrategy.OnPush, 9 | }) 10 | export class SelectableContainerFooterComponent { 11 | @Input() footer: ContainerFooterTemplate; 12 | } 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/selectionControl/selectionControl.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{selectedItems$ | async}} items selected 4 |
5 |
6 | Select page 7 | Clear page 8 |
9 |
10 | Select all 11 | Clear all 12 |
13 |
14 | -------------------------------------------------------------------------------- /source/components/cardContainer/container/selectionControl/selectionControl.ng1.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{selection.selectedItems}} items selected 4 |
5 |
6 | 7 | 8 |
9 |
10 | 11 | 12 |
13 |
14 | -------------------------------------------------------------------------------- /source/components/cardContainer/dataSources/asyncTypes.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | export interface IServerSearchFunction { 4 | (searchParams: IServerSearchParams): Observable>; 5 | } 6 | 7 | export interface IServerSearchFunctionOld { 8 | (searchParams: IServerSearchParams): Promise> | Observable>; 9 | } 10 | 11 | export interface IServerSearchParams { 12 | filters: {[index: string]: any}; 13 | sorts: ISortParams[]; 14 | paging: IPagingParams; 15 | } 16 | 17 | export interface ISortParams { 18 | column: string; 19 | direction: string; 20 | } 21 | 22 | export interface IPagingParams { 23 | pageNumber: number; 24 | pageSize: number; 25 | } 26 | 27 | export interface IDataResult { 28 | dataSet: TDataType[]; 29 | count: number; 30 | isEmpty?: boolean; 31 | } 32 | -------------------------------------------------------------------------------- /source/components/cardContainer/dataSources/dataServiceDataSource/dataServiceDataSource.service.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { services } from 'typescript-angular-utilities'; 5 | import __array = services.array; 6 | 7 | import { IAsyncDataSource, AsyncDataSource, IDataSetFunction } from '../asyncDataSource.service'; 8 | import { IDataSourceProcessorOld } from '../processor/dataSourceProcessorOld.service'; 9 | 10 | export { IAsyncDataSource }; 11 | 12 | export interface IDataServiceFunction { 13 | (): Promise | Observable; 14 | } 15 | 16 | export class DataServiceDataSource extends AsyncDataSource implements IAsyncDataSource { 17 | constructor(getDataSet: IDataServiceFunction 18 | , dataSourceProcessor: IDataSourceProcessorOld 19 | , array: __array.IArrayUtility) { 20 | super(getDataSet, dataSourceProcessor, array); 21 | this.countFilterGroups = true; 22 | 23 | if (_.isFunction(getDataSet)) { 24 | this.reload(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /source/components/cardContainer/dataSources/index.ts: -------------------------------------------------------------------------------- 1 | export * from './clientServerDataSource/clientServerDataSource.service'; 2 | export * from './dataServiceDataSource/dataServiceDataSource.service'; 3 | export * from './observableDataSource/observableDataSource.service'; 4 | export * from './serverSideDataSource/serverSideDataSource.service'; 5 | export * from './simpleDataSource/simpleDataSource.service'; 6 | export * from './smartDataSource/smartDataSource.service'; 7 | export * from './smartDataSource/smartDataSourceOld.service'; 8 | export * from './asyncDataSource.service'; 9 | export * from './asyncTypes'; 10 | export * from './dataSource'; 11 | export * from './dataSourceBaseOld.service'; 12 | export * from './processor/dataSourceProcessorOld.service'; 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/dataSources/observableDataSource/observableDataSource.service.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | import { IDataSource } from '../dataSource'; 4 | import { DataSourceBase } from '../dataSourceBase.service'; 5 | import { Sorter } from '../../sorts/index'; 6 | 7 | export { IDataSource }; 8 | 9 | export class ObservableDataSource extends DataSourceBase implements IDataSource { 10 | private dataStream$: Observable; 11 | 12 | constructor(dataSet$: Observable) { 13 | super(); 14 | this.countFilterGroups = true; 15 | this.dataStream$ = dataSet$; 16 | } 17 | 18 | init(): void { 19 | this._dataSet.next(null); 20 | this._rawDataSet.next(null); 21 | this._loadingDataSet.next(true); 22 | 23 | this.dataStream$.subscribe(data => { 24 | this._rawDataSet.next(data); 25 | this._loadingDataSet.next(!data); 26 | this.processData(); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /source/components/cardContainer/dataSources/simpleDataSource/simpleDataSource.service.ts: -------------------------------------------------------------------------------- 1 | import { services } from 'typescript-angular-utilities'; 2 | import __array = services.array; 3 | 4 | import { IDataSourceOld } from '../dataSource'; 5 | import { DataSourceBaseOld } from '../dataSourceBaseOld.service'; 6 | import { IDataSourceProcessorOld } from '../processor/dataSourceProcessorOld.service'; 7 | 8 | export { IDataSourceOld }; 9 | 10 | export class SimpleDataSource extends DataSourceBaseOld { 11 | constructor(data: TDataType[] 12 | , dataSourceProcessor: IDataSourceProcessorOld 13 | , array: __array.IArrayUtility) { 14 | super(dataSourceProcessor, array); 15 | this.countFilterGroups = false; 16 | this.rawDataSet = data; 17 | this.isEmpty = !(data && data.length); 18 | this.processData(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/cardContainerFilters.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /source/components/cardContainer/filters/dateFilter/dateFilter.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 9 |
10 |
11 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/dateFilter/dateFilter.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { services, downgrade } from 'typescript-angular-utilities'; 4 | 5 | import { componentName, dateFilter, controllerName, DateFilterController }from './dateFilter.component.ng1'; 6 | 7 | export const moduleName: string = 'rl.ui.components.cardContainer.filters.dateFilter'; 8 | export * from './dateFilterOld.service'; 9 | export * from './dateFilter.component.ng1'; 10 | 11 | angular.module(moduleName, [downgrade.moduleName]) 12 | .component(componentName, dateFilter) 13 | .controller(controllerName, DateFilterController); 14 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/dateFilter/dateFilter.ng1.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 |
7 | 8 |
9 | 10 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 24 | 25 |
26 |
27 |
-------------------------------------------------------------------------------- /source/components/cardContainer/filters/dateFilter/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dateFilter.component'; 2 | export * from './dateFilterOld.service'; 3 | export * from './dateFilter.service'; 4 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filter.tests.ts: -------------------------------------------------------------------------------- 1 | import { Observable } from 'rxjs'; 2 | 3 | import { Filter } from './filter'; 4 | 5 | class TestFilter extends Filter { 6 | predicate = (item, value) => true; 7 | 8 | setValue(value: any): void { 9 | this.value$.next(value); 10 | } 11 | } 12 | 13 | describe('Filter', () => { 14 | let filter: TestFilter; 15 | 16 | beforeEach(() => { 17 | filter = new TestFilter(); 18 | }); 19 | 20 | it('should filter the data using the predicate', () => { 21 | const unfiltered = [1, 2, 3, 4]; 22 | const filtered = [3, 4]; 23 | filter.predicate = (item, value) => item > value; 24 | filter.setValue(2); 25 | let result; 26 | 27 | filter.filter(Observable.of(unfiltered)).subscribe(data => result = data); 28 | 29 | expect(result).to.deep.equal(filtered); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filter.ts: -------------------------------------------------------------------------------- 1 | import { Observable, BehaviorSubject } from 'rxjs'; 2 | import { filter } from 'lodash'; 3 | 4 | export interface IFilter { 5 | type?: string; 6 | serialize(): Observable; 7 | filter(data$: Observable): Observable; 8 | } 9 | 10 | export interface IFilterPredicate { 11 | (item: TDataType, filterData: TFilterData): boolean; 12 | } 13 | 14 | export abstract class Filter implements IFilter { 15 | protected value$: BehaviorSubject; 16 | 17 | abstract predicate: IFilterPredicate; 18 | 19 | constructor() { 20 | this.value$ = new BehaviorSubject(null); 21 | } 22 | 23 | filter(data$: Observable): Observable { 24 | return data$.combineLatest(this.value$) 25 | .map(([data, filterData]) => filter(data, item => this.predicate(item, filterData))); 26 | } 27 | 28 | serialize(): Observable { 29 | return this.value$.asObservable(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterGroup.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 |
8 |

{{headerTitle}}

9 |
10 |
11 |
12 |
13 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterGroup.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | import { IDataSource } from '../../dataSources/index'; 4 | import { IFilterGroup, IFilterOption } from './filterGroup.service'; 5 | 6 | @Component({ 7 | selector: 'rlFilterGroup', 8 | template: require('./filterGroup.component.html'), 9 | changeDetection: ChangeDetectionStrategy.OnPush, 10 | }) 11 | export class FilterGroupComponent { 12 | @Input() filterGroup: IFilterGroup; 13 | @Input() icon: string; 14 | @Input() disabled: boolean; 15 | 16 | expanded: boolean = true; 17 | 18 | get headerTitle(): string { 19 | if (!this.disabled) { 20 | return this.filterGroup.label + ': ' + this.filterGroup.activeOption.label 21 | } 22 | 23 | return this.filterGroup.label; 24 | } 25 | 26 | toggleExpanded(): void { 27 | this.expanded = !this.expanded; 28 | } 29 | 30 | get childrenVisible(): boolean { 31 | return this.expanded && !this.disabled; 32 | } 33 | 34 | selectOption(option: IFilterOption): void { 35 | this.filterGroup.activeOption = option; 36 | this.expanded = false; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterGroup.directive.ng1.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 |
8 |

{{controller.headerTitle}}

9 |
10 |
11 |
12 |
13 | 14 |
15 |
16 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterGroup.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | import { downgrade } from 'typescript-angular-utilities'; 3 | 4 | import * as filterOption from './filterOption/filterOption.ng1'; 5 | import * as modeFilterGroup from './modeFilterGroup/modeFilterGroupOld.service'; 6 | import * as rangeFilterGroup from './rangeFilterGroup/rangeFilterGroupOld.service'; 7 | 8 | export { 9 | filterOption, 10 | modeFilterGroup, 11 | rangeFilterGroup, 12 | }; 13 | 14 | import { componentName, filterGroup, controllerName, FilterGroupController } from './filterGroup.directive.ng1'; 15 | 16 | export * from './filterGroup.directive.ng1'; 17 | export * from './filterGroupOld.service'; 18 | 19 | export const moduleName: string = 'rl.ui.components.cardContainer.filters.filterGroup'; 20 | 21 | angular.module(moduleName, [ 22 | downgrade.moduleName, 23 | 24 | filterOption.moduleName, 25 | ]) 26 | .component(componentName, filterGroup) 27 | .controller(controllerName, FilterGroupController); 28 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterOption/filterOption.html: -------------------------------------------------------------------------------- 1 |
4 |
5 | 6 |
7 |
8 |
10 | {{option?.label}} 11 |
12 |
13 | ({{option?.count}}) 14 |
15 |
-------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterOption/filterOption.ng1.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | {{filter.option.label}} 8 |
9 |
10 | ({{filter.option.count}}) 11 |
12 |
-------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterOption/filterOption.ng1.ts: -------------------------------------------------------------------------------- 1 | // /// 2 | 3 | import * as angular from 'angular'; 4 | 5 | export var moduleName: string = 'rl.ui.components.cardContainer.filters.filterGroup.filterOption'; 6 | export var componentName: string = 'rlFilterOption'; 7 | 8 | let filterOption: angular.IComponentOptions = { 9 | template: require('./filterOption.ng1.html'), 10 | controllerAs: 'filter', 11 | bindings: { 12 | activate: '&', 13 | isActive: '=active', 14 | option: '=', 15 | }, 16 | }; 17 | 18 | angular.module(moduleName, []) 19 | .component(componentName, filterOption); 20 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/filterOption/filterOption.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | import { IFilterGroupOld, IFilterOptionOld } from '../filterGroupOld.service'; 4 | 5 | @Component({ 6 | selector: 'rlFilterOption', 7 | template: require('./filterOption.html'), 8 | changeDetection: ChangeDetectionStrategy.OnPush, 9 | }) 10 | export class FilterOptionComponent { 11 | @Input() option: IFilterOptionOld; 12 | @Input() isActive: boolean; 13 | @Output() activate: EventEmitter = new EventEmitter(); 14 | } 15 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filterGroup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './filterOption/filterOption'; 2 | export * from './modeFilterGroup/modeFilterGroupOld.service'; 3 | export * from './modeFilterGroup/modeFilterGroup.service'; 4 | export * from './rangeFilterGroup/rangeFilterGroupOld.service'; 5 | export * from './rangeFilterGroup/rangeFilterGroup.service'; 6 | export * from './filterGroupOld.service'; 7 | export * from './filterGroup.service'; 8 | export * from './filterGroup.component'; 9 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/filters.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import * as columnSearchFilter from './columnSearchFilter/columnSearchFilter.service'; 4 | import * as dateFilter from './dateFilter/dateFilter.module'; 5 | import * as filterGroup from './filterGroup/filterGroup.module'; 6 | import * as selectFilter from './selectFilter/selectFilter.module'; 7 | 8 | import * as cardContainerFilters from './cardContainerFilters'; 9 | 10 | export * from './cardContainerFilters'; 11 | 12 | export { columnSearchFilter, filterGroup, selectFilter }; 13 | 14 | export var moduleName: string = 'rl.ui.components.cardContainer.filters'; 15 | 16 | angular.module(moduleName, [ 17 | dateFilter.moduleName, 18 | filterGroup.moduleName, 19 | selectFilter.moduleName, 20 | 21 | cardContainerFilters.moduleName 22 | ]); 23 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/index.ts: -------------------------------------------------------------------------------- 1 | import { DateFilterComponent } from './dateFilter/index'; 2 | import { FilterGroupComponent } from './filterGroup/index'; 3 | import { SelectFilterComponent } from './selectFilter/index'; 4 | 5 | export const FILTER_DIRECTIVES: any[] = [DateFilterComponent, FilterGroupComponent, SelectFilterComponent]; 6 | 7 | export * from './filter'; 8 | export * from './columnSearchFilter/columnSearchFilter.service'; 9 | export * from './dateFilter/index'; 10 | export * from './filterGroup/index'; 11 | export * from './searchFilter/searchFilter.service'; 12 | export * from './selectFilter/index'; 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/selectFilter/index.ts: -------------------------------------------------------------------------------- 1 | export * from './selectFilterOld.service'; 2 | export * from './selectFilter.service'; 3 | export * from './selectFilter.component'; 4 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/selectFilter/selectFilter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ContentChild, TemplateRef, ChangeDetectionStrategy } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { services } from 'typescript-angular-utilities'; 5 | import ITransform = services.transform.ITransform; 6 | 7 | import { SelectFilter } from './selectFilter.service'; 8 | import { IDataSource } from '../../datasources/dataSource'; 9 | 10 | @Component({ 11 | selector: 'rlSelectFilter', 12 | template: require('./selectFilter.html'), 13 | changeDetection: ChangeDetectionStrategy.OnPush, 14 | }) 15 | export class SelectFilterComponent { 16 | @Input() filter: SelectFilter; 17 | @Input() label: string; 18 | @Input() options: T[]; 19 | @Input() transform: ITransform; 20 | @Input() nullOption: string; 21 | 22 | @ContentChild(TemplateRef) template: TemplateRef; 23 | } 24 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/selectFilter/selectFilter.html: -------------------------------------------------------------------------------- 1 |
2 | 9 |
10 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/selectFilter/selectFilter.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import {componentName, selectFilter, controllerName, SelectFilterController }from './selectFilter.component.ng1'; 4 | 5 | export const moduleName: string = 'rl.ui.components.cardContainer.filters.selectFilter'; 6 | export * from './selectFilterOld.service'; 7 | export * from './selectFilter.component.ng1'; 8 | 9 | angular.module(moduleName, []) 10 | .component(componentName, selectFilter) 11 | .controller(controllerName, SelectFilterController); 12 | -------------------------------------------------------------------------------- /source/components/cardContainer/filters/selectFilter/selectFilter.ng1.html: -------------------------------------------------------------------------------- 1 |
2 | 4 |
-------------------------------------------------------------------------------- /source/components/cardContainer/index.ts: -------------------------------------------------------------------------------- 1 | import * as builder from './builder/index'; 2 | import * as container from './container/index'; 3 | import * as dataSources from './dataSources/index'; 4 | import * as filters from './filters/index'; 5 | import * as paging from './paging/index'; 6 | import * as sorts from './sorts/index'; 7 | import * as templates from './templates/index'; 8 | 9 | import { CardContainerComponent } from './cardContainer'; 10 | import { SelectableCardContainerComponent } from './selectableCardContainer'; 11 | import { CardComponent } from './card/card'; 12 | import { SelectableCardComponent } from './card/selectableCard'; 13 | 14 | export const CARD_CONTAINER_DIRECTIVES: any[] = [CardContainerComponent, SelectableCardContainerComponent, CardComponent, SelectableCardComponent, container.CONTAINER_DIRECTIVES, filters.FILTER_DIRECTIVES, templates.TEMPLATE_DIRECTIVES, paging.PAGER_DIRECTIVES]; 15 | export const CARD_CONTAINER_PROVIDERS: any[] = [builder.BUILDER_PROVIDERS]; 16 | 17 | export { container, builder, dataSources, filters, paging, sorts, templates }; 18 | 19 | export * from './card/card'; 20 | export * from './cardContainer'; 21 | export * from './selectableCardContainer'; 22 | export * from './column'; 23 | -------------------------------------------------------------------------------- /source/components/cardContainer/paging/index.ts: -------------------------------------------------------------------------------- 1 | import { PagerComponent } from './pager/pager'; 2 | import { PageSizeComponent } from './pageSize/pageSize'; 3 | 4 | export const PAGER_DIRECTIVES: any[] = [PagerComponent, PageSizeComponent]; 5 | 6 | export * from './dataPager/dataPagerOld.service'; 7 | export * from './dataPager/dataPager.service'; 8 | export * from './pager/pager'; 9 | export * from './pageSize/pageSize'; 10 | -------------------------------------------------------------------------------- /source/components/cardContainer/paging/pageSize/pageSize.html: -------------------------------------------------------------------------------- 1 |
2 | 6 |
7 | -------------------------------------------------------------------------------- /source/components/cardContainer/paging/pageSize/pageSize.ng1.html: -------------------------------------------------------------------------------- 1 |
2 | 4 |
5 | -------------------------------------------------------------------------------- /source/components/cardContainer/paging/pageSize/pageSize.tests.ts: -------------------------------------------------------------------------------- 1 | import { PageSizeComponent, availablePageSizes } from './pageSize'; 2 | 3 | interface IPagerMock { 4 | pageSize: number; 5 | } 6 | 7 | describe('PageSizeComponent', (): void => { 8 | let pageSize: PageSizeComponent; 9 | 10 | it('should get the pager from the card container and set the defaults', (): void => { 11 | const pager: IPagerMock = { pageSize: null }; 12 | const cardContainer: any = { 13 | dataSource: { pager }, 14 | }; 15 | 16 | pageSize = new PageSizeComponent(cardContainer); 17 | 18 | expect(pageSize.pager).to.equal(pager); 19 | expect(pageSize.pageSizes).to.equal(availablePageSizes); 20 | }); 21 | }); -------------------------------------------------------------------------------- /source/components/cardContainer/paging/pageSize/pageSize.ts: -------------------------------------------------------------------------------- 1 | import { Component, Inject, forwardRef, ChangeDetectionStrategy } from '@angular/core'; 2 | 3 | import { IDataPager } from '../dataPager/dataPager.service'; 4 | import { CardContainerComponent } from '../../cardContainer'; 5 | 6 | export const availablePageSizes: number[] = [10, 15, 20, 25]; 7 | 8 | @Component({ 9 | selector: 'rlPageSize', 10 | template: require('./pageSize.html'), 11 | changeDetection: ChangeDetectionStrategy.OnPush, 12 | }) 13 | export class PageSizeComponent { 14 | pageSizes: number[]; 15 | 16 | cardContainer: CardContainerComponent; 17 | pager: IDataPager; 18 | 19 | constructor(@Inject(forwardRef(() => CardContainerComponent)) cardContainer: CardContainerComponent) { 20 | this.cardContainer = cardContainer; 21 | 22 | this.pager = this.cardContainer.dataSource.pager; 23 | 24 | this.pageSizes = availablePageSizes; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /source/components/cardContainer/paging/pager/pager.html: -------------------------------------------------------------------------------- 1 | 31 | -------------------------------------------------------------------------------- /source/components/cardContainer/paging/pager/pager.ng1.html: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /source/components/cardContainer/sorts/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sorter/sorter.service'; 2 | export * from './mergeSort/mergeSort.service'; 3 | export * from './sortManager/sortManager.service'; 4 | export * from './sort'; 5 | export * from './sortDirection'; 6 | -------------------------------------------------------------------------------- /source/components/cardContainer/sorts/sort.ts: -------------------------------------------------------------------------------- 1 | import { types } from 'typescript-angular-utilities'; 2 | 3 | import { IColumn } from '../column'; 4 | import { SortDirection } from './sortDirection'; 5 | 6 | export * from './sortDirection'; 7 | 8 | export interface ICompareFunction { 9 | (a: TDataType, b: TDataType): types.CompareResult; 10 | } 11 | 12 | export interface ISort { 13 | column: IColumn; 14 | direction: SortDirection; 15 | } 16 | 17 | export interface IPartialSort { 18 | column: string; 19 | direction: SortDirection; 20 | } 21 | -------------------------------------------------------------------------------- /source/components/cardContainer/sorts/sortDirection.ts: -------------------------------------------------------------------------------- 1 | export interface ISortDirections { 2 | ascending: SortDirection; 3 | descending: SortDirection; 4 | none: SortDirection; 5 | } 6 | 7 | export class SortDirection { 8 | public static none: SortDirection = new SortDirection(0); 9 | public static ascending: SortDirection = new SortDirection(1); 10 | public static descending: SortDirection = new SortDirection(2); 11 | 12 | constructor(private value: number) { } 13 | 14 | public static toggle(direction: SortDirection): SortDirection { 15 | if (direction === SortDirection.ascending) { 16 | return SortDirection.descending; 17 | } else if (direction === SortDirection.descending) { 18 | return SortDirection.none; 19 | } else { 20 | return SortDirection.ascending; 21 | } 22 | } 23 | 24 | public static getFullName(direction: SortDirection): string { 25 | 'use strict'; 26 | if (direction === SortDirection.ascending) { 27 | return 'ascending'; 28 | } else if (direction === SortDirection.descending) { 29 | return 'descending'; 30 | } else { 31 | return 'none'; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /source/components/cardContainer/templates/columnContent.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef, Input } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlColumnContent]' }) 4 | export class ColumnContentTemplate { 5 | @Input() rlColumnContentName: string; 6 | 7 | get name(): string { 8 | return this.rlColumnContentName; 9 | } 10 | 11 | constructor(public template: TemplateRef) { } 12 | } -------------------------------------------------------------------------------- /source/components/cardContainer/templates/columnHeader.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef, Input } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlColumnHeader]' }) 4 | export class ColumnHeaderTemplate { 5 | @Input() rlColumnHeaderName: string; 6 | 7 | get name(): string { 8 | return this.rlColumnHeaderName; 9 | } 10 | 11 | constructor(public template: TemplateRef) { } 12 | } 13 | -------------------------------------------------------------------------------- /source/components/cardContainer/templates/containerFooter.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlContainerFooter]' }) 4 | export class ContainerFooterTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } 7 | -------------------------------------------------------------------------------- /source/components/cardContainer/templates/containerHeader.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlContainerHeader]' }) 4 | export class ContainerHeaderTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/cardContainer/templates/index.ts: -------------------------------------------------------------------------------- 1 | import { ColumnContentTemplate } from './columnContent.template'; 2 | import { ColumnHeaderTemplate } from './columnHeader.template'; 3 | import { ContainerHeaderTemplate } from './containerHeader.template'; 4 | import { ContainerFooterTemplate } from './containerFooter.template'; 5 | import { CARD_TEMPLATE_DIRECTIVES } from '../../cards/index'; 6 | 7 | export const TEMPLATE_DIRECTIVES: any[] = [CARD_TEMPLATE_DIRECTIVES, ColumnContentTemplate, ColumnHeaderTemplate, ContainerHeaderTemplate, ContainerFooterTemplate]; 8 | 9 | export * from './columnContent.template'; 10 | export * from './columnHeader.template'; 11 | export * from './containerHeader.template'; 12 | export * from './containerFooter.template'; 13 | -------------------------------------------------------------------------------- /source/components/cards/cardContent.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlCardContent]' }) 4 | export class CardContentTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/cards/cardFooter.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlCardFooter]' }) 4 | export class CardFooterTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/cards/cardHeader.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlCardHeader]' }) 4 | export class CardHeaderTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/cards/index.ts: -------------------------------------------------------------------------------- 1 | import { CardHeaderTemplate } from './cardHeader.template'; 2 | import { CardContentTemplate } from './cardContent.template'; 3 | import { CardFooterTemplate } from './cardFooter.template'; 4 | 5 | export const CARD_TEMPLATE_DIRECTIVES: any[] = [CardHeaderTemplate, CardContentTemplate, CardFooterTemplate]; 6 | 7 | export * from './cardHeader.template'; 8 | export * from './cardContent.template'; 9 | export * from './cardFooter.template'; 10 | -------------------------------------------------------------------------------- /source/components/commaList/commaList.html: -------------------------------------------------------------------------------- 1 | 2 | {{item}}, 3 | 4 | ... {{remainingItems}} more items -------------------------------------------------------------------------------- /source/components/commaList/commaList.md: -------------------------------------------------------------------------------- 1 | # Comma list 2 | A simple component for displaying an array as a comma separated list. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `list` 11 | 12 | Specifies the list that is going to be displayed. 13 | 14 | #### `max` 15 | 16 | Specifies the maximum number of items that should be shown. If the list exceeds the maximum, the remaining items are truncated and an ellipses (...) is shown. 17 | 18 | #### `transform` 19 | 20 | A selector for getting the display name of the options. Can be a property name or a function that returns a string. 21 | 22 | ### Full Example 23 | A comma-list with a **list**, **max**, and **transform**. 24 | ``` 25 | // myList = [{ value: 1 }, { value: 2 }, { value: 3 }]; 26 | 27 | ``` 28 | Output: 29 | ``` 30 | 1, 2... 1 more items 31 | ``` -------------------------------------------------------------------------------- /source/components/componentsDefaultTheme.ts: -------------------------------------------------------------------------------- 1 | export const defaultThemeValueName: string = 'useDefaultTheme'; 2 | export const defaultThemeValue: boolean = true; 3 | 4 | export class DefaultTheme { 5 | useDefaultTheme: boolean = true; 6 | } 7 | -------------------------------------------------------------------------------- /source/components/dateTimeStatic/dateTimeStatic.html: -------------------------------------------------------------------------------- 1 | {{view.dateValue | rlDate:view.includeTime}} -------------------------------------------------------------------------------- /source/components/dateTimeStatic/dateTimeStatic.md: -------------------------------------------------------------------------------- 1 | # Date time static (deprecated) 2 | A component that wraps the [`date filter`](../../filters/date/date.filter.md). Use the date filter instead for simplicity. 3 | 4 | ### Usage 5 | ``` 6 | 7 | ``` 8 | Output: 9 | ``` 10 | {{dateValue | rlDate:includeTime?}} 11 | ``` -------------------------------------------------------------------------------- /source/components/dateTimeStatic/dateTimeStatic.ts: -------------------------------------------------------------------------------- 1 | // /// 2 | 3 | import * as angular from 'angular'; 4 | import * as moment from 'moment'; 5 | 6 | 7 | export let moduleName: string = 'rl.ui.components.dateTimeStatic'; 8 | export let componentName: string = 'rlDateTimeStatic'; 9 | 10 | export interface IDateTimeStaticBindings { 11 | dateValue: moment.Moment; 12 | includeTime: boolean; 13 | } 14 | 15 | let dateTimeStaticComponent: angular.IComponentOptions = { 16 | template: require('./dateTimeStatic.html'), 17 | controllerAs: 'view', 18 | bindings: { 19 | dateValue: '<', 20 | includeTime: ' Cancel 2 | Save
3 | -------------------------------------------------------------------------------- /source/components/dialog/dialog.ng1.html: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 16 | 20 | -------------------------------------------------------------------------------- /source/components/dialog/dialogRoot.service.tests.ts: -------------------------------------------------------------------------------- 1 | import { DialogRootService } from './dialogRoot.service'; 2 | 3 | describe('DialogRootService', (): void => { 4 | let dialogRoot: DialogRootService; 5 | 6 | beforeEach((): void => { 7 | dialogRoot = new DialogRootService(); 8 | }); 9 | 10 | it('should set the dialog context on open', (): void => { 11 | expect(dialogRoot.dialogContext).to.not.exist; 12 | 13 | const context = {}; 14 | 15 | dialogRoot.openDialog.next(context); 16 | 17 | expect(dialogRoot.dialogContext).to.equal(context); 18 | }); 19 | 20 | it('should call onClosing on the context or return true if unspecified', (): void => { 21 | expect(dialogRoot.onClosing()).to.be.true; 22 | 23 | const onClosing = sinon.spy(() => false); 24 | dialogRoot.openDialog.next({ onClosing: onClosing }); 25 | 26 | const canClose = dialogRoot.onClosing(); 27 | 28 | expect(canClose).to.be.false; 29 | sinon.assert.calledOnce(onClosing); 30 | }); 31 | }); -------------------------------------------------------------------------------- /source/components/dialog/dialogRoot.service.ts: -------------------------------------------------------------------------------- 1 | import { Subject } from 'rxjs'; 2 | 3 | import { DialogHeaderTemplate, DialogContentTemplate, DialogFooterTemplate } from './templates/index'; 4 | 5 | export interface IDialogContent { 6 | id?: string; 7 | onClosing?: IDialogClosingHandler; 8 | header?: DialogHeaderTemplate; 9 | content?: DialogContentTemplate; 10 | footer?: DialogFooterTemplate; 11 | autosave?: boolean; 12 | submitAndClose?: { (): void }; 13 | size?: string; 14 | } 15 | 16 | export interface IDialogClosingHandler { 17 | (): boolean; 18 | } 19 | 20 | export class DialogRootService { 21 | dialogContext: IDialogContent; 22 | dismissing: boolean = false; 23 | 24 | openDialog: Subject = new Subject(); 25 | closeDialog: Subject = new Subject(); 26 | 27 | constructor() { 28 | this.openDialog.subscribe(context => this.dialogContext = context); 29 | } 30 | 31 | onClosing(): boolean { 32 | if (this.dialogContext) { 33 | return this.dialogContext.onClosing(); 34 | } else { 35 | return true; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /source/components/dialog/index.ts: -------------------------------------------------------------------------------- 1 | import { DialogComponent } from './dialog'; 2 | import { DialogOutletComponent } from './dialogOutlet'; 3 | import { PromptDialogComponent } from './promptDialog'; 4 | import { DialogRootService } from './dialogRoot.service'; 5 | import { DIALOG_TEMPLATE_DIRECTIVES } from './templates/index'; 6 | 7 | export const DIALOG_DIRECTIVES: any[] = [DialogComponent, DialogOutletComponent, PromptDialogComponent, DIALOG_TEMPLATE_DIRECTIVES]; 8 | export const DIALOG_PROVIDERS: any[] = [DialogRootService]; 9 | 10 | export * from './dialog'; 11 | export * from './dialogOutlet'; 12 | export * from './dialogRoot.service'; 13 | export * from './promptDialog'; 14 | -------------------------------------------------------------------------------- /source/components/dialog/promptDialog.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | {{message}} 4 |
5 |
6 | {{cancelButton}} 7 | {{okButton}} 8 |
9 |
-------------------------------------------------------------------------------- /source/components/dialog/promptDialog.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter, ViewChild } from '@angular/core'; 2 | import { Subject } from 'rxjs/Subject'; 3 | 4 | import { DialogComponent } from './dialog'; 5 | import { DialogRootService } from './dialogRoot.service'; 6 | 7 | @Component({ 8 | selector: 'rlPromptDialog', 9 | template: require('./promptDialog.html'), 10 | }) 11 | export class PromptDialogComponent { 12 | @Input() message: string; 13 | @Input() okButton: string = 'Ok'; 14 | @Input() cancelButton: string = 'Cancel'; 15 | @Output() onAccept: EventEmitter = new EventEmitter(); 16 | @Output() onCancel: EventEmitter = new EventEmitter(); 17 | 18 | @ViewChild(DialogComponent) dialog: DialogComponent; 19 | 20 | constructor(private dialogRoot: DialogRootService) { } 21 | 22 | open(): void { 23 | this.dialog.open(); 24 | } 25 | 26 | accept(): void { 27 | this.onAccept.emit(null); 28 | if (this.dialog.isOpen()) { 29 | this.dialog.close(); 30 | } 31 | } 32 | 33 | cancel(): void { 34 | this.onCancel.emit(null); 35 | if (this.dialog.isOpen()) { 36 | this.dialog.close(); 37 | } 38 | } 39 | 40 | dismiss(): void { 41 | this.dialog.dismiss(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /source/components/dialog/templates/dialogContent.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlDialogContent]' }) 4 | export class DialogContentTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/dialog/templates/dialogFooter.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlDialogFooter]' }) 4 | export class DialogFooterTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/dialog/templates/dialogHeader.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlDialogHeader]' }) 4 | export class DialogHeaderTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/dialog/templates/index.ts: -------------------------------------------------------------------------------- 1 | import { DialogHeaderTemplate } from './dialogHeader.template'; 2 | import { DialogContentTemplate } from './dialogContent.template'; 3 | import { DialogFooterTemplate } from './dialogFooter.template'; 4 | 5 | export const DIALOG_TEMPLATE_DIRECTIVES: any[] = [DialogHeaderTemplate, DialogContentTemplate, DialogFooterTemplate]; 6 | 7 | export * from './dialogHeader.template'; 8 | export * from './dialogContent.template'; 9 | export * from './dialogFooter.template'; 10 | -------------------------------------------------------------------------------- /source/components/form/RecluseForm.ts: -------------------------------------------------------------------------------- 1 | import { Component, forwardRef } from '@angular/core'; 2 | import { FormGroup } from '@angular/forms'; 3 | 4 | import { FormComponent } from '../form/form'; 5 | 6 | @Component({ 7 | selector: 'rlRecluseForm', 8 | template: '', 9 | providers: [ 10 | { 11 | provide: FormComponent, 12 | useExisting: forwardRef(() => RecluseFormComponent), 13 | }, 14 | ], 15 | }) 16 | export class RecluseFormComponent { 17 | form = new FormGroup({}); 18 | } 19 | -------------------------------------------------------------------------------- /source/components/form/form.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /source/components/form/form.md: -------------------------------------------------------------------------------- 1 | # Form 2 | Component that wraps an angular form with the ability to validate and show an error if the user attempts to submit the form. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `save` 11 | 12 | This expression will be triggered whenever validation passes and the form is submitted. 13 | 14 | #### `saving` 15 | 16 | Outputs a flag specifying if the form is currently saving. 17 | 18 | #### `form` 19 | 20 | Outputs the underlying angular form object. 21 | 22 | #### `child-link` 23 | 24 | If specified, the form component will attach child behavior for triggering the form to save programmatically using the [parentChildBehavior](https://github.com/RenovoSolutions/TypeScript-Angular-Utilities/blob/master/source/services/parentChildBehavior/parentChildBehavior.service.ts) service. 25 | 26 | #### `initialize-dirty` 27 | 28 | If `true`, the form component will default to a dirty state and allow submission even if no values are changed. If `false` (default), the form starts as pristine. 29 | -------------------------------------------------------------------------------- /source/components/form/index.ts: -------------------------------------------------------------------------------- 1 | import { FormComponent } from './form'; 2 | import { INPUT_DIRECTIVES } from '../inputs/index'; 3 | import { AutosaveDirective } from '../../behaviors/autosave/autosave'; 4 | import { RecluseFormComponent } from './RecluseForm'; 5 | 6 | export const FORM_DIRECTIVES = [FormComponent, INPUT_DIRECTIVES, AutosaveDirective, RecluseFormComponent]; 7 | 8 | export * from './form'; 9 | -------------------------------------------------------------------------------- /source/components/inputs/checkbox/checkbox.css: -------------------------------------------------------------------------------- 1 | .rl-checkbox.default-theme:before { 2 | font-family: FontAwesome; 3 | content: "\f096"; /*fa-square-o*/ 4 | font-size: 1.5em; 5 | position: relative; 6 | top: .05em; 7 | } 8 | 9 | .rl-checkbox-checked.default-theme:before { 10 | font-family: FontAwesome; 11 | content: "\f046"; /*fa-check-square-o*/ 12 | font-size: 1.4em; 13 | } 14 | 15 | .rl-checkbox.default-theme.disabled:before, 16 | .rl-checkbox-checked.default-theme.disabled:before { 17 | opacity: 0.6; 18 | } 19 | -------------------------------------------------------------------------------- /source/components/inputs/checkbox/checkbox.html: -------------------------------------------------------------------------------- 1 | 6 | {{label}} 7 | -------------------------------------------------------------------------------- /source/components/inputs/checkbox/checkbox.ng1.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/inputs/checkbox/checkbox.tests.ts: -------------------------------------------------------------------------------- 1 | import { services } from 'typescript-angular-utilities'; 2 | 3 | import { CheckboxComponent } from './checkbox'; 4 | 5 | describe('CheckboxComponent', () => { 6 | let checkbox: CheckboxComponent; 7 | let setValue: sinon.SinonSpy; 8 | 9 | beforeEach(() => { 10 | checkbox = new CheckboxComponent({}, null, null, null); 11 | setValue = sinon.spy(value => checkbox.value = value); 12 | checkbox.setValue = setValue; 13 | 14 | expect(checkbox.value).to.be.undefined; 15 | }); 16 | 17 | it('should toggle the value if active', (): void => { 18 | checkbox.toggle(); 19 | 20 | sinon.assert.calledOnce(setValue); 21 | sinon.assert.calledWith(setValue, true); 22 | 23 | checkbox.toggle(); 24 | 25 | sinon.assert.calledTwice(setValue); 26 | sinon.assert.calledWith(setValue, false); 27 | }); 28 | 29 | it('should not toggle if not active', (): void => { 30 | checkbox.active = false; 31 | checkbox.toggle(); 32 | sinon.assert.notCalled(setValue); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /source/components/inputs/checkbox/checkbox.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Optional } from '@angular/core'; 2 | 3 | import { services } from 'typescript-angular-utilities'; 4 | import __object = services.object; 5 | import __array = services.array; 6 | import __guid = services.guid; 7 | 8 | import { DefaultTheme } from '../../componentsDefaultTheme'; 9 | 10 | import { InputComponent, baseInputs, baseOutputs } from '../input'; 11 | import { FormComponent } from '../../form/form'; 12 | 13 | @Component({ 14 | selector: 'rlCheckbox', 15 | template: require('./checkbox.html'), 16 | inputs: baseInputs, 17 | outputs: baseOutputs, 18 | }) 19 | export class CheckboxComponent extends InputComponent { 20 | @Input() active: boolean = true; 21 | 22 | useDefaultTheme: boolean; 23 | 24 | constructor(defaultTheme: DefaultTheme 25 | , @Optional() rlForm: FormComponent 26 | , object: __object.ObjectUtility 27 | , guid: __guid.GuidService) { 28 | super(rlForm, object, guid); 29 | this.inputType = 'checkbox'; 30 | this.initControl(); 31 | this.useDefaultTheme = defaultTheme.useDefaultTheme; 32 | } 33 | 34 | toggle(): void { 35 | if (this.active) { 36 | this.setValue(!this.value); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /source/components/inputs/dateTime/dateTime.html: -------------------------------------------------------------------------------- 1 |
6 | 7 | 8 | 17 | 18 | 19 | 20 | {{timezone?.display}} 21 | 22 | 23 | 25 | 26 | 27 | 28 |
29 | {{componentValidator.error$ | async}} 30 |
31 |
32 | -------------------------------------------------------------------------------- /source/components/inputs/dateTime/dateTime.ng1.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 | {{dateTime.timezone.display}} 9 | 10 | 11 | 14 | 15 | {{dateTime.inputValidator.error}} 16 |
-------------------------------------------------------------------------------- /source/components/inputs/radio/index.ts: -------------------------------------------------------------------------------- 1 | import { RadioGroupComponent } from './radioGroup'; 2 | import { RadioComponent } from './radio'; 3 | 4 | export const RADIO_DIRECTIVES: any[] = [RadioGroupComponent, RadioComponent]; 5 | 6 | export * from './radioGroup'; 7 | export * from './radio'; -------------------------------------------------------------------------------- /source/components/inputs/radio/radio.css: -------------------------------------------------------------------------------- 1 | .rl-radio.default-theme:before { 2 | font-family: FontAwesome; 3 | content: "\f10c"; /*fa-circle-o*/ 4 | font-size: 1.5em; 5 | position: relative; 6 | top: .05em; 7 | } 8 | 9 | .rl-radio-selected.default-theme:before { 10 | font-family: FontAwesome; 11 | content: "\f192"; /*fa-dot-circle-o*/ 12 | font-size: 1.4em; 13 | } 14 | 15 | .rl-radio.default-theme.disabled:before, 16 | .rl-radio-selected.default-theme.disabled:before { 17 | opacity: 0.6; 18 | } 19 | -------------------------------------------------------------------------------- /source/components/inputs/radio/radio.html: -------------------------------------------------------------------------------- 1 | 6 | {{label}} 7 | 8 | -------------------------------------------------------------------------------- /source/components/inputs/radio/radio.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { downgrade } from 'typescript-angular-utilities'; 4 | 5 | import { 6 | directiveName as radioGroupDirectiveName, 7 | radioGroup, 8 | controllerName as radioGroupControllerName, 9 | RadioGroupController 10 | } from './radioGroup.ng1'; 11 | import { 12 | componentName as radioComponentName, 13 | radio, 14 | controllerName as radioControllerName, 15 | RadioController 16 | } from './radio.ng1'; 17 | 18 | export { 19 | radioGroupDirectiveName, 20 | radioGroup, 21 | radioGroupControllerName, 22 | RadioGroupController, 23 | radioComponentName, 24 | radio, 25 | radioControllerName, 26 | RadioController, 27 | }; 28 | 29 | export var moduleName: string = 'rl21.components.radio'; 30 | 31 | angular.module(moduleName, [downgrade.moduleName]) 32 | .directive(radioGroupDirectiveName, radioGroup) 33 | .controller(radioGroupControllerName, RadioGroupController) 34 | .component(radioComponentName, radio) 35 | .controller(radioControllerName, RadioController); 36 | -------------------------------------------------------------------------------- /source/components/inputs/radio/radio.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as ng from 'angular'; 2 | 3 | import { RadioGroup, RadioGroupController } from './radioGroup.ng1'; 4 | 5 | export let componentName: string = 'rlRadio'; 6 | export let controllerName: string = 'RadioController'; 7 | 8 | export class RadioController { 9 | radioGroup: RadioGroup; 10 | groupController: RadioGroupController; 11 | ngModel: ng.INgModelController; 12 | 13 | $onInit(): void { 14 | if (this.groupController != null) { 15 | this.radioGroup = this.groupController.group; 16 | } else { 17 | this.radioGroup = new RadioGroup(this.ngModel); 18 | } 19 | } 20 | } 21 | 22 | export let radio: ng.IComponentOptions = { 23 | require: { 24 | groupController: '?^^rlRadioGroup', 25 | ngModel: '?ngModel', 26 | }, 27 | transclude: true, 28 | template: ` 29 | 33 | `, 34 | controller: controllerName, 35 | controllerAs: 'radio', 36 | bindings: { 37 | value: '<', 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /source/components/inputs/radio/radio.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | import { DefaultTheme } from '../../componentsDefaultTheme'; 4 | 5 | import { RadioGroupComponent } from './radioGroup'; 6 | 7 | @Component({ 8 | selector: 'rlRadio', 9 | template: require('./radio.html'), 10 | }) 11 | export class RadioComponent { 12 | @Input() label: string; 13 | @Input() option: T; 14 | 15 | radioGroup: RadioGroupComponent; 16 | useDefaultTheme: boolean; 17 | 18 | constructor(defaultTheme: DefaultTheme 19 | , radioGroup: RadioGroupComponent) { 20 | this.radioGroup = radioGroup; 21 | this.useDefaultTheme = defaultTheme.useDefaultTheme; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /source/components/inputs/radio/radioGroup.ts: -------------------------------------------------------------------------------- 1 | import { Component, Optional } from '@angular/core'; 2 | 3 | import { services } from 'typescript-angular-utilities'; 4 | import __object = services.object; 5 | import __array = services.array; 6 | import __guid = services.guid; 7 | 8 | import { InputComponent, baseInputs, baseOutputs } from '../input'; 9 | import { FormComponent } from '../../form/form'; 10 | 11 | @Component({ 12 | selector: 'rlRadioGroup', 13 | template: '', 14 | inputs: baseInputs, 15 | outputs: baseOutputs, 16 | }) 17 | export class RadioGroupComponent extends InputComponent { 18 | constructor(@Optional() rlForm: FormComponent 19 | , object: __object.ObjectUtility 20 | , guid: __guid.GuidService) { 21 | super(rlForm, object, guid); 22 | this.inputType = 'radio'; 23 | this.initControl(); 24 | } 25 | 26 | select(value: T): void { 27 | this.setValue(value); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /source/components/inputs/signature/signature.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | Clear 8 |
9 |
10 | -------------------------------------------------------------------------------- /source/components/inputs/spinner/spinner.html: -------------------------------------------------------------------------------- 1 | 2 |
6 | 7 | 14 |
15 | {{componentValidator.error$ | async}} 16 |
17 |
18 |
19 |
20 | 21 | {{prefix}} 22 | 29 | {{postfix}} 30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /source/components/inputs/spinner/spinner.ng1.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 | {{spinner.inputValidator.error}} 7 |
8 |
9 |
10 |
11 | 12 | {{::spinner.prefix}} 13 | 14 | {{::spinner.postfix}} 15 |
16 |
17 |
-------------------------------------------------------------------------------- /source/components/inputs/textarea/textarea.html: -------------------------------------------------------------------------------- 1 |
4 | 5 | 16 |
17 | {{componentValidator.error$ | async}} 18 |
19 |
20 | -------------------------------------------------------------------------------- /source/components/inputs/textarea/textarea.ng1.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | {{input.inputValidator.error}} 5 |
-------------------------------------------------------------------------------- /source/components/inputs/textarea/textarea.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { buildInput, moduleName as inputModule } from '../input.ng1'; 4 | 5 | export const moduleName: string = 'rl.ui.components.textarea'; 6 | export const componentName: string = 'rlTextarea'; 7 | 8 | const textarea: angular.IComponentOptions = buildInput({ 9 | template: require('./textarea.ng1.html'), 10 | bindings: { 11 | rows: ' 4 | 5 | 16 |
17 | {{componentValidator.error$ | async}} 18 |
19 |
20 | -------------------------------------------------------------------------------- /source/components/inputs/textbox/textbox.md: -------------------------------------------------------------------------------- 1 | # Textbox 2 | This component extends the base [input](../input.md) with textbox-specific behavior. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `maxlength` 11 | 12 | Sets the maxlength of the textbox. 13 | 14 | `ng-model`, `validator`, `validators`, `label`, `name`. 15 | 16 | See [input](../input.md) for detail on the base options. 17 | 18 | ### Full example 19 | An input with **maxlength** and **label**. 20 | ``` 21 | 22 | ``` 23 | Output (if test.text is empty): 24 | ``` 25 | 26 | ``` 27 | Output (if test.text has a value): 28 | ``` 29 | 30 | 31 | ``` -------------------------------------------------------------------------------- /source/components/inputs/textbox/textbox.ng1.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | {{input.inputValidator.error}} 5 |
-------------------------------------------------------------------------------- /source/components/inputs/textbox/textbox.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | import * as _ from 'lodash'; 3 | 4 | import { buildInput, moduleName as inputModule } from '../input.ng1'; 5 | 6 | export const moduleName: string = 'rl.ui.components.textbox'; 7 | export const componentName: string = 'rlTextbox'; 8 | 9 | const textbox: angular.IComponentOptions = buildInput({ 10 | template: require('./textbox.ng1.html'), 11 | bindings: { 12 | maxlength: '{{$transform($item)}}
2 |
3 | 4 |
-------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/index.ts: -------------------------------------------------------------------------------- 1 | import { TypeaheadListComponent } from './typeaheadList'; 2 | import { TYPEAHEAD_LIST_TEMPLATE_DIRECTIVES } from './templates/index'; 3 | 4 | export const TYPEAHEAD_LIST_DIRECTIVES: any[] = [TypeaheadListComponent, TYPEAHEAD_LIST_TEMPLATE_DIRECTIVES]; 5 | 6 | export * from './typeaheadList'; 7 | export * from './templates/index'; 8 | -------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/templates/index.ts: -------------------------------------------------------------------------------- 1 | import { ListHeaderTemplate } from './listHeader.template'; 2 | import { ListItemTemplate } from './listItem.template'; 3 | 4 | export const TYPEAHEAD_LIST_TEMPLATE_DIRECTIVES: any[] = [ListHeaderTemplate, ListItemTemplate]; 5 | 6 | export * from './listHeader.template'; 7 | export * from './listItem.template'; 8 | -------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/templates/listHeader.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlListHeader]' }) 4 | export class ListHeaderTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/templates/listItem.template.ts: -------------------------------------------------------------------------------- 1 | import { Directive, TemplateRef } from '@angular/core'; 2 | 3 | @Directive({ selector: '[rlListItem]' }) 4 | export class ListItemTemplate { 5 | constructor(public template: TemplateRef) { } 6 | } -------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/typeaheadDataItem.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Inject, forwardRef } from '@angular/core'; 2 | import { Observable } from 'rxjs'; 3 | 4 | import { TypeaheadListComponent } from './typeaheadList'; 5 | 6 | @Component({ 7 | selector: '[rlTypeaheadDataItem]', 8 | template: '' 9 | }) 10 | export class TypeaheadDataItemComponent { 11 | @Input('rlTypeaheadDataItem') item: T; 12 | 13 | get context(): any { 14 | return { 15 | $implicit: this.item, 16 | remove: this.remove.bind(this), 17 | }; 18 | } 19 | 20 | typeaheadList: TypeaheadListComponent; 21 | 22 | constructor(@Inject(forwardRef(() => TypeaheadListComponent)) typeaheadList: TypeaheadListComponent) { 23 | this.typeaheadList = typeaheadList; 24 | } 25 | 26 | remove = (): Observable => { 27 | return this.typeaheadList.remove(this.item); 28 | } 29 | } -------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/typeaheadItem.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export let componentName: string = 'rlTypeaheadListItem'; 4 | 5 | class TypeaheadItemController { 6 | transclude: angular.ITranscludeFunction; 7 | 8 | static $inject: string[] = ['$scope', '$element', '$compile']; 9 | constructor(private $scope: angular.IScope 10 | , private $element: angular.IAugmentedJQuery 11 | , private $compile: angular.ICompileService) { } 12 | 13 | $onInit() { 14 | let itemScope = this.$scope.$parent.$new(); 15 | let contentArea: JQuery = this.$element.find('.content-target'); 16 | if (this.transclude.isSlotFilled('listItemSlot')) { 17 | this.transclude(itemScope, (template: JQuery): void => { 18 | contentArea.append(template); 19 | }, null, 'listItemSlot'); 20 | } else { 21 | let template: JQuery = contentArea.append(require('./defaultListItem.ng1.html')); 22 | this.$compile(template)(itemScope); 23 | } 24 | } 25 | } 26 | 27 | export let typeaheadItem: angular.IComponentOptions = { 28 | bindings: { 29 | transclude: '<', 30 | }, 31 | controller: TypeaheadItemController, 32 | template: `
`, 33 | }; 34 | -------------------------------------------------------------------------------- /source/components/inputs/typeaheadList/typeaheadList.ng1.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 5 |
6 |
7 | 10 |
11 |
12 |
13 |
14 |
15 |
Name
16 |
17 |
18 |
19 | 20 |
21 |
-------------------------------------------------------------------------------- /source/components/inputs/userRating/userRating.css: -------------------------------------------------------------------------------- 1 | .rating.default-theme { 2 | unicode-bidi:bidi-override; 3 | direction:rtl; 4 | font-size:1.5em; 5 | } 6 | 7 | .rating.default-theme .star { 8 | font-family:FontAwesome; 9 | font-weight:normal; 10 | font-style:normal; 11 | display:inline-block; 12 | } 13 | 14 | .rating.default-theme .star:hover { cursor: pointer; } 15 | 16 | .rating.default-theme .star:before { 17 | content:"\f006"; 18 | padding-right:5px; 19 | color:#999999; 20 | } 21 | 22 | .rating.default-theme .star.filled:before { 23 | content:"\f005"; 24 | color:#eec277; 25 | } 26 | 27 | .rating.default-theme .star:hover:before, .rating.default-theme .star:hover~.star:before { color:#ffd288; } 28 | 29 | .filled { color:#eec277; } 30 | 31 | .rating.default-theme .star.disabled { 32 | pointer-events: none; 33 | cursor: not-allowed; 34 | color: #bbbbbb; 35 | } 36 | -------------------------------------------------------------------------------- /source/components/inputs/userRating/userRating.html: -------------------------------------------------------------------------------- 1 | 4 | 9 |
10 | {{componentValidator.error$ | async}} 11 |
12 |
13 | -------------------------------------------------------------------------------- /source/components/lazyLoad/lazyLoad.md: -------------------------------------------------------------------------------- 1 | # Lazy Load 2 | Component for conditionally showing content. With this component, the content will not render until it is first shown. Afterward the initial render it will hide and show using `ng-show`. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `show` 11 | 12 | This expression determines whether the content should show or hide. -------------------------------------------------------------------------------- /source/components/lazyLoad/lazyLoad.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { IChangeObject } from '../../types/changes'; 4 | 5 | export const moduleName: string = 'rl.ui.components.lazyLoad'; 6 | export const componentName: string = 'rlLazyLoad'; 7 | export const controllerName: string = 'LazyLoadController'; 8 | 9 | export interface ILazyLoadChanges { 10 | show: IChangeObject; 11 | } 12 | 13 | export class LazyLoadController { 14 | show: boolean; 15 | init: boolean = false; 16 | 17 | $onInit(): void { 18 | this.init = this.show; 19 | } 20 | 21 | $onChanges(changes: ILazyLoadChanges): void { 22 | if (!this.init && changes.show && changes.show.currentValue) { 23 | this.init = true; 24 | } 25 | } 26 | } 27 | 28 | const lazyLoad: angular.IComponentOptions = { 29 | transclude: true, 30 | template: ` 31 |
32 |
33 |
34 |
35 |
36 | `, 37 | controller: controllerName, 38 | controllerAs: 'lazyLoad', 39 | bindings: { 40 | show: '<', 41 | }, 42 | }; 43 | 44 | angular.module(moduleName, []) 45 | .component(componentName, lazyLoad) 46 | .controller(controllerName, LazyLoadController); 47 | -------------------------------------------------------------------------------- /source/components/messageLog/messageLog.component.html: -------------------------------------------------------------------------------- 1 | 2 |
5 | 6 | 7 | 8 |
9 |
No existing messages
10 |
11 |
12 |
13 | 14 | Top 15 | Refresh 16 | 17 | 18 | Older 19 | 20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /source/components/messageLog/ng1/editedByPopover.html: -------------------------------------------------------------------------------- 1 |
Last edited by: {{entry.lastUpdatedBy.name}}
2 |
{{ entry.lastUpdatedDate | rlDate:true }}
-------------------------------------------------------------------------------- /source/components/messageLog/ng1/messageLogEditDialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 |
8 |
9 |
-------------------------------------------------------------------------------- /source/components/multiStepIndicator/multiStepIndicator.html: -------------------------------------------------------------------------------- 1 |
4 |
    5 |
  1. 11 |
    12 |

    {{step.count()}}

    13 |

    {{step.title}}

    14 |

    {{step.subtitle}}

    15 |
    16 |
  2. 17 |
18 |
-------------------------------------------------------------------------------- /source/components/multiStepIndicator/step.component.html: -------------------------------------------------------------------------------- 1 |
4 |

{{title}}

5 |
6 | -------------------------------------------------------------------------------- /source/components/multiStepIndicator/step.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ChangeDetectionStrategy, HostBinding, OnInit, OnChanges } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'rlStep', 5 | template: require('./step.component.html'), 6 | changeDetection: ChangeDetectionStrategy.OnPush, 7 | }) 8 | export class StepComponent { 9 | @Input() title: string; 10 | @Input() link: any[] | string; 11 | @Input() valid: boolean; 12 | @Input() current: boolean; 13 | @Input() useMsiStyling: boolean = false; 14 | 15 | // Default classes 16 | @HostBinding('class.rl-step') stepStyle: boolean = true; 17 | @HostBinding('class.active') activeStyle: boolean = true; 18 | 19 | // Conditional classes 20 | @HostBinding('class.error') errorStyle: boolean = false; 21 | 22 | ngOnInit() { 23 | this.checkIfValid(); 24 | } 25 | 26 | ngOnChanges() { 27 | this.checkIfValid(); 28 | } 29 | 30 | checkIfValid() { 31 | this.valid 32 | ? this.errorStyle = false 33 | : this.errorStyle = true; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /source/components/multiStepIndicator/step.tests.ts: -------------------------------------------------------------------------------- 1 | import { StepComponent } from './step.component'; 2 | 3 | describe('StepComponent', () => { 4 | let step: StepComponent; 5 | 6 | beforeEach(() => { 7 | step = new StepComponent; 8 | }); 9 | 10 | it('should set error styling on the step if it isn\'t valid', (): void => { 11 | step.valid = false; 12 | step.checkIfValid(); 13 | 14 | expect(step.errorStyle).to.be.true; 15 | }); 16 | 17 | it('should not set error styling on the step if it is valid', (): void => { 18 | step.valid = true; 19 | step.checkIfValid(); 20 | 21 | expect(step.errorStyle).to.be.false; 22 | }); 23 | 24 | }); -------------------------------------------------------------------------------- /source/components/popoutList/index.ts: -------------------------------------------------------------------------------- 1 | import { PopoutItemComponent } from './popoutItem'; 2 | import { PopoutListComponent } from './popoutList'; 3 | import { PopoutTriggerDirective } from './popoutTrigger'; 4 | import { PopoutListService } from './popoutList.service'; 5 | 6 | export const POPOUT_LIST_DIRECTIVES: any[] = [PopoutItemComponent, PopoutListComponent, PopoutTriggerDirective]; 7 | export const POPOUT_LIST_PROVIDERS: any[] = [PopoutListService]; 8 | 9 | export * from './popoutItem'; 10 | export * from './popoutList'; 11 | export * from './popoutTrigger'; 12 | export * from './popoutList.service'; 13 | -------------------------------------------------------------------------------- /source/components/popoutList/popoutItem.html: -------------------------------------------------------------------------------- 1 |
  • 6 | 7 |
  • 8 | -------------------------------------------------------------------------------- /source/components/popoutList/popoutItem.tests.ts: -------------------------------------------------------------------------------- 1 | import { PopoutItemComponent } from './popoutItem'; 2 | 3 | interface IListServiceMock { 4 | isFocused: sinon.SinonSpy; 5 | } 6 | 7 | describe('PopoutItemComponent', () => { 8 | let item: PopoutItemComponent; 9 | let listService: IListServiceMock; 10 | 11 | beforeEach(() => { 12 | listService = { isFocused: sinon.spy() }; 13 | item = new PopoutItemComponent(listService); 14 | }); 15 | 16 | it('should check the list to see if this item is focused', (): void => { 17 | listService.isFocused = sinon.spy(() => true); 18 | 19 | expect(item.focused).to.be.true; 20 | 21 | sinon.assert.calledOnce(listService.isFocused); 22 | sinon.assert.calledWith(listService.isFocused, item); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /source/components/popoutList/popoutItem.ts: -------------------------------------------------------------------------------- 1 | import { Component, Output, EventEmitter } from '@angular/core'; 2 | 3 | import { PopoutListService } from './popoutList.service'; 4 | 5 | @Component({ 6 | selector: 'rlPopoutItem', 7 | template: require('./popoutItem.html'), 8 | }) 9 | export class PopoutItemComponent { 10 | @Output() trigger: EventEmitter = new EventEmitter(); 11 | 12 | list: PopoutListService; 13 | 14 | constructor(list: PopoutListService) { 15 | this.list = list; 16 | } 17 | 18 | get focused(): boolean { 19 | return this.list.isFocused(this); 20 | } 21 | 22 | focus(): void { 23 | this.list.focus(this); 24 | } 25 | 26 | blur(): void { 27 | this.list.blur(); 28 | } 29 | 30 | select(): void { 31 | this.list.selectCurrent(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /source/components/popoutList/popoutList.html: -------------------------------------------------------------------------------- 1 |
      2 | 3 | 5 | 6 | 7 | 8 | {{getDisplayName(option)}} 9 | 10 |
    11 | -------------------------------------------------------------------------------- /source/components/ratingBar/ratingBar.css: -------------------------------------------------------------------------------- 1 | .rating-bar .default-theme.background { 2 | background-color: #fff; 3 | border: 1px solid #aaaaaa; 4 | } 5 | .rating-bar .default-theme.background.empty { 6 | border: 1px solid red; 7 | } 8 | .rating-bar .default-theme .very-high { background-color: #20D000 } 9 | .rating-bar .default-theme .high { background-color: #00a000 } 10 | .rating-bar .default-theme .medium { background-color: #007000 } 11 | .rating-bar .default-theme .low { background-color: #aa0000 } 12 | .rating-bar .default-theme .very-low { background-color: #ff0000 } 13 | -------------------------------------------------------------------------------- /source/components/ratingBar/ratingBar.html: -------------------------------------------------------------------------------- 1 |
    2 |
    6 |
    9 |
    10 |
    -------------------------------------------------------------------------------- /source/components/ratingBar/ratingBarBackgrounds.service.ts: -------------------------------------------------------------------------------- 1 | export interface IRatingBarBackgroundsService { 2 | standard: IBackgroundType; 3 | dark: IBackgroundType; 4 | transparent: IBackgroundType; 5 | getBackground(type: string): string; 6 | } 7 | 8 | export interface IBackgroundType { 9 | type: string; 10 | class: string; 11 | } 12 | 13 | export class RatingBarBackgroundService implements IRatingBarBackgroundsService { 14 | standard: IBackgroundType = { 15 | type: 'standard', 16 | class: 'background', 17 | }; 18 | dark: IBackgroundType = { 19 | type: 'dark', 20 | class: 'background-dark', 21 | }; 22 | transparent: IBackgroundType = { 23 | type: 'transparent', 24 | class: 'background-transparent', 25 | }; 26 | 27 | getBackground(type: string): string { 28 | if (type === this.dark.type) { 29 | return this.dark.class; 30 | } else if (type === this.transparent.type) { 31 | return this.transparent.class; 32 | } else { 33 | return this.standard.class; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /source/components/ratingBar/ratingBarClass.service.ts: -------------------------------------------------------------------------------- 1 | export interface IRatingBarClassService { 2 | getClass(confidence: number): string; 3 | } 4 | 5 | export class RatingBarClassService implements IRatingBarClassService { 6 | getClass(confidence: number): string { 7 | if (confidence >= 0.8) { 8 | return 'very-high'; 9 | } else if (confidence >= 0.6) { 10 | return 'high'; 11 | } else if (confidence >= 0.4) { 12 | return 'medium'; 13 | } else if (confidence >= 0.2) { 14 | return 'low'; 15 | } else { 16 | return 'very-low'; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /source/components/richTextEditor/editorButtons.css: -------------------------------------------------------------------------------- 1 | .nw-button.header:before { 2 | content: '\f1dc'; /* fa-header */ 3 | } 4 | 5 | .nw-button.paragraph:before { 6 | content: '\f1dd'; /* fa-paragraph */ 7 | } -------------------------------------------------------------------------------- /source/components/richTextEditor/headerButton.ts: -------------------------------------------------------------------------------- 1 | import * as ng from 'angular'; 2 | 3 | export var headerButtonDirectiveName: string = 'rlHeaderButton'; 4 | 5 | export interface IHeaderButtonScope extends ng.IScope { 6 | trigger(): void; 7 | execCommand(command: string, value: string): void; 8 | } 9 | 10 | export function headerButton(): ng.IDirective { 11 | 'use strict'; 12 | return { 13 | restrict: 'E', 14 | template: ` 15 | 16 | `, 17 | link(scope: IHeaderButtonScope): void { 18 | scope.trigger = (): void => { 19 | scope.execCommand('formatblock', 'h1'); 20 | }; 21 | }, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /source/components/richTextEditor/paragraphButton.ts: -------------------------------------------------------------------------------- 1 | import * as ng from 'angular'; 2 | 3 | export var paragraphButtonDirectiveName: string = 'rlParagraphButton'; 4 | 5 | export interface IParagraphButtonScope extends ng.IScope { 6 | trigger(): void; 7 | execCommand(command: string, value: string): void; 8 | } 9 | 10 | export function paragraphButton(): ng.IDirective { 11 | 'use strict'; 12 | return { 13 | restrict: 'E', 14 | template: ` 15 | 16 | `, 17 | link(scope: IParagraphButtonScope): void { 18 | scope.trigger = (): void => { 19 | scope.execCommand('formatblock', 'p'); 20 | }; 21 | }, 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /source/components/richTextEditor/richTextEditor.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/simpleCardContainer/simpleCardContainer.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /source/components/simpleCardList/index.ts: -------------------------------------------------------------------------------- 1 | import { SimpleCardListComponent } from './simpleCardList'; 2 | import { SimpleCardComponent } from './simpleCard'; 3 | 4 | export const SIMPLE_CARD_DIRECTIVES: any[] = [SimpleCardListComponent, SimpleCardComponent]; 5 | 6 | export * from './simpleCardList'; 7 | export * from './simpleCard'; 8 | -------------------------------------------------------------------------------- /source/components/simpleCardList/simpleCard.html: -------------------------------------------------------------------------------- 1 |
    2 |
    6 | 7 |
    8 |
    9 |
    10 | 11 |
    12 |
    13 | 17 |
    18 |
    -------------------------------------------------------------------------------- /source/components/simpleCardList/simpleCard.ng1.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 | 7 | 8 |
    9 |
    10 |
    11 |
    12 |
    13 | 17 |
    18 |
    19 |
    -------------------------------------------------------------------------------- /source/components/simpleCardList/simpleCardList.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { downgrade } from 'typescript-angular-utilities'; 4 | import {moduleName as parentChildModuleName } from '../../services/parentChild/parentChild.service'; 5 | import * as card from './simpleCard.ng1'; 6 | import * as list from './simpleCardList.ng1'; 7 | 8 | export { 9 | card as simpleCard, 10 | list as simpleCardList, 11 | }; 12 | 13 | export var moduleName: string = 'rl.ui.components.simpleCardList'; 14 | 15 | 16 | angular.module(moduleName, [downgrade.moduleName, parentChildModuleName]) 17 | .directive(list.directiveName, list.simpleCardList) 18 | .controller(list.controllerName, list.SimpleCardListController) 19 | .component(card.componentName, card.simpleCard) 20 | .controller(card.controllerName, card.SimpleCardController); 21 | -------------------------------------------------------------------------------- /source/components/stringWithWatermark/stringWithWatermark.html: -------------------------------------------------------------------------------- 1 | 2 | {{string}} 3 | {{watermark}} 4 | 5 | -------------------------------------------------------------------------------- /source/components/stringWithWatermark/stringWithWatermark.md: -------------------------------------------------------------------------------- 1 | # String with Watermark 2 | Component for showing a placeholder if the specified string has no value. 3 | 4 | ### Usage 5 | ``` 6 | 7 | ``` 8 | ### Options 9 | 10 | #### `string` 11 | 12 | The value that should be displayed. 13 | 14 | #### `watermark` 15 | 16 | The placeholder that should be shown in place of the string if none is present. 17 | 18 | ### Full example 19 | 20 | A string with a value: 21 | ``` 22 | 23 | ``` 24 | Output: 25 | ``` 26 | Something here 27 | ``` 28 | An empty string: 29 | ``` 30 | 31 | ``` 32 | Output: 33 | ``` 34 | Placeholder 35 | ``` -------------------------------------------------------------------------------- /source/components/stringWithWatermark/stringWithWatermark.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export const moduleName: string = 'rl.ui.components.stringWithWatermark'; 4 | export const componentName: string = 'rlStringWithWatermark'; 5 | 6 | export interface IStringWithWatermarkBindings { 7 | string: string; 8 | watermark: string; 9 | } 10 | 11 | const stringWithWatermark: angular.IComponentOptions = { 12 | template: ` 13 | 14 | 15 | 16 | 17 | `, 18 | controllerAs: 'controller', 19 | bindings: { 20 | string: '@', 21 | watermark: '@', 22 | }, 23 | }; 24 | 25 | angular.module(moduleName, []) 26 | .component(componentName, stringWithWatermark); 27 | -------------------------------------------------------------------------------- /source/components/stringWithWatermark/stringWithWatermark.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'rlStringWithWatermark', 5 | template: require('./stringWithWatermark.html'), 6 | }) 7 | export class StringWithWatermarkComponent { 8 | @Input() string: string; 9 | @Input() watermark: string; 10 | } 11 | -------------------------------------------------------------------------------- /source/components/tabs/ng1/tab.css: -------------------------------------------------------------------------------- 1 | .rl-tab-content .rl-tab-pane { display: none } 2 | .rl-tab-content .rl-tab-pane.active { display: block } 3 | 4 | .rl-tabset li.error > a::before { 5 | font-family: "FontAwesome"; 6 | content: '\f071'; 7 | color: #d50000; 8 | } -------------------------------------------------------------------------------- /source/components/tabs/ng1/tab.ng1.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 | 10 |
    -------------------------------------------------------------------------------- /source/components/tabs/ng1/tabs.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { 4 | componentName as tabComponentName, 5 | tab, 6 | controllerName as tabControllerName, 7 | TabController, 8 | } from './tab.ng1'; 9 | import { 10 | componentName as tabsetComponentName, 11 | tabset, 12 | controllerName as tabsetControllerName, 13 | TabsetController, 14 | ITabHeader, 15 | } from './tabset.ng1'; 16 | 17 | 18 | export { 19 | tabComponentName, 20 | tab, 21 | tabControllerName, 22 | TabController, 23 | tabsetComponentName, 24 | tabset, 25 | tabsetControllerName, 26 | TabsetController, 27 | ITabHeader, 28 | } 29 | 30 | export let moduleName: string = 'rl.ui.components.tabs'; 31 | 32 | angular.module(moduleName, []) 33 | .component(tabComponentName, tab) 34 | .controller(tabControllerName, TabController) 35 | .component(tabsetComponentName, tabset) 36 | .controller(tabsetControllerName, TabsetController); 37 | -------------------------------------------------------------------------------- /source/components/tabs/ng1/tabset.ng1.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    6 |
    8 | 9 |
    10 |
    11 |
    12 |
    13 |
    14 |
    15 |
    -------------------------------------------------------------------------------- /source/components/tabs/ng2/index.ts: -------------------------------------------------------------------------------- 1 | import { TabsetComponent } from './tabset'; 2 | import { TabComponent } from './tab/tab'; 3 | import { TabHeaderComponent } from './tab/tabHeader/index'; 4 | import { TabContentComponent } from './tab/tabContent/index'; 5 | import { TabFooterComponent } from './tab/tabFooter/index'; 6 | 7 | 8 | export const TABS_COMPONENT: any[] = [ 9 | TabComponent, 10 | TabHeaderComponent, 11 | TabContentComponent, 12 | TabFooterComponent, 13 | TabsetComponent, 14 | ]; 15 | 16 | export * from './tab/tab'; 17 | export * from './tabset'; 18 | export * from './tab/tabHeader/index'; 19 | export * from './tab/tabContent/index'; 20 | export * from './tab/tabFooter/index'; -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tab.css: -------------------------------------------------------------------------------- 1 | .rl-tab-content .rl-tab-pane { display: none } 2 | .rl-tab-content .rl-tab-pane.active { display: block } 3 | 4 | .rl-tabset li.error > a::before { 5 | font-family: "FontAwesome"; 6 | content: '\f071'; 7 | color: #d50000; 8 | } -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tab.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 |
    5 |
    6 | 10 |
    -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tab.ts: -------------------------------------------------------------------------------- 1 | import { Component, ContentChild } from '@angular/core'; 2 | 3 | import { TabHeaderComponent } from './tabHeader/index'; 4 | import { TabContentComponent } from './tabContent/index'; 5 | import { TabFooterComponent } from './tabFooter/index'; 6 | 7 | import { TabsetComponent } from '../tabset'; 8 | import { FormComponent } from '../../../form/form'; 9 | 10 | @Component({ 11 | selector: 'rlTab', 12 | template: require('./tab.html'), 13 | }) 14 | export class TabComponent { 15 | @ContentChild(TabHeaderComponent) 16 | header: TabHeaderComponent; 17 | 18 | @ContentChild(FormComponent) 19 | childForm: FormComponent; 20 | 21 | isActive: boolean; 22 | 23 | constructor() { 24 | } 25 | 26 | get isValid(): boolean{ 27 | let hasChildForm: boolean = this.childForm != null; 28 | if (hasChildForm) { 29 | return this.childForm.form.valid; 30 | } 31 | return true; 32 | } 33 | } -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabContent/index.ts: -------------------------------------------------------------------------------- 1 | export { TabContentComponent } from './tabContent.component'; -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabContent/tabContent.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabContent/tabContent.component.tests.ts: -------------------------------------------------------------------------------- 1 | import { TabContentComponent } from './tabContent.component'; 2 | 3 | describe('a tabContent component', () => { 4 | let tabContentComponent : TabContentComponent; 5 | 6 | // register all needed dependencies 7 | beforeEach(() => { 8 | tabContentComponent = new TabContentComponent(); 9 | }); 10 | 11 | it('should have an instance', () => { 12 | expect(tabContentComponent).to.not.be.null; 13 | }); 14 | }); -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabContent/tabContent.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'rlTabContent', 5 | template: require('./tabContent.component.html') 6 | }) 7 | 8 | export class TabContentComponent { 9 | constructor() { } 10 | } -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabFooter/index.ts: -------------------------------------------------------------------------------- 1 | export { TabFooterComponent } from './tabFooter.component'; -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabFooter/tabFooter.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabFooter/tabFooter.component.tests.ts: -------------------------------------------------------------------------------- 1 | import { TabFooterComponent } from './tabFooter.component'; 2 | 3 | describe('a tabFooter component', () => { 4 | let tabFooterComponent : TabFooterComponent; 5 | 6 | // register all needed dependencies 7 | beforeEach(() => { 8 | tabFooterComponent = new TabFooterComponent(); 9 | }); 10 | 11 | it('should have an instance', () => { 12 | expect(tabFooterComponent).to.not.be.null; 13 | }); 14 | }); -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabFooter/tabFooter.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'rlTabFooter', 5 | template: require('./tabFooter.component.html') 6 | }) 7 | 8 | export class TabFooterComponent { 9 | 10 | constructor() { } 11 | } -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabHeader/index.ts: -------------------------------------------------------------------------------- 1 | export { TabHeaderComponent } from './tabHeader.component'; -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabHeader/tabHeader.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabHeader/tabHeader.component.tests.ts: -------------------------------------------------------------------------------- 1 | import { TabHeaderComponent } from './tabHeader.component'; 2 | 3 | describe('a tabHeader component', () => { 4 | let tabHeaderComponent : TabHeaderComponent; 5 | 6 | // register all needed dependencies 7 | beforeEach(() => { 8 | tabHeaderComponent = new TabHeaderComponent({}); 9 | }); 10 | 11 | it('should have an instance', () => { 12 | expect(tabHeaderComponent).to.not.be.null; 13 | }); 14 | 15 | it('should get the inner HTML', () => { 16 | const innerHtmlTest = "askljeudSHUTUPBRENTdggfhlawkjegbfl;akjosbd"; 17 | 18 | tabHeaderComponent = new TabHeaderComponent({ 19 | nativeElement: { 20 | innerHTML: innerHtmlTest 21 | } 22 | }); 23 | 24 | expect(tabHeaderComponent.innerHTML).to.equal(innerHtmlTest); 25 | }); 26 | }); -------------------------------------------------------------------------------- /source/components/tabs/ng2/tab/tabHeader/tabHeader.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ElementRef } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'rlTabHeader', 5 | template: require('./tabHeader.component.html') 6 | }) 7 | 8 | export class TabHeaderComponent { 9 | 10 | constructor(private el: ElementRef) { 11 | } 12 | 13 | get innerHTML(): string { 14 | return this.el.nativeElement.innerHTML; 15 | } 16 | } -------------------------------------------------------------------------------- /source/components/tabs/ng2/tabset.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    6 |
    8 | 9 |
    10 |
    11 |
    12 |
    13 | 14 |
    15 |
    -------------------------------------------------------------------------------- /source/components/tabs/ng2/tabset.ts: -------------------------------------------------------------------------------- 1 | import { Component, ContentChildren, AfterContentInit, QueryList } from '@angular/core'; 2 | 3 | import { TabComponent } from './tab/tab'; 4 | 5 | @Component({ 6 | selector: 'rlTabset', 7 | template: require('./tabset.html'), 8 | }) 9 | export class TabsetComponent implements AfterContentInit { 10 | 11 | constructor() { 12 | } 13 | @ContentChildren(TabComponent) tabs: QueryList; 14 | 15 | select(tab: TabComponent): void { 16 | this.tabs.forEach(thisTab => { 17 | thisTab.isActive = false; 18 | }); 19 | 20 | tab.isActive = true; 21 | } 22 | 23 | ngAfterContentInit() { 24 | if (this.tabs) { 25 | this.select(this.tabs.first); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /source/components/validationGroup/validationGroup.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {{groupValidator.error$ | async}} 4 |
    5 | 6 |
    7 | -------------------------------------------------------------------------------- /source/components/validationGroup/validationGroup.md: -------------------------------------------------------------------------------- 1 | # Validation group 2 | A component for applying validation to a group of elements, such as a list that must have at least one entry. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `validator (alias: validators)` 11 | 12 | A handler for applying custom validation logic to the content group. Validators can be provided as a single or as an array of validators. 13 | Model: 14 | ``` 15 | { 16 | validate(): boolean; 17 | errorMessage: string | { (): string }; 18 | isActive?: boolean | { (): boolean }; 19 | } 20 | ``` 21 | Examples: 22 | ``` 23 | validator="myValidator" 24 | validators="[myValidator1, myValidator2]" 25 | ``` 26 | 27 | ### Full example 28 | 29 | ``` 30 | ... 31 | ``` 32 | Output (with validation errors): 33 | ``` 34 |
    35 |
    36 | 37 |
    38 | ... 39 |
    40 | ``` 41 | Output (with no errors): 42 | ``` 43 |
    44 | ... 45 |
    46 | ``` -------------------------------------------------------------------------------- /source/components/validationGroup/validationGroup.ng1.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {{group.groupValidator.error}} 4 |
    5 |
    6 |
    -------------------------------------------------------------------------------- /source/pipes/date/date.pipe.md: -------------------------------------------------------------------------------- 1 | # Date filter 2 | A filter for formatting [`moment`](http:\\www.momentjs.com) objects for display. 3 | 4 | ### Usage 5 | ``` 6 | {{myDate | rlDate:includeTime?}} 7 | ``` 8 | ### Options 9 | 10 | #### `includeTime (default: false)` 11 | 12 | If true, date will be formatted as 'MM/DD/YYYY h:mm A z'. 13 | 14 | Default format is 'MM/DD/YYYY'. 15 | 16 | ### Full Example 17 | Example date with and without time included. 18 | ``` 19 | // myDate = moment('2016-01-02T12:00:00-05:00'); 20 | {{myDate | rlDate}} 21 | {{myDate | rlDate:true}} 22 | ``` 23 | Output: 24 | ``` 25 | 01/02/2016 26 | 01/02/2016 12:00 PM EST 27 | ``` -------------------------------------------------------------------------------- /source/pipes/date/date.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | import * as moment from 'moment'; 3 | 4 | import { services } from 'typescript-angular-utilities'; 5 | import __dateFormats = services.date.defaultFormats; 6 | import __object = services.object; 7 | 8 | @Pipe({ name: 'rlDate' }) 9 | export class DatePipe implements PipeTransform { 10 | private object: __object.IObjectUtility; 11 | 12 | constructor(object: __object.ObjectUtility) { 13 | this.object = object; 14 | } 15 | 16 | transform(date?: moment.Moment, includeTime?: boolean): string { 17 | if (this.object.isNullOrEmpty(date)) { 18 | return ''; 19 | } 20 | 21 | const momentDate: moment.Moment = moment(date); 22 | if (includeTime) { 23 | return momentDate.format(__dateFormats.dateTimeFormat) + ' ' + momentDate.zoneAbbr(); 24 | } else { 25 | return momentDate.format(__dateFormats.dateFormat); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /source/pipes/index.ts: -------------------------------------------------------------------------------- 1 | import { DatePipe } from './date/date.pipe'; 2 | import { IsEmptyPipe } from './isEmpty/isEmpty.pipe'; 3 | import { LocalizeStringDatesPipe } from './localizeStringDates/localizeStringDates.pipe'; 4 | import { TruncatePipe } from './truncate/truncate.pipe'; 5 | 6 | export { DatePipe, IsEmptyPipe, LocalizeStringDatesPipe, TruncatePipe }; 7 | -------------------------------------------------------------------------------- /source/pipes/isEmpty/isEmpty.md: -------------------------------------------------------------------------------- 1 | ## isEmpty 2 | Tests the provided value to see if it is null or empty using the [object](https://github.com/RenovoSolutions/TypeScript-Angular-Utilities/blob/master/README.md#object) utility to call isNullOrEmpty on the value. Returns true if the item is empty. If you specify `isEmpty:false`, returns true for non-empty values. 3 | 4 | ``` 5 | 6 | My array has values! 7 | 8 | 9 | My array is empty! 10 | 11 | ``` 12 | -------------------------------------------------------------------------------- /source/pipes/isEmpty/isEmpty.pipe.tests.ts: -------------------------------------------------------------------------------- 1 | import { services } from 'typescript-angular-utilities'; 2 | import __object = services.object; 3 | 4 | import { IsEmptyPipe } from './isEmpty.pipe'; 5 | 6 | describe('isEmpty', () => { 7 | let isEmpty: IsEmptyPipe; 8 | 9 | beforeEach(() => { 10 | isEmpty = new IsEmptyPipe(__object.objectUtility); 11 | }); 12 | 13 | it('should return true if the array is null or empty', (): void => { 14 | expect(isEmpty.transform(null)).to.be.true; 15 | expect(isEmpty.transform([])).to.be.true; 16 | }); 17 | 18 | it('should return false if the array has items', (): void => { 19 | expect(isEmpty.transform([1, 2, 3])).to.be.false; 20 | expect(isEmpty.transform(['1', '2', '3'])).to.be.false; 21 | }); 22 | 23 | it('should invert the result if trueIfEmpty is specified as false', (): void => { 24 | expect(isEmpty.transform(null, false)).to.be.false; 25 | expect(isEmpty.transform([1, 2, 3], false)).to.be.true; 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /source/pipes/isEmpty/isEmpty.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from '@angular/core'; 2 | 3 | import { services } from 'typescript-angular-utilities'; 4 | import __object = services.object; 5 | 6 | @Pipe({ name: 'isEmpty' }) 7 | export class IsEmptyPipe implements PipeTransform { 8 | private objectUtility: __object.IObjectUtility; 9 | 10 | constructor(objectUtility: __object.ObjectUtility) { 11 | this.objectUtility = objectUtility; 12 | } 13 | transform(input: any, trueWhenEmpty?: boolean): boolean { 14 | var isEmpty: boolean = this.objectUtility.isNullOrEmpty(input); 15 | 16 | if (trueWhenEmpty === false) { 17 | return !isEmpty; 18 | } 19 | return isEmpty; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /source/pipes/truncate/truncate.md: -------------------------------------------------------------------------------- 1 | ## truncate 2 | Converts the input value to a string using `.toString()` and then limits the length of the string to the truncate length. Can optionally add an ellipses to the end (...). 3 | 4 | ``` 5 | // with: 6 | scope.myString = 'some long string that needs to be truncated'; 7 | 8 | {{myString | truncate:10:true}} 9 | 10 | // displays: 11 | // 'some long ...' 12 | ``` 13 | -------------------------------------------------------------------------------- /source/pipes/truncate/truncate.pipe.ts: -------------------------------------------------------------------------------- 1 | // Formats and optionally truncates and ellipsimogrifies a string for display in a card header 2 | 3 | import { Pipe, PipeTransform } from '@angular/core'; 4 | 5 | import { services } from 'typescript-angular-utilities'; 6 | import __object = services.object; 7 | 8 | @Pipe({ name: 'truncate' }) 9 | export class TruncatePipe implements PipeTransform { 10 | private objectUtility: __object.IObjectUtility; 11 | 12 | constructor(objectUtility: __object.ObjectUtility) { 13 | this.objectUtility = objectUtility; 14 | } 15 | 16 | transform(input?: string | number, truncateTo?: number, includeEllipses?: boolean): string { 17 | includeEllipses = includeEllipses == null ? false : includeEllipses; 18 | 19 | var out: string = this.objectUtility.isNullOrWhitespace(input) ? '' : input.toString(); 20 | if (out.length) { 21 | if (truncateTo != null && out.length > truncateTo) { 22 | out = out.substring(0, truncateTo); 23 | if (includeEllipses) { 24 | out += '...'; 25 | } 26 | } 27 | } 28 | return out; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /source/services/async/async.service.ts: -------------------------------------------------------------------------------- 1 | import { isBoolean } from 'lodash'; 2 | import { Observable, BehaviorSubject } from 'rxjs'; 3 | 4 | export type IWaitValue = Observable | Promise | boolean; 5 | 6 | export class AsyncHelper { 7 | waitAsObservable(waitOn: IWaitValue): Observable { 8 | if (waitOn == null || isBoolean(waitOn)) { 9 | return new BehaviorSubject(waitOn); 10 | } 11 | 12 | return Observable.from(waitOn); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /source/services/autosave/triggers/trigger.tests.ts: -------------------------------------------------------------------------------- 1 | import { Trigger, ITrigger } from './trigger'; 2 | 3 | describe('autosave trigger', () => { 4 | let trigger: ITrigger; 5 | 6 | beforeEach(() => { 7 | // aliases test and trigger 8 | trigger = new Trigger('test trigger', sinon.spy()); 9 | }); 10 | 11 | it('should be true if any alias of the trigger is specified', (): void => { 12 | expect(trigger.hasMatch('test a simple autosave')).to.be.true; 13 | }); 14 | 15 | it('should be false if no match is found', (): void => { 16 | expect(trigger.hasMatch('some random strings all together')).to.be.false; 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /source/services/autosave/triggers/trigger.ts: -------------------------------------------------------------------------------- 1 | import * as _ from 'lodash'; 2 | 3 | export interface ITrigger { 4 | setTrigger(autosave: { (): void }): void; 5 | hasMatch(triggers: string): boolean; 6 | configure(settings: TSettings): void; 7 | aliases: string[]; 8 | } 9 | 10 | export class Trigger implements ITrigger { 11 | protected settings: TSettings; 12 | aliases: string[]; 13 | 14 | constructor(aliases: string, private triggerAction?: {(settings: TSettings): void}) { 15 | this.aliases = aliases.split(' '); 16 | } 17 | 18 | setTrigger(autosave: { (): void }): void { 19 | if (_.isFunction(this.triggerAction)) { 20 | this.triggerAction(this.settings); 21 | } 22 | } 23 | 24 | hasMatch(triggers: string): boolean { 25 | let triggerList: string[] = triggers.split(' '); 26 | return _.some(triggerList, (trigger: string): boolean => { 27 | return _.some(this.aliases, (alias: string): boolean => { 28 | return trigger === alias; 29 | }); 30 | }); 31 | } 32 | 33 | configure(settings: TSettings): void { 34 | this.settings = settings; 35 | } 36 | } -------------------------------------------------------------------------------- /source/services/autosave/triggers/triggers.md: -------------------------------------------------------------------------------- 1 | # Autosave Triggers 2 | Configures how the save is triggered on an autosave form. Multiple triggers may be specified in a space seperated list. 3 | 4 | ### Usage 5 | ``` 6 | ... 7 | ``` 8 | ### Options 9 | 10 | #### `none` 11 | 12 | Disables automatic autosaving. Saves can still be triggered programatically. 13 | 14 | Example: `triggers="none"` 15 | 16 | #### `onChange(default)` 17 | 18 | Triggers autosave when the form becomes dirty. This is debounced as the user enters additional keystrokes. 19 | 20 | **debounce-duration** may be configured on the [rl-autosave](../../behaviors/autosave/autosave.md) behavior. 21 | 22 | Example: `triggers="onChange"`, `triggers="onChange other"` -------------------------------------------------------------------------------- /source/services/breakpoints/breakpoint.ts: -------------------------------------------------------------------------------- 1 | export var lg: string = 'lg'; 2 | export var md: string = 'md'; 3 | export var sm: string = 'sm'; 4 | export var xs: string = 'xs'; 5 | 6 | export var all: string[] = [xs, sm, md, lg]; 7 | -------------------------------------------------------------------------------- /source/services/breakpoints/breakpoints.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { visibleBreakpointServiceName, VisibleBreakpointService } from './visibleBreakpoint.service'; 4 | import { breakpointServiceName, BreakpointService } from './breakpoints.service.ng1'; 5 | 6 | export * from './breakpoint'; 7 | export * from './visibleBreakpoint.service'; 8 | export * from './breakpoints.service.ng1'; 9 | 10 | export var moduleName: string = 'rl.ui.services.breakpoints'; 11 | 12 | angular.module(moduleName, []) 13 | .constant('resizeDebounceMilliseconds', 500) 14 | .service(breakpointServiceName, BreakpointService); 15 | -------------------------------------------------------------------------------- /source/services/breakpoints/index.ts: -------------------------------------------------------------------------------- 1 | import { BreakpointService } from './breakpoints.service'; 2 | import { VisibleBreakpointService } from './visibleBreakpoint.service'; 3 | 4 | export const BREAKPOINT_PROVIDERS: any[] = [ 5 | BreakpointService, 6 | VisibleBreakpointService 7 | ]; 8 | 9 | export * from './breakpoint'; 10 | export * from './breakpoints.service'; 11 | export * from './visibleBreakpoint.service'; -------------------------------------------------------------------------------- /source/services/breakpoints/visibleBreakpoint.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { JQueryProvider } from '../jquery/jquery.provider'; 3 | 4 | /* 5 | * Implementation also requires the following elements to be inserted on the page: 6 | *
    7 | *
    8 | *
    9 | *
    10 | * They have been inserted into index.html for your convenience. 11 | */ 12 | 13 | export var visibleBreakpointServiceName: string = 'visibleBreakpoint'; 14 | 15 | export interface IVisibleBreakpointService { 16 | isVisible(breakpoint: string): boolean; 17 | } 18 | 19 | @Injectable() 20 | export class VisibleBreakpointService implements IVisibleBreakpointService { 21 | jquery: JQueryStatic; 22 | 23 | constructor(jquery: JQueryProvider) { 24 | this.jquery = jquery; 25 | } 26 | 27 | isVisible(breakpoint: string): boolean { 28 | return this.jquery(`.device-${breakpoint}`).is(':visible'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /source/services/dialog/bootstrapModalDialog/bootstrapModalDialog.controller.ts: -------------------------------------------------------------------------------- 1 | import * as ng from 'angular'; 2 | 3 | import { serviceName, BootstrapModalDialogService } from './bootstrapModalDialog.service'; 4 | 5 | export var controllerName: string = 'BootstrapModalDialogController'; 6 | 7 | export interface IBootstrapModalDialogScope extends ng.IScope { 8 | modalController: string | Function | (string | Function)[]; 9 | resolveData: any; 10 | } 11 | 12 | export class BootstrapModalDialogController { 13 | static $inject: string[] = ['$scope', '$controller', serviceName]; 14 | constructor($scope: IBootstrapModalDialogScope 15 | , $controller: ng.IControllerService 16 | , baseDialog: BootstrapModalDialogService) { 17 | let controller: any; 18 | 19 | if ($scope.modalController != null) { 20 | let locals: any = $scope.resolveData || {}; 21 | $scope.resolveData = null; 22 | locals.$scope = $scope; 23 | 24 | controller = $controller($scope.modalController, locals); 25 | } 26 | 27 | $scope.$on('modal.closing', baseDialog.modalClosing); 28 | 29 | return controller; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /source/services/dialog/bootstrapModalDialog/bootstrapModalDialog.module.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import { downgrade } from 'typescript-angular-utilities'; 4 | 5 | import { controllerName, BootstrapModalDialogController } from './bootstrapModalDialog.controller'; 6 | import { serviceName, BootstrapModalDialogService } from './bootstrapModalDialog.service'; 7 | 8 | export * from './bootstrapModalDialog.controller'; 9 | export * from './bootstrapModalDialog.service'; 10 | 11 | export var moduleName: string = 'rl.ui.services.dialog.bootstrapModalDialog'; 12 | 13 | angular.module(moduleName, [downgrade.moduleName]) 14 | .controller(controllerName, BootstrapModalDialogController) 15 | .service(serviceName, BootstrapModalDialogService); 16 | -------------------------------------------------------------------------------- /source/services/dialog/promptDialog.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /source/services/document/document.provider.ts: -------------------------------------------------------------------------------- 1 | import { ValueProvider } from '@angular/core'; 2 | 3 | export abstract class DocumentWrapper { } 4 | 5 | export const DOCUMENT_PROVIDER: ValueProvider = { 6 | provide: DocumentWrapper, 7 | useValue: document, 8 | }; 9 | -------------------------------------------------------------------------------- /source/services/documentWrapper/documentWrapper.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import * as $ from 'jquery'; 3 | 4 | export interface IDocumentService { 5 | height(): number; 6 | } 7 | 8 | @Injectable() 9 | export class DocumentService { 10 | private documentControl: JQuery; 11 | 12 | constructor() { 13 | this.documentControl = $(document); 14 | } 15 | 16 | height(): number { 17 | return this.documentControl.height(); 18 | } 19 | } -------------------------------------------------------------------------------- /source/services/form/form.service.ng1.tests.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | import 'angular-mocks'; 3 | 4 | import { services as utilityServices } from 'typescript-angular-utilities'; 5 | import __test = utilityServices.test; 6 | 7 | import { moduleName, serviceName, IFormService } from './form.service.ng1'; 8 | 9 | describe('form service', (): void => { 10 | let formService: IFormService; 11 | 12 | beforeEach(() => { 13 | angular.mock.module(moduleName); 14 | 15 | let services: any = __test.angularFixture.inject(serviceName); 16 | formService = services[serviceName]; 17 | }); 18 | 19 | it('should get the first error message from a child of the form', (): void => { 20 | let form: any = { 21 | prop1: {}, 22 | prop2: {}, 23 | ngModel1: { rlErrorMessage: 'error1' }, 24 | ngModel2: { rlErrorMessage: 'error2' }, 25 | }; 26 | expect(formService.getAggregateError(form)).to.equal('error1'); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /source/services/form/form.service.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | import * as _ from 'lodash'; 3 | 4 | import { IFormValidator } from '../../types/formValidators'; 5 | 6 | export let moduleName: string = 'rl.ui.services.form'; 7 | export let serviceName: string = 'formService'; 8 | 9 | export interface IFormService { 10 | getAggregateError(form: IFormValidator): string; 11 | } 12 | 13 | class FormService implements IFormService { 14 | getAggregateError(form: IFormValidator): string { 15 | let filteredForm: any = _.filter(form, (prop: any): boolean => { 16 | return prop != null && prop.rlErrorMessage != null; 17 | }); 18 | let errors: string[] = _.mapValues(filteredForm, 'rlErrorMessage'); 19 | return _.first(errors); 20 | } 21 | } 22 | 23 | angular.module(moduleName, []) 24 | .service(serviceName, FormService); -------------------------------------------------------------------------------- /source/services/form/form.service.ts: -------------------------------------------------------------------------------- 1 | import { FormGroup, FormControl } from '@angular/forms'; 2 | import { filter, first, map } from 'lodash'; 3 | 4 | import { IControlValidator} from '../../types/formValidators'; 5 | 6 | export class FormService { 7 | getAggregateError(form: FormGroup): string { 8 | const filteredForm: any = filter(form.controls, (control: IControlValidator): boolean => { 9 | return control != null && !control.valid; 10 | }); 11 | 12 | const errors: string[] = map(filteredForm, 'rlErrorMessage'); 13 | 14 | const filteredErrors = filter(errors, (error: string): boolean => error ? true : false ) 15 | 16 | if (filteredErrors.length > 0) { 17 | return first(filteredErrors); 18 | }else { 19 | return first(map(form.controls, nestedForm => this.getAggregateError(nestedForm))); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /source/services/jquery/jquery.provider.ts: -------------------------------------------------------------------------------- 1 | import { ValueProvider } from '@angular/core'; 2 | import * as $ from 'jquery'; 3 | 4 | export abstract class JQueryProvider {} 5 | 6 | export const JQUERY_PROVIDER: ValueProvider = { 7 | provide: JQueryProvider, 8 | useValue: $, 9 | }; 10 | -------------------------------------------------------------------------------- /source/services/jquery/jquery.service.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | export * from './jquery.provider'; 4 | 5 | export var moduleName: string = 'rl.utilities.services.jquery'; 6 | export var serviceName: string = 'jqueryUtility'; 7 | 8 | export interface IJQueryUtility { 9 | getHtml(jquery: JQuery): string; 10 | replaceContent(contentArea: JQuery, newContents: JQuery): JQuery; 11 | } 12 | 13 | class JQueryUtility implements IJQueryUtility { 14 | getHtml(jquery: JQuery): string { 15 | return angular.element('
    ').append(jquery).html() 16 | } 17 | 18 | replaceContent(contentArea: JQuery, newContent: JQuery): JQuery { 19 | contentArea.empty(); 20 | return contentArea.append(newContent); 21 | } 22 | } 23 | 24 | angular.module(moduleName, []) 25 | .service(serviceName, JQueryUtility); 26 | -------------------------------------------------------------------------------- /source/services/windowWrapper/windowWrapper.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import * as $ from 'jquery'; 3 | 4 | export interface IWindowService { 5 | resize(callback: { (event: JQueryEventObject): any }): void; 6 | scrollTop(): number; 7 | scroll(handler: IScrollHandler): void; 8 | height(): number; 9 | } 10 | 11 | export interface IScrollHandler { 12 | (event: JQueryEventObject): any; 13 | } 14 | 15 | @Injectable() 16 | export class WindowService { 17 | private windowControl: JQuery; 18 | 19 | constructor() { 20 | this.windowControl = $(window); 21 | } 22 | 23 | resize(callback: { (event: JQueryEventObject): any }): void { 24 | this.windowControl.resize(callback); 25 | } 26 | 27 | scrollTop(): number { 28 | return this.windowControl.scrollTop(); 29 | } 30 | 31 | scroll(handler: IScrollHandler): void { 32 | this.windowControl.scroll(handler); 33 | } 34 | 35 | height(): number { 36 | return this.windowControl.height(); 37 | } 38 | } -------------------------------------------------------------------------------- /source/types/changes.ts: -------------------------------------------------------------------------------- 1 | export interface IChangeObject { 2 | currentValue: TDataType; 3 | previousValue: TDataType; 4 | } 5 | -------------------------------------------------------------------------------- /source/types/formValidators.ts: -------------------------------------------------------------------------------- 1 | import { FormControl, FormGroup } from '@angular/forms'; 2 | import * as angular from 'angular'; 3 | 4 | export interface IControlValidator extends FormControl { 5 | rlErrorMessage?: string; 6 | } 7 | 8 | export interface IFormValidator extends angular.IFormController { 9 | rlErrorMessage?: string; 10 | } 11 | 12 | export interface INgModelValidator extends angular.INgModelController { 13 | rlErrorMessage?: string; 14 | } 15 | -------------------------------------------------------------------------------- /source/types/types.module.ts: -------------------------------------------------------------------------------- 1 | import * as changes from './changes'; 2 | import * as ngModel from './formValidators'; 3 | import * as viewData from './viewData'; 4 | 5 | export { ngModel, viewData }; 6 | -------------------------------------------------------------------------------- /source/types/viewData.ts: -------------------------------------------------------------------------------- 1 | export interface IViewDataEntity { 2 | viewData: TViewDataType; 3 | } 4 | -------------------------------------------------------------------------------- /source/ui.module.ng1.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | 3 | import 'angular-ui-bootstrap'; 4 | import 'angular-sanitize'; 5 | import 'angular-animate'; 6 | 7 | import { downgrade as utilitiesDowngrade } from 'typescript-angular-utilities'; 8 | import * as componentsDowngrade from './componentsDowngrade'; 9 | 10 | import '../libraries/angular-bootstrap-slider/slider'; 11 | 12 | import * as behaviors from './behaviors/behaviors.module'; 13 | import * as components from './components/components.module'; 14 | import * as downgrade from './componentsDowngrade'; 15 | import * as pipes from './pipes/index'; 16 | import * as services from './services/services.module'; 17 | import * as types from './types/types.module'; 18 | 19 | export { behaviors, components, downgrade, pipes, services, types }; 20 | 21 | export var moduleName: string = 'rl.ui'; 22 | 23 | angular.module(moduleName, [ 24 | 'ui.bootstrap', 25 | 'ui.bootstrap-slider', 26 | 'ngSanitize', 27 | utilitiesDowngrade.moduleName, 28 | componentsDowngrade.moduleName, 29 | 30 | behaviors.moduleName, 31 | components.moduleName, 32 | downgrade.moduleName, 33 | services.moduleName, 34 | ]); 35 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "declaration": true, 6 | "inlineSourceMap": true, 7 | "emitDecoratorMetadata": true, 8 | "experimentalDecorators": true, 9 | "target": "ES5", 10 | "typeRoots": [ 11 | "./node_modules/@types" 12 | ] 13 | }, 14 | "exclude": [ 15 | "node_modules", 16 | "bower_components", 17 | "libraries", 18 | ".vscode", 19 | "output" 20 | ] 21 | } -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "indent": [ 4 | true, 5 | "tabs" 6 | ], 7 | "quotemark": [ 8 | true, 9 | "single" 10 | ], 11 | "semicolon": [ 12 | true, 13 | "always" 14 | ], 15 | "trailing-comma": [ 16 | true, 17 | { 18 | "multiline": "always", 19 | "singleline": "never" 20 | } 21 | ], 22 | "triple-equals": [ 23 | true, 24 | "allow-null-check" 25 | ], 26 | "typedef": [ 27 | true, 28 | "call-signature", 29 | "parameter", 30 | "arrow-parameter", 31 | "property-declaration", 32 | "variable-declaration", 33 | "member-variable-declaration" 34 | ], 35 | "use-strict": [ 36 | true, 37 | "check-module", 38 | "check-function" 39 | ], 40 | "variable-name": [ 41 | true, 42 | "check-format", 43 | "allow-leading-underscore", 44 | "ban-keywords" 45 | ], 46 | "whitespace": [ 47 | true, 48 | "check-branch", 49 | "check-decl", 50 | "check-operator", 51 | "check-separator", 52 | "check-type" 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /typings/angularExtensions.d.ts: -------------------------------------------------------------------------------- 1 | import * as ng from 'angular'; 2 | 3 | declare module 'angular' { 4 | interface ITranscludeFunction { 5 | // If the scope is provided, then the cloneAttachFn must be as well. 6 | (scope: ng.IScope, cloneAttachFn: ng.ICloneAttachFunction, futureParent?: ng.IAugmentedJQuery, slotName?: string): ng.IAugmentedJQuery; 7 | // If one argument is provided, then it's assumed to be the cloneAttachFn. 8 | (cloneAttachFn?: ng.ICloneAttachFunction, futureParent?: ng.IAugmentedJQuery, slotName?: string): ng.IAugmentedJQuery; 9 | 10 | isSlotFilled(slotName: string): boolean; 11 | } 12 | } -------------------------------------------------------------------------------- /typings/angularUIBootstrap.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'angular-ui-router' { 2 | export interface IStateService{ 3 | includes(value: any): boolean; 4 | go(name: string): Promise; 5 | } 6 | } -------------------------------------------------------------------------------- /typings/bootstrapDateTimePicker.d.ts: -------------------------------------------------------------------------------- 1 | import * as moment from 'moment' 2 | 3 | declare namespace bootstrapDateTimePicker { 4 | export interface IConfiguration { 5 | stepping?: number; 6 | format?: string | boolean; 7 | direction?: string; 8 | elementHeight?: number; 9 | pickDate?: boolean; 10 | pickTime?: boolean; 11 | minDate?: string | Date | moment.Moment; 12 | maxDate?: string | Date | moment.Moment; 13 | } 14 | 15 | export interface IDateTimePicker extends JQuery { 16 | (config: IConfiguration): JQuery; 17 | defaults: IConfiguration; 18 | } 19 | } 20 | 21 | 22 | export = bootstrapDateTimePicker; 23 | export as namespace bootstrapDateTimePicker; 24 | 25 | 26 | -------------------------------------------------------------------------------- /typings/chaiAssertions.d.ts: -------------------------------------------------------------------------------- 1 | declare var expect: Chai.ExpectStatic; 2 | 3 | declare module Chai { 4 | interface ChaiStatic { 5 | Assertion: Assertion; 6 | } 7 | 8 | interface Assertion extends MomentAssertion { 9 | addMethod: Function; 10 | } 11 | 12 | interface MomentAssertion { 13 | sameMoment(value: any, message?: string): Assertion; 14 | equalMoment(value: any, message?: string): Assertion; 15 | afterMoment(value: any, message?: string): Assertion; 16 | beforeMoment(value: any, message?: string): Assertion; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typings/commonjs.d.ts: -------------------------------------------------------------------------------- 1 | // Add a definition for commonjs require 2 | 3 | declare var require: { (path: string): any }; -------------------------------------------------------------------------------- /typings/jQuery.d.ts: -------------------------------------------------------------------------------- 1 | 2 | interface JQuery { 3 | datetimepicker: bootstrapDateTimePicker.IDateTimePicker; 4 | } 5 | -------------------------------------------------------------------------------- /typings/jasmine.d.ts: -------------------------------------------------------------------------------- 1 | declare var describe: { (name: string, specs: { (): any }) }; 2 | declare var fdescribe: { (name: string, specs: { (): any }) }; 3 | declare var it: { (name: string, spec: { (done?: Function): any }) }; 4 | declare var fit: { (name: string, spec: { (done?: Function): any }) }; 5 | declare var beforeEach: { (setup: { (): any }) }; 6 | declare var afterEach: { (cleanup: { (): any }) }; 7 | -------------------------------------------------------------------------------- /typings/moment.d.ts: -------------------------------------------------------------------------------- 1 | import * as moment from "moment"; 2 | 3 | declare module "moment" { 4 | export type MomentFormatSpecification = string; 5 | } 6 | 7 | export = moment; 8 | -------------------------------------------------------------------------------- /typings/sinon.d.ts: -------------------------------------------------------------------------------- 1 | import { SinonStatic } from 'sinon'; 2 | 3 | declare global { 4 | const sinon: SinonStatic; 5 | } 6 | --------------------------------------------------------------------------------