diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..a80ddd239 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,90 @@ +{ + "root": true, + "ignorePatterns": ["projects/**/*"], + "overrides": [ + { + "parser": "@typescript-eslint/parser", + "files": ["*.ts"], + "parserOptions": { + "project": ["tsconfig.json", "e2e/tsconfig.json"], + "createDefaultProgram": true + }, + "extends": ["plugin:@angular-eslint/recommended", "plugin:@angular-eslint/template/process-inline-templates"], + "rules": { + "@angular-eslint/component-selector": [ + "error", + { + "prefix": "app", + "style": "kebab-case", + "type": "element" + } + ], + "@angular-eslint/directive-selector": [ + "error", + { + "style": "camelCase", + "type": "attribute" + } + ], + // "arrow-body-style": ["error", "as-needed", { "requireReturnForObjectLiteral": true }], + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/naming-convention": ["error", { "selector": "class", "format": ["PascalCase"] }], + "spaced-comment": ["error", "always", { "exceptions": ["*"] }], + "curly": ["error", "all"], + "eol-last": ["error", "always"], + "guard-for-in": "error", + "no-restricted-imports": ["error", "rxjs/Rx"], + "indent": "off", + "no-labels": ["error", { "allowLoop": true, "allowSwitch": true }], + "max-len": ["error", { "code": 140 }], + "@typescript-eslint/explicit-member-accessibility": "off", + "@typescript-eslint/member-ordering": [ + "error", + { + "default": ["static-field", "instance-field", "static-method", "instance-method"] + } + ], + "no-caller": "error", + "no-bitwise": "error", + "no-console": ["error", { "allow": ["warn", "error", "log"] }], + "no-new-wrappers": "error", + "no-debugger": "error", + "no-empty": "off", + "@typescript-eslint/no-empty-interface": "error", + "no-eval": "error", + "@typescript-eslint/no-inferrable-types": ["error", { "ignoreParameters": true }], + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-non-null-assertion": "error", + "@typescript-eslint/no-throw-literal": "error", + "no-fallthrough": "error", + "no-trailing-spaces": "error", + "no-undef-init": "error", + "no-var": "error", + "sort-keys": "off", + "brace-style": "error", + "radix": "error", + "semi": "error", + "eqeqeq": ["error", "always", { "null": "ignore" }], + "@angular-eslint/no-empty-lifecycle-method": "off", + "@typescript-eslint/type-annotation-spacing": "error", + "@typescript-eslint/unified-signatures": "error", + "@angular-eslint/directive-class-suffix": "error", + "@angular-eslint/component-class-suffix": "error", + "@angular-eslint/use-pipe-transform-interface": "error", + "@angular-eslint/no-output-rename": "error", + "@angular-eslint/no-input-rename": "error", + "@angular-eslint/no-host-metadata-property": "error", + "@angular-eslint/no-outputs-metadata-property": "error", + "@angular-eslint/no-inputs-metadata-property": "error", + "@angular-eslint/no-output-on-prefix": "error" + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@angular-eslint/template/recommended"], + "rules": { + "@angular-eslint/template/eqeqeq": "off" + } + } + ] +} diff --git a/angular.json b/angular.json index 27fef3a69..82bb368cd 100644 --- a/angular.json +++ b/angular.json @@ -142,10 +142,9 @@ } }, "lint": { - "builder": "@angular-devkit/build-angular:tslint", + "builder": "@angular-eslint/builder:lint", "options": { - "tsConfig": ["src/tsconfig.app.json", "src/tsconfig.spec.json"], - "exclude": ["**/node_modules/**"] + "lintFilePatterns": ["src/**/*.ts", "src/**/*.html"] } } } @@ -160,5 +159,8 @@ "@schematics/angular:directive": { "prefix": "app" } + }, + "cli": { + "defaultCollection": "@angular-eslint/schematics" } } diff --git a/package.json b/package.json index 92e9191e2..d05590c14 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@angular/platform-browser": "^12.2.17", "@angular/platform-browser-dynamic": "^12.2.17", "@angular/router": "^12.2.17", + "@apollo/client": "3.3.0", "@github/markdown-toolbar-element": "^2.1.1", "@octokit/rest": "^16.37.0", "ajv": "^6.11.0", @@ -55,11 +56,15 @@ "rxjs": "6.6.7", "tslib": "^2.0.0", "uuid": "7.0.3", - "zone.js": "~0.11.4", - "@apollo/client": "3.3.0" + "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~12.2.18", + "@angular-eslint/builder": "12.7.0", + "@angular-eslint/eslint-plugin": "12.7.0", + "@angular-eslint/eslint-plugin-template": "12.7.0", + "@angular-eslint/schematics": "12.7.0", + "@angular-eslint/template-parser": "12.7.0", "@angular/cli": "^12.2.18", "@angular/compiler-cli": "^12.2.17", "@angular/language-service": "^12.2.17", @@ -75,8 +80,10 @@ "@types/jasmine": "^3.8.2", "@types/jasminewd2": "2.0.8", "@types/node": "^15.6.1", + "@typescript-eslint/eslint-plugin": "4.28.2", + "@typescript-eslint/parser": "4.28.2", "angular-cli-ghpages": "^1.0.0-rc.2", - "codelyzer": "^6.0.2", + "eslint": "^7.26.0", "husky": "^4.2.5", "jasmine": "^3.9.0", "jasmine-core": "~3.8.0", @@ -92,7 +99,6 @@ "pretty-quick": "^3.1.1", "scuri": "^0.9.4", "ts-node": "^10.9.2", - "tslint": "~6.1.0", "tslint-config-prettier": "^1.18.0", "typescript": "4.3.5" } diff --git a/src/app/core/models/generators/github-issue.generator.ts b/src/app/core/models/generators/github-issue.generator.ts index 0dc7240bc..464f33f7d 100644 --- a/src/app/core/models/generators/github-issue.generator.ts +++ b/src/app/core/models/generators/github-issue.generator.ts @@ -2,21 +2,22 @@ import { GithubIssue } from '../github/github-issue.model'; export default function generateGithubIssuesArray(numberOfElements: number = 1): Array { const created_and_updated_date: string = getRandomDate().toISOString(); - return new Array(10).map((value: GithubIssue, index: number, array: GithubIssue[]) => { - return new GithubIssue({ - id: index, - number: Math.random(), - assignees: undefined, - body: `Automatically Generated Issue No id: ${index}.`, - created_at: created_and_updated_date, - labels: undefined, - title: `Autogen Issue ${index}`, - updated_at: created_and_updated_date, - url: '', - user: undefined, - comments: undefined - }); - }); + return new Array(10).map( + (value: GithubIssue, index: number, array: GithubIssue[]) => + new GithubIssue({ + id: index, + number: Math.random(), + assignees: undefined, + body: `Automatically Generated Issue No id: ${index}.`, + created_at: created_and_updated_date, + labels: undefined, + title: `Autogen Issue ${index}`, + updated_at: created_and_updated_date, + url: '', + user: undefined, + comments: undefined + }) + ); } /** diff --git a/src/app/core/models/github/github-graphql.issue.ts b/src/app/core/models/github/github-graphql.issue.ts index 7ffb6c33a..b4e9e77fc 100644 --- a/src/app/core/models/github/github-graphql.issue.ts +++ b/src/app/core/models/github/github-graphql.issue.ts @@ -20,10 +20,12 @@ export class GithubGraphqlIssue extends GithubIssue { }, assignees: flattenEdges(issue.assignees.edges), labels: flattenEdges(issue.labels.edges), - comments: flattenEdges(issue.comments.edges, (node) => ({ - ...node, - id: node.databaseId - })) + comments: flattenEdges(issue.comments.edges, (node) => { + return { + ...node, + id: node.databaseId + }; + }) }); } } diff --git a/src/app/core/models/github/github-issue.model.ts b/src/app/core/models/github/github-issue.model.ts index 3be64d611..c2fec9485 100644 --- a/src/app/core/models/github/github-issue.model.ts +++ b/src/app/core/models/github/github-issue.model.ts @@ -58,9 +58,7 @@ export class GithubIssue { } else { const order = GithubLabel.LABEL_ORDER[name]; return labels - .reduce((result, currLabel) => { - return order[currLabel.getValue()] > order[result.getValue()] ? currLabel : result; - }) + .reduce((result, currLabel) => (order[currLabel.getValue()] > order[result.getValue()] ? currLabel : result)) .getValue(); } } diff --git a/src/app/core/models/templates/tester-response-template.model.ts b/src/app/core/models/templates/tester-response-template.model.ts index 296a2e713..cf578fa5f 100644 --- a/src/app/core/models/templates/tester-response-template.model.ts +++ b/src/app/core/models/templates/tester-response-template.model.ts @@ -66,6 +66,7 @@ interface TesterResponseParseResult { } const GITHUB_UI_EDIT_WARNING = + // eslint-disable-next-line max-len '[IMPORTANT!: Please do not edit or reply to this comment using the GitHub UI. You can respond to it using CATcher during the next phase of the PE]'; const TESTER_RESPONSES_HEADER = '# Items for the Tester to Verify'; const DISAGREE_CHECKBOX_DESCRIPTION = 'I disagree'; diff --git a/src/app/core/services/auth.service.ts b/src/app/core/services/auth.service.ts index 7dba57036..99f5b7033 100644 --- a/src/app/core/services/auth.service.ts +++ b/src/app/core/services/auth.service.ts @@ -152,6 +152,7 @@ export class AuthService { this.generateStateString(); this.redirectToOAuthPage( encodeURI( + // eslint-disable-next-line max-len `${AppConfig.githubUrl}/login/oauth/authorize?client_id=${AppConfig.clientId}&scope=${githubRepoPermission},read:user&state=${this.state}` ) ); diff --git a/src/app/core/services/data.service.ts b/src/app/core/services/data.service.ts index c8a20a786..369bc5bfa 100644 --- a/src/app/core/services/data.service.ts +++ b/src/app/core/services/data.service.ts @@ -50,9 +50,7 @@ export class DataService { */ getDataFile(): Observable<{}> { return this.githubService.fetchDataFile().pipe( - map((allCsvDataWrapper: {}) => { - return this.constructData(allCsvDataWrapper); - }), + map((allCsvDataWrapper: {}) => this.constructData(allCsvDataWrapper)), map((jsonData: TabulatedUserData) => { this.dataFile = { teamStructure: this.extractTeamStructure(jsonData) diff --git a/src/app/core/services/github.service.ts b/src/app/core/services/github.service.ts index b88f39b64..579f98d0b 100644 --- a/src/app/core/services/github.service.ts +++ b/src/app/core/services/github.service.ts @@ -107,8 +107,8 @@ export class GithubService { const graphqlFilter = issuesFilter.convertToGraphqlFilter(); return this.toFetchIssues(issuesFilter).pipe( filter((toFetch) => toFetch), - mergeMap(() => { - return this.fetchGraphqlList( + mergeMap(() => + this.fetchGraphqlList( FetchIssuesByTeam, { owner: ORG_NAME, @@ -121,8 +121,8 @@ export class GithubService { }, (result) => result.data.repository.label.issues.edges, GithubGraphqlIssue - ); - }) + ) + ) ); } @@ -135,14 +135,14 @@ export class GithubService { const graphqlFilter = issuesFilter.convertToGraphqlFilter(); return this.toFetchIssues(issuesFilter).pipe( filter((toFetch) => toFetch), - mergeMap(() => { - return this.fetchGraphqlList( + mergeMap(() => + this.fetchGraphqlList( FetchIssues, { owner: ORG_NAME, name: REPO, filter: graphqlFilter }, (result) => result.data.repository.issues.edges, GithubGraphqlIssue - ); - }) + ) + ) ); } @@ -168,9 +168,7 @@ export class GithubService { }), map((resultArray: GithubResponse[]) => { const responses = [responseInFirstPage, ...resultArray]; - const isCached = responses.reduce((result, response) => { - return result && response.isCached; - }, true); + const isCached = responses.reduce((result, response) => result && response.isCached, true); responses.forEach((resp, index) => this.issuesCacheManager.set(index + 1, resp)); return !isCached; }) @@ -184,12 +182,8 @@ export class GithubService { */ isRepositoryPresent(owner: string, repo: string): Observable { return from(octokit.repos.get({ owner: owner, repo: repo, headers: GithubService.IF_NONE_MATCH_EMPTY })).pipe( - map((rawData: { status: number }) => { - return rawData.status !== ERRORCODE_NOT_FOUND; - }), - catchError((err) => { - return of(false); - }), + map((rawData: { status: number }) => rawData.status !== ERRORCODE_NOT_FOUND), + catchError((err) => of(false)), catchError((err) => throwError('Failed to fetch repo data.')) ); } @@ -276,9 +270,7 @@ export class GithubService { }) ).pipe( map((res: any) => res.status !== ERRORCODE_NOT_FOUND), - catchError(() => { - return of(false); - }) + catchError(() => of(false)) ); } @@ -307,9 +299,7 @@ export class GithubService { return this.toFetchIssue(id).pipe( filter((toFetch) => toFetch), mergeMap(() => from(queryRef.refetch())), - map((value: ApolloQueryResult) => { - return new GithubGraphqlIssue(value.data.repository.issue); - }), + map((value: ApolloQueryResult) => new GithubGraphqlIssue(value.data.repository.issue)), throwIfEmpty(() => new HttpErrorResponse({ status: 304 })) ); } @@ -390,17 +380,13 @@ export class GithubService { createIssue(title: string, description: string, labels: string[]): Observable { return from(octokit.issues.create({ owner: ORG_NAME, repo: REPO, title: title, body: description, labels: labels })).pipe( - map((response: GithubResponse) => { - return new GithubIssue(response.data); - }) + map((response: GithubResponse) => new GithubIssue(response.data)) ); } createIssueComment(issueId: number, description: string): Observable { return from(octokit.issues.createComment({ owner: ORG_NAME, repo: REPO, issue_number: issueId, body: description })).pipe( - map((response: GithubResponse) => { - return response.data; - }) + map((response: GithubResponse) => response.data) ); } @@ -420,20 +406,14 @@ export class GithubService { this.issuesLastModifiedManager.set(id, response.headers['last-modified']); return new GithubIssue(response.data); }), - catchError((err) => { - return throwError(err); - }) + catchError((err) => throwError(err)) ); } updateIssueComment(issueComment: IssueComment): Observable { return from( octokit.issues.updateComment({ owner: ORG_NAME, repo: REPO, comment_id: issueComment.id, body: issueComment.description }) - ).pipe( - map((response: GithubResponse) => { - return response.data; - }) - ); + ).pipe(map((response: GithubResponse) => response.data)); } uploadFile(filename: string, base64String: string): Observable { @@ -451,9 +431,7 @@ export class GithubService { fetchEventsForRepo(): Observable { return from(octokit.issues.listEventsForRepo({ owner: ORG_NAME, repo: REPO, headers: GithubService.IF_NONE_MATCH_EMPTY })).pipe( - map((response) => { - return response['data']; - }), + map((response) => response['data']), catchError((err) => throwError('Failed to fetch events for repo.')) ); } @@ -506,9 +484,7 @@ export class GithubService { fetchAuthenticatedUser(): Observable { return from(octokit.users.getAuthenticated()).pipe( - map((response) => { - return response['data']; - }), + map((response) => response['data']), catchError((err) => throwError('Failed to fetch authenticated user.')) ); } @@ -560,11 +536,7 @@ export class GithubService { headers: { 'If-None-Match': this.issuesCacheManager.getEtagFor(pageNumber) } }); const apiCall$ = from(apiCall); - return apiCall$.pipe( - catchError((err) => { - return of(this.issuesCacheManager.get(pageNumber)); - }) - ); + return apiCall$.pipe(catchError((err) => of(this.issuesCacheManager.get(pageNumber)))); } /** @@ -587,9 +559,7 @@ export class GithubService { const issues = results.reduce((accumulated, current) => accumulated.concat(pluckEdges(current)), []); return issues.map((issue) => new Model(issue.node)); }), - throwIfEmpty(() => { - return new HttpErrorResponse({ status: 304 }); - }) + throwIfEmpty(() => new HttpErrorResponse({ status: 304 })) ); } diff --git a/src/app/core/services/issue.service.ts b/src/app/core/services/issue.service.ts index a7afb2f58..a8fd96cc2 100644 --- a/src/app/core/services/issue.service.ts +++ b/src/app/core/services/issue.service.ts @@ -55,14 +55,12 @@ export class IssueService { this.issuesPollSubscription = timer(0, IssueService.POLL_INTERVAL) .pipe( - exhaustMap(() => { - return this.reloadAllIssues().pipe( - catchError(() => { - return EMPTY; - }), + exhaustMap(() => + this.reloadAllIssues().pipe( + catchError(() => EMPTY), finalize(() => this.isLoading.next(false)) - ); - }) + ) + ) ) .subscribe(); } @@ -82,18 +80,16 @@ export class IssueService { */ pollIssue(issueId: number): Observable { return timer(0, IssueService.POLL_INTERVAL).pipe( - exhaustMap(() => { - return this.githubService.fetchIssueGraphql(issueId).pipe( + exhaustMap(() => + this.githubService.fetchIssueGraphql(issueId).pipe( map((response) => { const issue = this.createIssueModel(response); this.updateLocalStore(issue); return issue; }), - catchError((err) => { - return this.getIssue(issueId); - }) - ); - }) + catchError((err) => this.getIssue(issueId)) + ) + ) ); } @@ -115,9 +111,7 @@ export class IssueService { this.createAndSaveIssueModel(response); return this.issues[id]; }), - catchError((err) => { - return of(this.issues[id]); - }) + catchError((err) => of(this.issues[id])) ); } @@ -300,13 +294,7 @@ export class IssueService { * Obtain an observable containing an array of issues that are duplicates of the parentIssue. */ getDuplicateIssuesFor(parentIssue: Issue): Observable { - return this.issues$.pipe( - map((issues) => { - return issues.filter((issue) => { - return issue.duplicateOf === parentIssue.id; - }); - }) - ); + return this.issues$.pipe(map((issues) => issues.filter((issue) => issue.duplicateOf === parentIssue.id))); } reset(resetSessionId: boolean) { diff --git a/src/app/core/services/label.service.ts b/src/app/core/services/label.service.ts index 50c56fe8b..c2ef8cb46 100644 --- a/src/app/core/services/label.service.ts +++ b/src/app/core/services/label.service.ts @@ -307,11 +307,11 @@ export class LabelService { let labelValue: string; const containsDotRegex = /\./g; - const rawName: string = String(githubLabel.name); + const rawName = String(githubLabel.name); [labelCategory, labelValue] = containsDotRegex.test(rawName) ? githubLabel.name.split('.') : [undefined, rawName]; const labelColor = githubLabel.color; - const labelDefinition: string = String(githubLabel.description); + const labelDefinition = String(githubLabel.description); return new Label(labelCategory, labelValue, labelColor, labelDefinition); } diff --git a/src/app/core/services/mocks/mock.issue.service.ts b/src/app/core/services/mocks/mock.issue.service.ts index 09868b073..268044dfc 100644 --- a/src/app/core/services/mocks/mock.issue.service.ts +++ b/src/app/core/services/mocks/mock.issue.service.ts @@ -78,9 +78,7 @@ export class MockIssueService { this.createAndSaveIssueModel(response); return this.issues[id]; }), - catchError((err) => { - return of(this.issues[id]); - }) + catchError((err) => of(this.issues[id])) ); } @@ -229,13 +227,7 @@ export class MockIssueService { * Obtain an observable containing an array of issues that are duplicates of the parentIssue. */ getDuplicateIssuesFor(parentIssue: Issue): Observable { - return this.issues$.pipe( - map((issues) => { - return issues.filter((issue) => { - return issue.duplicateOf === parentIssue.id; - }); - }) - ); + return this.issues$.pipe(map((issues) => issues.filter((issue) => issue.duplicateOf === parentIssue.id))); } reset() { diff --git a/src/app/core/services/phase.service.ts b/src/app/core/services/phase.service.ts index 3e5d8b221..f2799f0f1 100644 --- a/src/app/core/services/phase.service.ts +++ b/src/app/core/services/phase.service.ts @@ -125,13 +125,12 @@ export class PhaseService { sessionSetup(): Observable { // Permission Caching Mechanism to prevent repeating permission request. let isSessionFixPermissionGranted = false; - const cacheSessionFixPermission = () => { - return pipe( + const cacheSessionFixPermission = () => + pipe( tap((sessionFixPermission: boolean | null) => { isSessionFixPermissionGranted = sessionFixPermission ? sessionFixPermission : false; }) ); - }; return this.fetchSessionData().pipe( assertSessionDataIntegrity(), diff --git a/src/app/core/services/user.service.ts b/src/app/core/services/user.service.ts index 7e8eddf53..f6424796a 100644 --- a/src/app/core/services/user.service.ts +++ b/src/app/core/services/user.service.ts @@ -24,11 +24,7 @@ export class UserService { * Get the authenticated user if it exist. */ getAuthenticatedUser(): Observable { - return this.githubService.fetchAuthenticatedUser().pipe( - map((data: GithubUser) => { - return data; - }) - ); + return this.githubService.fetchAuthenticatedUser().pipe(map((data: GithubUser) => data)); } createUserModel(userLoginId: string): Observable { diff --git a/src/app/phase-team-response/issues-faulty/issues-faulty.component.ts b/src/app/phase-team-response/issues-faulty/issues-faulty.component.ts index 692222786..32966ca53 100644 --- a/src/app/phase-team-response/issues-faulty/issues-faulty.component.ts +++ b/src/app/phase-team-response/issues-faulty/issues-faulty.component.ts @@ -60,7 +60,7 @@ export class IssuesFaultyComponent implements OnInit, OnChanges { const hasTeamResponse = (issue: Issue) => this.issueService.hasTeamResponse(issue.id); const isDuplicateIssue = (issue: Issue) => !!issue.duplicateOf; const isDuplicatedBy = (issue: Issue) => - !!this.issueService.issues$.getValue().filter(childIssue => childIssue.duplicateOf === issue.id).length; + !!this.issueService.issues$.getValue().filter((childIssue) => childIssue.duplicateOf === issue.id).length; const isTransitiveDuplicate = hasTeamResponse(issue) && isDuplicateIssue(issue) && isDuplicatedBy(issue); const hasStatus = (issue: Issue) => !!issue.status; diff --git a/src/app/shared/comment-editor/upload-text-insertor.ts b/src/app/shared/comment-editor/upload-text-insertor.ts index ee317cace..e79ecc6dc 100644 --- a/src/app/shared/comment-editor/upload-text-insertor.ts +++ b/src/app/shared/comment-editor/upload-text-insertor.ts @@ -44,6 +44,7 @@ export function insertUploadUrlVideo( commentField: AbstractControl, commentTextArea: ElementRef ) { + // eslint-disable-next-line max-len const insertedString = `
video:${uploadUrl}
`; replacePlaceholderString(filename, insertedString, commentField, commentTextArea); diff --git a/src/app/shared/issue/description/description.component.ts b/src/app/shared/issue/description/description.component.ts index 38fac7c6d..5cc61562f 100644 --- a/src/app/shared/issue/description/description.component.ts +++ b/src/app/shared/issue/description/description.component.ts @@ -94,9 +94,7 @@ export class DescriptionComponent implements OnInit { this.issueService .getLatestIssue(this.issue.id) .pipe( - map((issue: Issue) => { - return issue.description === this.issue.description; - }), + map((issue: Issue) => issue.description === this.issue.description), mergeMap((isSaveToUpdate: boolean) => { if (isSaveToUpdate || this.submitButtonText === SUBMIT_BUTTON_TEXT.OVERWRITE) { return this.issueService.updateIssue(this.getUpdatedIssue()); diff --git a/src/app/shared/issue/duplicateOf/duplicate-of.component.ts b/src/app/shared/issue/duplicateOf/duplicate-of.component.ts index 553aab567..3f95ad1ce 100644 --- a/src/app/shared/issue/duplicateOf/duplicate-of.component.ts +++ b/src/app/shared/issue/duplicateOf/duplicate-of.component.ts @@ -136,19 +136,13 @@ export class DuplicateOfComponent implements OnInit, OnDestroy { private changeFilter(issuesObservable: Observable, searchInputString): Observable { return issuesObservable.pipe( first(), - map((issues) => { - return applySearchFilter(searchInputString, [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE], this.issueService, issues); - }) + map((issues) => applySearchFilter(searchInputString, [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE], this.issueService, issues)) ); } private getDupIssueList(): Observable { return this.issueService.issues$.pipe( - map((issues) => { - return issues.filter((issue) => { - return this.issue.id !== issue.id && this.issue.teamAssigned.id === issue.teamAssigned.id; - }); - }) + map((issues) => issues.filter((issue) => this.issue.id !== issue.id && this.issue.teamAssigned.id === issue.teamAssigned.id)) ); } } diff --git a/src/app/shared/lib/github-paginator-parser.ts b/src/app/shared/lib/github-paginator-parser.ts index 87f090c65..e4bdd5946 100644 --- a/src/app/shared/lib/github-paginator-parser.ts +++ b/src/app/shared/lib/github-paginator-parser.ts @@ -25,16 +25,16 @@ export function getNumberOfPages(response: GithubResponse): number { function githubPaginatorParser(linkStr: string) { return linkStr .split(',') - .map((paginateItem) => { - return paginateItem.split(';').map((curr, idx) => { + .map((paginateItem) => + paginateItem.split(';').map((curr, idx) => { if (idx === 0) { return /[^_]page=(\d+)/.exec(curr)[1]; } if (idx === 1) { return /rel="(.+)"/.exec(curr)[1]; } - }); - }) + }) + ) .reduce((obj, curr) => { obj[curr[1]] = curr[0]; return obj; diff --git a/src/app/shared/lib/marked.ts b/src/app/shared/lib/marked.ts index d4727dae1..f9ff6ba49 100644 --- a/src/app/shared/lib/marked.ts +++ b/src/app/shared/lib/marked.ts @@ -9,9 +9,7 @@ export function markedOptionsFactory(): MarkedOptions { return html.replace(/^ { - return checked ? ' ' : ' '; - }; + renderer.checkbox = (checked) => (checked ? ' ' : ' '); return { renderer, diff --git a/src/app/shared/view-issue/new-team-response/new-team-response.component.ts b/src/app/shared/view-issue/new-team-response/new-team-response.component.ts index fb3b7add6..2baa86669 100644 --- a/src/app/shared/view-issue/new-team-response/new-team-response.component.ts +++ b/src/app/shared/view-issue/new-team-response/new-team-response.component.ts @@ -49,9 +49,7 @@ export class NewTeamResponseComponent implements OnInit, OnDestroy { ) {} ngOnInit() { - this.teamMembers = this.issue.teamAssigned.teamMembers.map((member) => { - return member.loginId; - }); + this.teamMembers = this.issue.teamAssigned.teamMembers.map((member) => member.loginId); this.duplicatedIssueList = this.getDupIssueList(); // Populate the filtered list with all the issues first this.duplicatedIssueList.pipe(first()).subscribe((issues) => this.filteredDuplicateIssueList.next(issues)); @@ -88,9 +86,7 @@ export class NewTeamResponseComponent implements OnInit, OnDestroy { private changeFilter(issuesObservable: Observable, searchInputString): Observable { return issuesObservable.pipe( first(), - map((issues) => { - return applySearchFilter(searchInputString, [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE], this.issueService, issues); - }) + map((issues) => applySearchFilter(searchInputString, [TABLE_COLUMNS.ID, TABLE_COLUMNS.TITLE], this.issueService, issues)) ); } @@ -143,11 +139,7 @@ export class NewTeamResponseComponent implements OnInit, OnDestroy { * @return - Determines whether it is safe to submit a tester response. */ isSafeToSubmit(): Observable { - return this.issueService.getLatestIssue(this.issue.id).pipe( - map((issue: Issue) => { - return !issue.teamResponse; - }) - ); + return this.issueService.getLatestIssue(this.issue.id).pipe(map((issue: Issue) => !issue.teamResponse)); } /** @@ -209,13 +201,7 @@ export class NewTeamResponseComponent implements OnInit, OnDestroy { } private getDupIssueList(): Observable { - return this.issueService.issues$.pipe( - map((issues) => { - return issues.filter((issue) => { - return this.issue.id !== issue.id; - }); - }) - ); + return this.issueService.issues$.pipe(map((issues) => issues.filter((issue) => this.issue.id !== issue.id))); } get description() { diff --git a/src/app/shared/view-issue/team-response/team-response.component.ts b/src/app/shared/view-issue/team-response/team-response.component.ts index e2fdc5039..de5e12ba3 100644 --- a/src/app/shared/view-issue/team-response/team-response.component.ts +++ b/src/app/shared/view-issue/team-response/team-response.component.ts @@ -104,11 +104,7 @@ export class TeamResponseComponent implements OnInit { * @return - Determines whether it is safe to updated an existing team response. */ isSafeToUpdate(): Observable { - return this.issueService.getLatestIssue(this.issue.id).pipe( - map((issue: Issue) => { - return issue.teamResponse === this.issue.teamResponse; - }) - ); + return this.issueService.getLatestIssue(this.issue.id).pipe(map((issue: Issue) => issue.teamResponse === this.issue.teamResponse)); } /** diff --git a/src/app/shared/view-issue/tester-response/tester-response.component.ts b/src/app/shared/view-issue/tester-response/tester-response.component.ts index 4eb1a16b4..fe688b5bb 100644 --- a/src/app/shared/view-issue/tester-response/tester-response.component.ts +++ b/src/app/shared/view-issue/tester-response/tester-response.component.ts @@ -108,9 +108,10 @@ export class TesterResponseComponent implements OnInit, OnChanges { if (!issue.testerResponses) { return false; } - return issue.testerResponses.reduce((result, response, index) => { - return result && response.compareTo(this.issue.testerResponses[index]) === 0; - }, true); + return issue.testerResponses.reduce( + (result, response, index) => result && response.compareTo(this.issue.testerResponses[index]) === 0, + true + ); }) ); } diff --git a/src/typings.d.ts b/src/typings.d.ts index 6f504bd8c..535bac8d0 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -1,9 +1,11 @@ /* SystemJS module definition */ +// eslint-disable-next-line no-var -- Please revisit this eslint rule in the future declare var nodeModule: NodeModule; interface NodeModule { id: string; } +// eslint-disable-next-line no-var -- Please revisit this eslint rule in the future declare var window: Window & typeof globalThis; interface Window { process: any; diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 6c3e59124..000000000 --- a/tslint.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "extends": ["tslint-config-prettier"], - "rulesDirectory": ["node_modules/codelyzer"], - "linterOptions": { - "exclude": ["node_modules/*", "graphql/*", "dist/*"] - }, - "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "comment-format": [true, "check-space"], - "curly": true, - "deprecation": { - "severity": "warn" - }, - "eofline": true, - "forin": true, - "import-blacklist": [true, "rxjs/Rx"], - "import-spacing": true, - "indent": [true, "spaces", 2], - "label-position": true, - "max-line-length": [true, 140], - "member-access": false, - "member-ordering": [ - true, - { - "order": ["static-field", "instance-field", "static-method", "instance-method"] - } - ], - "no-arg": true, - "no-bitwise": true, - "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-misused-new": true, - "no-non-null-assertion": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], - "prefer-const": true, - "radix": true, - "semicolon": [true, "always"], - "triple-equals": [true, "allow-null-check"], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "unified-signatures": true, - "variable-name": false, - "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type", "check-module"], - "component-selector": [true, "element", "app", "kebab-case"], - "no-output-on-prefix": true, - "no-inputs-metadata-property": true, - "no-outputs-metadata-property": true, - "no-host-metadata-property": true, - "no-input-rename": true, - "no-output-rename": true, - "use-life-cycle-interface": true, - "use-pipe-transform-interface": true, - "component-class-suffix": true, - "directive-class-suffix": true, - "ordered-imports": true - } -}