Commit b4bcc0f1 authored by Matt Teeter's avatar Matt Teeter

Merge branch 'develop' into 'master'

Develop

See merge request !15
parents e727ed0d a8cd77a0
Pipeline #87435 passed with stages
in 4 minutes and 6 seconds
...@@ -2,6 +2,14 @@ ...@@ -2,6 +2,14 @@
Monorepo for building-block type utilities that don't have dependencies on any other `@psu` libraries. Monorepo for building-block type utilities that don't have dependencies on any other `@psu` libraries.
- [Angular](https://git.psu.edu/ais-swe/ux/utils/tree/develop/libs/utils/angular)
- Before Unload directive
- Caps Lock directive
- Coalescing Component Factory Resolver
- ngLet directive
- Safe pipe
- Value By Key pipe
- Yes/No pipe
- [Browser](https://git.psu.edu/ais-swe/ux/utils/tree/develop/libs/utils/browser) - [Browser](https://git.psu.edu/ais-swe/ux/utils/tree/develop/libs/utils/browser)
- Cache Interceptor - Cache Interceptor
- Autofocus Directive - Autofocus Directive
......
...@@ -141,11 +141,6 @@ ...@@ -141,11 +141,6 @@
"setupFile": "libs/utils/src/test-setup.ts" "setupFile": "libs/utils/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
}, },
"utils-security": { "utils-security": {
...@@ -169,11 +164,6 @@ ...@@ -169,11 +164,6 @@
"setupFile": "libs/utils/security/src/test-setup.ts" "setupFile": "libs/utils/security/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
}, },
"utils-rx": { "utils-rx": {
...@@ -197,11 +187,6 @@ ...@@ -197,11 +187,6 @@
"setupFile": "libs/utils/rx/src/test-setup.ts" "setupFile": "libs/utils/rx/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
}, },
"utils-browser": { "utils-browser": {
...@@ -225,11 +210,6 @@ ...@@ -225,11 +210,6 @@
"setupFile": "libs/utils/browser/src/test-setup.ts" "setupFile": "libs/utils/browser/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
}, },
"utils-angular": { "utils-angular": {
...@@ -253,11 +233,6 @@ ...@@ -253,11 +233,6 @@
"setupFile": "libs/utils/angular/src/test-setup.ts" "setupFile": "libs/utils/angular/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
}, },
"utils-responsive": { "utils-responsive": {
...@@ -281,11 +256,6 @@ ...@@ -281,11 +256,6 @@
"setupFile": "libs/utils/responsive/src/test-setup.ts" "setupFile": "libs/utils/responsive/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
}, },
"utils-theming": { "utils-theming": {
...@@ -309,11 +279,6 @@ ...@@ -309,11 +279,6 @@
"setupFile": "libs/utils/theming/src/test-setup.ts" "setupFile": "libs/utils/theming/src/test-setup.ts"
} }
} }
},
"schematics": {
"@nrwl/angular:component": {
"styleext": "scss"
}
} }
} }
}, },
...@@ -331,14 +296,14 @@ ...@@ -331,14 +296,14 @@
"e2eTestRunner": "cypress" "e2eTestRunner": "cypress"
}, },
"@nrwl/angular:library": { "@nrwl/angular:library": {
"unitTestRunner": "jest",
"directory": "utils", "directory": "utils",
"simpleModuleName": true, "simpleModuleName": true,
"style": "scss" "style": "scss",
"unitTestRunner": "jest"
}, },
"@psu/schematics:ng-new": { "@psu/schematics:ng-new": {
"workspaceType": "library" "workspaceType": "library"
} }
}, },
"defaultProject": "demo" "defaultProject": "utils"
} }
module.exports = { module.exports = {
testMatch: ["**/+(*.)+(spec|test).+(ts|js)?(x)"], testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
transform: { transform: {
"^.+\\.(ts|js|html)$": "ts-jest" '^.+\\.(ts|js|html)$': 'ts-jest'
}, },
resolver: "@nrwl/jest/plugins/resolver", resolver: '@nrwl/jest/plugins/resolver',
moduleFileExtensions: ["ts", "js", "html"], moduleFileExtensions: ['ts', 'js', 'html'],
collectCoverage: true, collectCoverage: true,
coverageReporters: ["html"] coverageReporters: ['lcov', 'html', 'text']
}; };
# utils-angular # Angular Utils
This library was generated with [Nx](https://nx.dev). ## before-unload directive
## Running unit tests ## caps-lock directive
Run `nx test utils-angular` to execute the unit tests. ## coalescing-component-factory-resolver
## ng-let directive
## safe pipe
## value-by-key pipe
Pipe that returns an object's value by key
### Usage
```js
let obj = {
a: { name: 'one' },
b: { name: 'two' },
c: { name: 'three' }
};
```
```html
<!-- Will output "one" -->
<span>{{ (obj | valueByKey : 'a')?.name }}</span>
```
## yes-no pipe
...@@ -7,5 +7,7 @@ export * from './lib/ng-let/ng-let.directive'; ...@@ -7,5 +7,7 @@ export * from './lib/ng-let/ng-let.directive';
export * from './lib/ng-let/ng-let.module'; export * from './lib/ng-let/ng-let.module';
export * from './lib/safe-pipe/safe-pipe.module'; export * from './lib/safe-pipe/safe-pipe.module';
export * from './lib/safe-pipe/safe-pipe.pipe'; export * from './lib/safe-pipe/safe-pipe.pipe';
export { ValueByKeyModule } from './lib/value-by-key/value-by-key.module';
export { ValueByKeyPipe } from './lib/value-by-key/value-by-key.pipe';
export * from './lib/yes-no/yes-no.module'; export * from './lib/yes-no/yes-no.module';
export * from './lib/yes-no/yes-no.pipe'; export * from './lib/yes-no/yes-no.pipe';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ValueByKeyPipe } from './value-by-key.pipe';
@NgModule({
declarations: [ValueByKeyPipe],
imports: [CommonModule],
exports: [ValueByKeyPipe]
})
export class ValueByKeyModule {}
import { ValueByKeyPipe } from './value-by-key.pipe';
describe('ValueByKeyPipe', () => {
let pipe: ValueByKeyPipe;
beforeEach(() => {
pipe = new ValueByKeyPipe();
});
it('create an instance', () => {
expect(pipe).toBeTruthy();
});
it('should return a value when the key exists in the object', () => {
expect(pipe.transform({ a: 'test' }, 'a')).toEqual('test');
});
it('should return null if the key is not found in the object', () => {
expect(pipe.transform({ a: 'test' }, 'b')).toBeNull();
});
it('should return null if the object is nil', () => {
expect(pipe.transform(undefined, 'a')).toBeNull();
expect(pipe.transform(null, 'a')).toBeNull();
});
it('should return null if the key is nil', () => {
expect(pipe.transform({ a: 'test' }, undefined)).toBeNull();
expect(pipe.transform({ a: 'test' }, null)).toBeNull();
});
});
import { Pipe, PipeTransform } from '@angular/core';
import { pathOr } from 'ramda';
@Pipe({
name: 'valueByKey'
})
export class ValueByKeyPipe implements PipeTransform {
public transform(value: object, key: string): any {
return pathOr(null, [key], value);
}
}
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
"peerDependencies": { "peerDependencies": {
"@angular/common": "^8.0.0", "@angular/common": "^8.0.0",
"@angular/core": "^8.0.0", "@angular/core": "^8.0.0",
"@angular/cdk": "^8.2.3" "@angular/cdk": "^8.2.3",
"ramda": "^0.27.0"
}, },
"private": false, "private": false,
"repository": { "repository": {
......
...@@ -21,7 +21,7 @@ export class ResponsiveDirective implements OnInit, OnDestroy { ...@@ -21,7 +21,7 @@ export class ResponsiveDirective implements OnInit, OnDestroy {
constructor(private responsiveService: ResponsiveService) {} constructor(private responsiveService: ResponsiveService) {}
ngOnInit(): void { public ngOnInit(): void {
this.responsiveService.currentScreenSize$ this.responsiveService.currentScreenSize$
.pipe( .pipe(
filter(size => !!size), filter(size => !!size),
......
import { BreakpointObserver } from '@angular/cdk/layout'; import { BreakpointObserver } from '@angular/cdk/layout';
import { Injectable, OnDestroy } from '@angular/core'; import { Injectable, OnDestroy } from '@angular/core';
import { combineLatest, Observable, ReplaySubject, Subject } from 'rxjs'; import { combineLatest, Observable, ReplaySubject, Subject } from 'rxjs';
import { map, takeUntil, tap } from 'rxjs/operators'; import { filter, map, takeUntil, tap } from 'rxjs/operators';
import { PSU_BREAKPOINTS } from './breakpoints.model'; import { PSU_BREAKPOINTS } from './breakpoints.model';
import { ScreenSize } from './screen-size.model'; import { ScreenSize } from './screen-size.model';
...@@ -45,23 +45,29 @@ export class ResponsiveService implements OnDestroy { ...@@ -45,23 +45,29 @@ export class ResponsiveService implements OnDestroy {
combineLatest(this.isMobile$, this.isTabletSmall$, this.isTabletLarge$, this.isDesktop$) combineLatest(this.isMobile$, this.isTabletSmall$, this.isTabletLarge$, this.isDesktop$)
.pipe( .pipe(
map(([mobile, tabletSmall, tabletLarge, desktop]) => ({ mobile, tabletSmall, tabletLarge, desktop })), map(([mobile, tabletSmall, tabletLarge, desktop]) => ({ mobile, tabletSmall, tabletLarge, desktop })),
filter(responsiveChange => {
const values = Object.values(responsiveChange);
return values.some(breakpoints => !!breakpoints) && values.filter(val => !!val).length === 1;
}),
tap(responsiveChange => { tap(responsiveChange => {
let screenSize: ScreenSize; let screenSize: ScreenSize;
if (responsiveChange.mobile) { if (responsiveChange.desktop) {
screenSize = ScreenSize.MOBILE; screenSize = ScreenSize.DESKTOP;
this.isMobile = true; this.isDesktop = true;
} else if (responsiveChange.tabletSmall) {
screenSize = ScreenSize.TABLET_SM;
this.isTabletSmall = true;
} else if (responsiveChange.tabletLarge) { } else if (responsiveChange.tabletLarge) {
screenSize = ScreenSize.TABLET; screenSize = ScreenSize.TABLET;
this.isTabletLarge = true; this.isTabletLarge = true;
} else { } else if (responsiveChange.tabletSmall) {
screenSize = ScreenSize.DESKTOP; screenSize = ScreenSize.TABLET_SM;
this.isDesktop = true; this.isTabletSmall = true;
} else if (responsiveChange.mobile) {
screenSize = ScreenSize.MOBILE;
this.isMobile = true;
} }
this.screenSizeChange(screenSize); if (!!screenSize) {
this.screenSizeChange(screenSize);
}
}), }),
takeUntil(this._destroy$) takeUntil(this._destroy$)
) )
......
...@@ -8,28 +8,28 @@ ...@@ -8,28 +8,28 @@
"nx.json": "*" "nx.json": "*"
}, },
"projects": { "projects": {
"demo-e2e": { "demo": {
"tags": [] "tags": []
}, },
"demo": { "demo-e2e": {
"tags": [] "tags": []
}, },
"utils": { "utils": {
"tags": ["none"] "tags": ["none"]
}, },
"utils-security": { "utils-angular": {
"tags": [] "tags": []
}, },
"utils-rx": { "utils-browser": {
"tags": [] "tags": []
}, },
"utils-browser": { "utils-responsive": {
"tags": [] "tags": []
}, },
"utils-angular": { "utils-rx": {
"tags": [] "tags": []
}, },
"utils-responsive": { "utils-security": {
"tags": [] "tags": []
}, },
"utils-theming": { "utils-theming": {
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
"@psu/schematics": "^1.0.4-beta.13", "@psu/schematics": "^1.0.4-beta.13",
"@types/jest": "24.0.9", "@types/jest": "24.0.9",
"@types/node": "~8.9.4", "@types/node": "~8.9.4",
"@types/ramda": "^0.26.43",
"backoff-rxjs": "^6.3.3", "backoff-rxjs": "^6.3.3",
"codelyzer": "~5.0.1", "codelyzer": "~5.0.1",
"commitizen": "^4.0.3", "commitizen": "^4.0.3",
...@@ -78,6 +79,7 @@ ...@@ -78,6 +79,7 @@
"ngx-cookie": "^4.1.2", "ngx-cookie": "^4.1.2",
"npm-link-check": "3.0.0", "npm-link-check": "3.0.0",
"prettier": "1.18.2", "prettier": "1.18.2",
"ramda": "^0.27.0",
"short-uuid": "^3.1.1", "short-uuid": "^3.1.1",
"ts-jest": "24.0.0", "ts-jest": "24.0.0",
"ts-mocks": "^2.6.0", "ts-mocks": "^2.6.0",
...@@ -93,28 +95,28 @@ ...@@ -93,28 +95,28 @@
"url": "https://git.psu.edu/ais-swe/ux/utils" "url": "https://git.psu.edu/ais-swe/ux/utils"
}, },
"lint-staged": { "lint-staged": {
"*.json": [ "*.html": [
"prettier --write", "html-beautify -qr",
"git add" "git add"
], ],
"*.ts": [ "*.json": [
"prettier --write", "prettier --write",
"tslint --project tsconfig.json",
"git add"
],
"*.html": [
"html-beautify -qr",
"git add" "git add"
], ],
"*.scss": [ "*.scss": [
"css-beautify -qr", "css-beautify -qr",
"git add" "git add"
],
"*.ts": [
"prettier --write",
"tslint --fix --project tsconfig.json",
"git add"
] ]
}, },
"husky": { "husky": {
"hooks": { "hooks": {
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"pre-push": "yarn test" "pre-push": "yarn test utils"
} }
}, },
"config": { "config": {
......
...@@ -17,11 +17,11 @@ ...@@ -17,11 +17,11 @@
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@psu/utils": ["libs/utils/src/index.ts"], "@psu/utils": ["libs/utils/src/index.ts"],
"@psu/utils/security": ["libs/utils/security/src/index.ts"],
"@psu/utils/rx": ["libs/utils/rx/src/index.ts"],
"@psu/utils/browser": ["libs/utils/browser/src/index.ts"],
"@psu/utils/angular": ["libs/utils/angular/src/index.ts"], "@psu/utils/angular": ["libs/utils/angular/src/index.ts"],
"@psu/utils/browser": ["libs/utils/browser/src/index.ts"],
"@psu/utils/responsive": ["libs/utils/responsive/src/index.ts"], "@psu/utils/responsive": ["libs/utils/responsive/src/index.ts"],
"@psu/utils/rx": ["libs/utils/rx/src/index.ts"],
"@psu/utils/security": ["libs/utils/security/src/index.ts"],
"@psu/utils/theming": ["libs/utils/theming/src/index.ts"] "@psu/utils/theming": ["libs/utils/theming/src/index.ts"]
} }
}, },
......
{ {
"rulesDirectory": [ "rulesDirectory": ["node_modules/@nrwl/workspace/src/tslint", "node_modules/codelyzer"],
"node_modules/@nrwl/workspace/src/tslint",
"node_modules/codelyzer"
],
"rules": { "rules": {
"arrow-return-shorthand": true, "arrow-return-shorthand": true,
"callable-types": true, "callable-types": true,
...@@ -17,17 +14,12 @@ ...@@ -17,17 +14,12 @@
"member-ordering": [ "member-ordering": [
true, true,
{ {
"order": [ "order": ["static-field", "instance-field", "static-method", "instance-method"]
"static-field",
"instance-field",
"static-method",
"instance-method"
]
} }
], ],
"no-arg": true, "no-arg": true,
"no-bitwise": true, "no-bitwise": true,
"no-console": [true, "debug", "info", "time", "timeEnd", "trace"], "no-console": [true, "debug", "info", "log", "time", "timeEnd", "trace"],
"no-construct": true, "no-construct": true,
"no-debugger": true, "no-debugger": true,
"no-duplicate-super": true, "no-duplicate-super": true,
...@@ -62,8 +54,8 @@ ...@@ -62,8 +54,8 @@
] ]
} }
], ],
"directive-selector": [true, "attribute", "app", "camelCase"], "directive-selector": [true, "attribute", "ut", "camelCase"],
"component-selector": [true, "element", "app", "kebab-case"], "component-selector": [true, "element", "ut", "kebab-case"],
"no-conflicting-lifecycle": true, "no-conflicting-lifecycle": true,
"no-host-metadata-property": true, "no-host-metadata-property": true,
"no-input-rename": true, "no-input-rename": true,
......
...@@ -1609,6 +1609,13 @@ ...@@ -1609,6 +1609,13 @@
resolved "https://nexus.ci.psu.edu/repository/npm-all/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" resolved "https://nexus.ci.psu.edu/repository/npm-all/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==
"@types/ramda@^0.26.43":
version "0.26.43"
resolved "https://nexus.ci.psu.edu/repository/npm-all/@types/ramda/-/ramda-0.26.43.tgz#62e235ea17133b8629bc891a26851cf0ea2b4204"
integrity sha512-VK2EaHR/fpeMNPDboGSPAmH+a6HN1pflWqRt67Jii2n8vGpYt6vxIBc1ZdoYrA/jQXRaGGpJKRiSPcHALRD3/A==
dependencies:
ts-toolbelt "^6.3.3"
"@types/resolve@0.0.8": "@types/resolve@0.0.8":
version "0.0.8" version "0.0.8"
resolved "https://nexus.ci.psu.edu/repository/npm-all/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"