From 9b3cc51dbed3e0960420a91f746b4139ff545f3c Mon Sep 17 00:00:00 2001 From: Tiago Melo Date: Thu, 26 Apr 2018 15:52:27 +0100 Subject: [PATCH] mgr/dashboard: Add Prettier formatter to the frontend This will force the use of prettier on frontend code, bringing a more consistent formatting to all the code. The current configuration will apply the prettier formatting, on all staged files, during the precommit hook. Signed-off-by: Tiago Melo --- src/pybind/mgr/dashboard/frontend/.prettierrc | 5 + .../mgr/dashboard/frontend/package.json | 6 +- .../datatable/table/table.component.spec.ts | 62 ++++++------- .../app/shared/validators/cd-validators.ts | 30 +++--- src/pybind/mgr/dashboard/frontend/tslint.json | 93 +++---------------- 5 files changed, 67 insertions(+), 129 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/.prettierrc diff --git a/src/pybind/mgr/dashboard/frontend/.prettierrc b/src/pybind/mgr/dashboard/frontend/.prettierrc new file mode 100644 index 0000000000000..7d65e36439876 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/.prettierrc @@ -0,0 +1,5 @@ +{ + "arrowParens": "always", + "printWidth": 100, + "singleQuote": true +} diff --git a/src/pybind/mgr/dashboard/frontend/package.json b/src/pybind/mgr/dashboard/frontend/package.json index 14eef2b248451..b89fe35015132 100644 --- a/src/pybind/mgr/dashboard/frontend/package.json +++ b/src/pybind/mgr/dashboard/frontend/package.json @@ -8,7 +8,8 @@ "build": "ng build", "test": "ng test", "lint": "ng lint", - "e2e": "ng e2e" + "e2e": "ng e2e", + "precommit": "pretty-quick --staged" }, "private": true, "dependencies": { @@ -45,6 +46,7 @@ "@types/node": "~6.0.60", "codelyzer": "^4.0.1", "copy-webpack-plugin": "4.3.0", + "husky": "^0.14.3", "jasmine-core": "~2.6.2", "jasmine-spec-reporter": "~4.1.0", "karma": "~1.7.0", @@ -55,6 +57,8 @@ "karma-jasmine-html-reporter": "^0.2.2", "karma-junit-reporter": "^1.2.0", "karma-phantomjs-launcher": "^1.0.4", + "prettier": "1.12.1", + "pretty-quick": "^1.4.1", "protractor": "~5.3.0", "ts-node": "~3.2.0", "tslint": "~5.9.1", diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts index 5eb78f884e58d..37eaf41bc13bb 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.spec.ts @@ -17,7 +17,7 @@ describe('TableComponent', () => { data.push({ a: i, b: i * i, - c: [-(i % 10), 'score' + (i % 16 + 6) ], + c: [-(i % 10), 'score' + (i % 16 + 6)], d: !(i % 2) }); } @@ -31,14 +31,12 @@ describe('TableComponent', () => { expect(component.rows[0]).toEqual(firstObject); }; - beforeEach( - async(() => { - TestBed.configureTestingModule({ - declarations: [TableComponent], - imports: [NgxDatatableModule, FormsModule, ComponentsModule, RouterTestingModule] - }).compileComponents(); - }) - ); + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TableComponent], + imports: [NgxDatatableModule, FormsModule, ComponentsModule, RouterTestingModule] + }).compileComponents(); + })); beforeEach(() => { fixture = TestBed.createComponent(TableComponent); @@ -49,10 +47,10 @@ describe('TableComponent', () => { component.data = createFakeData(100); component.useData(); component.columns = [ - {prop: 'a', name: 'Index'}, - {prop: 'b', name: 'Power ofA'}, - {prop: 'c', name: 'Poker array'}, - {prop: 'd', name: 'Boolean value'} + { prop: 'a', name: 'Index' }, + { prop: 'b', name: 'Power ofA' }, + { prop: 'c', name: 'Poker array' }, + { prop: 'd', name: 'Boolean value' } ]; }); @@ -69,7 +67,7 @@ describe('TableComponent', () => { expect(component.limit).toBe(10); expect(component.limit).toEqual(jasmine.any(Number)); - const e = {target: {value: '1'}}; + const e = { target: { value: '1' } }; component.setLimit(e); expect(component.limit).toBe(1); expect(component.limit).toEqual(jasmine.any(Number)); @@ -79,19 +77,19 @@ describe('TableComponent', () => { }); it('should search for 13', () => { - doSearch('13', 9, {a: 7, b: 49, c: [ -7, 'score13'], d: false}); + doSearch('13', 9, { a: 7, b: 49, c: [-7, 'score13'], d: false }); expect(component.rows[1].a).toBe(13); expect(component.rows[8].a).toBe(87); }); it('should search for true', () => { - doSearch('true', 50, {a: 0, b: 0, c: [ -0, 'score6'], d: true}); + doSearch('true', 50, { a: 0, b: 0, c: [-0, 'score6'], d: true }); expect(component.rows[0].d).toBe(true); expect(component.rows[1].d).toBe(true); }); it('should search for false', () => { - doSearch('false', 50, {a: 1, b: 1, c: [ -1, 'score7'], d: false}); + doSearch('false', 50, { a: 1, b: 1, c: [-1, 'score7'], d: false }); expect(component.rows[0].d).toBe(false); expect(component.rows[1].d).toBe(false); }); @@ -106,36 +104,36 @@ describe('TableComponent', () => { searchTerms = st; component.updateFilter(true); }; - searchTest('a b c', [ 'a', 'b', 'c' ]); - searchTest('a+b c', [ 'a+b', 'c' ]); - searchTest('a,,,, b,,, c', [ 'a', 'b', 'c' ]); - searchTest('a,,,+++b,,, c', [ 'a+++b', 'c' ]); - searchTest('"a b c" "d e f", "g, h i"', [ 'a+b+c', 'd+e++f', 'g+h+i' ]); + searchTest('a b c', ['a', 'b', 'c']); + searchTest('a+b c', ['a+b', 'c']); + searchTest('a,,,, b,,, c', ['a', 'b', 'c']); + searchTest('a,,,+++b,,, c', ['a+++b', 'c']); + searchTest('"a b c" "d e f", "g, h i"', ['a+b+c', 'd+e++f', 'g+h+i']); }); it('should search for multiple values', () => { - doSearch('7 5 3', 5, {a: 57, b: 3249, c: [ -7, 'score15'], d: false}); + doSearch('7 5 3', 5, { a: 57, b: 3249, c: [-7, 'score15'], d: false }); }); it('should search with column filter', () => { - doSearch('power:1369', 1, {a: 37, b: 1369, c: [ -7, 'score11'], d: false}); - doSearch('ndex:7 ofa:5 poker:3', 3, {a: 71, b: 5041, c: [-1, 'score13'], d: false}); + doSearch('power:1369', 1, { a: 37, b: 1369, c: [-7, 'score11'], d: false }); + doSearch('ndex:7 ofa:5 poker:3', 3, { a: 71, b: 5041, c: [-1, 'score13'], d: false }); }); it('should search with through array', () => { - doSearch('array:score21', 6, {a: 15, b: 225, c: [-5, 'score21'], d: false}); + doSearch('array:score21', 6, { a: 15, b: 225, c: [-5, 'score21'], d: false }); }); it('should search with spaces', () => { - doSearch('\'poker array\':score21', 6, {a: 15, b: 225, c: [-5, 'score21'], d: false}); - doSearch('"poker array":score21', 6, {a: 15, b: 225, c: [-5, 'score21'], d: false}); - doSearch('poker+array:score21', 6, {a: 15, b: 225, c: [-5, 'score21'], d: false}); + doSearch(`'poker array':score21`, 6, { a: 15, b: 225, c: [-5, 'score21'], d: false }); + doSearch('"poker array":score21', 6, { a: 15, b: 225, c: [-5, 'score21'], d: false }); + doSearch('poker+array:score21', 6, { a: 15, b: 225, c: [-5, 'score21'], d: false }); }); it('should not search if column name is incomplete', () => { - doSearch('\'poker array\'', 100, {a: 0, b: 0, c: [-0, 'score6'], d: true}); - doSearch('pok', 100, {a: 0, b: 0, c: [-0, 'score6'], d: true}); - doSearch('pok:', 100, {a: 0, b: 0, c: [-0, 'score6'], d: true}); + doSearch(`'poker array'`, 100, { a: 0, b: 0, c: [-0, 'score6'], d: true }); + doSearch('pok', 100, { a: 0, b: 0, c: [-0, 'score6'], d: true }); + doSearch('pok:', 100, { a: 0, b: 0, c: [-0, 'score6'], d: true }); }); it('should restore full table after search', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/validators/cd-validators.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/validators/cd-validators.ts index 88edeb8aef3f7..0c1a9b53ebc91 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/validators/cd-validators.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/validators/cd-validators.ts @@ -1,16 +1,7 @@ -import { - AbstractControl, - ValidationErrors, - ValidatorFn, - Validators -} from '@angular/forms'; +import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms'; import * as _ from 'lodash'; -type Prerequisites = { // tslint:disable-line - [key: string]: any -}; - export function isEmptyInputValue(value: any): boolean { return value == null || value.length === 0; } @@ -33,7 +24,7 @@ export class CdValidators { * the specified prerequisites matches. If the prerequisites are fulfilled, * then the given function is executed and if it succeeds, the 'required' * validation error will be returned, otherwise null. - * @param {Prerequisites} prerequisites An object containing the prerequisites. + * @param {Object} prerequisites An object containing the prerequisites. * ### Example * ```typescript * { @@ -49,17 +40,20 @@ export class CdValidators { * argument. The function must return true to set the validation error. * @return {ValidatorFn} Returns the validator function. */ - static requiredIf(prerequisites: Prerequisites, condition?: Function | undefined): ValidatorFn { + static requiredIf(prerequisites: Object, condition?: Function | undefined): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { // Check if all prerequisites matches. - if (!Object.keys(prerequisites).every((key) => { - return (control.parent && control.parent.get(key).value === prerequisites[key]); - })) { + if ( + !Object.keys(prerequisites).every((key) => { + return control.parent && control.parent.get(key).value === prerequisites[key]; + }) + ) { return null; } - const success = _.isFunction(condition) ? condition.call(condition, control.value) : - isEmptyInputValue(control.value); - return success ? {'required': true} : null; + const success = _.isFunction(condition) + ? condition.call(condition, control.value) + : isEmptyInputValue(control.value); + return success ? { required: true } : null; }; } } diff --git a/src/pybind/mgr/dashboard/frontend/tslint.json b/src/pybind/mgr/dashboard/frontend/tslint.json index d2486f1bbcaa0..eb4503d8dbb65 100644 --- a/src/pybind/mgr/dashboard/frontend/tslint.json +++ b/src/pybind/mgr/dashboard/frontend/tslint.json @@ -1,70 +1,37 @@ { - "rulesDirectory": [ - "node_modules/codelyzer" - ], - "extends": [ - "tslint-eslint-rules" - ], + "rulesDirectory": ["node_modules/codelyzer"], + "extends": ["tslint-eslint-rules"], "rules": { "no-consecutive-blank-lines": true, "arrow-return-shorthand": true, "callable-types": true, "class-name": true, - "comment-format": [ - true, - "check-space" - ], + "comment-format": [true, "check-space"], "curly": true, "eofline": true, "forin": true, - "import-blacklist": [ - true, - "rxjs", - "rxjs/Rx" - ], + "import-blacklist": [true, "rxjs", "rxjs/Rx"], "import-spacing": true, - "indent": [ - true, - "spaces" - ], + "indent": [true, "spaces"], "interface-over-type-literal": true, "label-position": true, - "max-line-length": [ - true, - 100 - ], "member-access": false, "member-ordering": [ true, { - "order": [ - "static-field", - "instance-field", - "static-method", - "instance-method" - ] + "order": ["static-field", "instance-field", "static-method", "instance-method"] } ], "no-arg": true, "no-bitwise": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], + "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], "no-construct": true, "no-debugger": true, "no-duplicate-super": true, "no-empty": false, "no-empty-interface": true, "no-eval": true, - "no-inferrable-types": [ - true, - "ignore-params" - ], + "no-inferrable-types": [true, "ignore-params"], "no-misused-new": true, "no-non-null-assertion": true, "no-shadowed-variable": true, @@ -77,27 +44,12 @@ "no-use-before-declare": true, "no-var-keyword": true, "object-literal-sort-keys": false, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], + "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], "prefer-const": true, - "quotemark": [ - true, - "single" - ], + "quotemark": [true, "single"], "radix": true, - "semicolon": [ - true, - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], + "semicolon": [true, "always"], + "triple-equals": [true, "allow-null-check"], "typedef-whitespace": [ true, { @@ -109,32 +61,17 @@ } ], "unified-signatures": true, - "variable-name": [ - true, - "check-format", - "allow-snake-case" - ], + "variable-name": [true, "check-format", "allow-snake-case"], "whitespace": [ true, "check-branch", - "check-decl", "check-operator", "check-separator", "check-type", "check-module" ], - "directive-selector": [ - true, - "attribute", - "cd", - "camelCase" - ], - "component-selector": [ - true, - "element", - "cd", - "kebab-case" - ], + "directive-selector": [true, "attribute", "cd", "camelCase"], + "component-selector": [true, "element", "cd", "kebab-case"], "angular-whitespace": [true, "check-interpolation", "check-semicolon"], "no-output-on-prefix": true, "use-input-property-decorator": true, -- 2.39.5