From 5d540a0761e08f5bb9190ad664f2529e0fdf068a Mon Sep 17 00:00:00 2001 From: David Burke Date: Wed, 4 Jun 2025 13:29:03 -0400 Subject: [PATCH] Modernize angular bootstrap --- angular.json | 12 -- package-lock.json | 155 ------------------ package.json | 3 +- src/app/api/api-schema.d.ts | 56 +++---- src/app/api/issues/issues-api.service.ts | 11 +- .../api/user-reports/user-reports.service.ts | 4 +- .../event-detail/event-detail.component.ts | 7 - .../issue-detail/issue-detail.component.ts | 25 +-- .../issue-detail/issue-detail.service.ts | 115 +++++-------- .../teams/new-team/slugify.directive.ts | 2 +- src/environments/environment.prod.ts | 4 - src/environments/environment.ts | 1 - src/main.ts | 23 +-- tsconfig.app.json | 8 +- tsconfig.json | 9 +- 15 files changed, 102 insertions(+), 333 deletions(-) delete mode 100644 src/environments/environment.prod.ts diff --git a/angular.json b/angular.json index 4cc076d2..d7367a18 100644 --- a/angular.json +++ b/angular.json @@ -71,12 +71,6 @@ }, "configurations": { "prod-no-static": { - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], "outputHashing": "all" }, "production": { @@ -92,12 +86,6 @@ "maximumError": "6kb" } ], - "fileReplacements": [ - { - "replace": "src/environments/environment.ts", - "with": "src/environments/environment.prod.ts" - } - ], "optimization": { "styles": { "inlineCritical": false diff --git a/package-lock.json b/package-lock.json index 3e8d2a74..85416c06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,7 +91,6 @@ "ts-node": "~7.0.0", "typescript": "^5.8.2", "wait-on": "^5.3.0", - "webpack-bundle-analyzer": "^4.10.2", "xliff": "^6.2.1" } }, @@ -6553,13 +6552,6 @@ "node": ">=14" } }, - "node_modules/@polka/url": { - "version": "1.0.0-next.28", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", - "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", - "dev": true, - "license": "MIT" - }, "node_modules/@redocly/ajv": { "version": "8.11.2", "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", @@ -8652,19 +8644,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", @@ -11650,13 +11629,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true, - "license": "MIT" - }, "node_modules/debug": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", @@ -12016,13 +11988,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "license": "MIT" - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -13837,22 +13802,6 @@ "dev": true, "license": "MIT" }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/hachure-fill": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", @@ -17469,16 +17418,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -19816,21 +19755,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">= 10" - } - }, "node_modules/slice-ansi": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", @@ -21017,16 +20941,6 @@ "node": ">=0.6" } }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/tough-cookie": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", @@ -21758,75 +21672,6 @@ } } }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/webpack-dev-middleware": { "version": "7.4.2", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", diff --git a/package.json b/package.json index f230f0c0..268a8205 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "cy:openscreenshot": "cypress open --env screenshot=true", "cy:run": "cypress run", "e2e": "concurrently \"npm run start -- --no-hmr\" \"wait-on http-get://localhost:4200 && npm run cy:run\" --kill-others --success first", - "build-stats": "ng build --stats-json", + "build-stats": "ng build -c production --stats-json", "analyze": "webpack-bundle-analyzer dist/glitchtip-frontend/stats.json", "docs:json": "compodoc -p ./tsconfig.json -e json -d .", "extract-i18n": "ng extract-i18n", @@ -111,7 +111,6 @@ "ts-node": "~7.0.0", "typescript": "^5.8.2", "wait-on": "^5.3.0", - "webpack-bundle-analyzer": "^4.10.2", "xliff": "^6.2.1" }, "overrides": { diff --git a/src/app/api/api-schema.d.ts b/src/app/api/api-schema.d.ts index 4fa1ded2..d7110299 100644 --- a/src/app/api/api-schema.d.ts +++ b/src/app/api/api-schema.d.ts @@ -3017,10 +3017,10 @@ export interface components { /** Status */ status: string; project: components["schemas"]["ProjectReference"]; - /** Short Id */ - short_id: string; - /** Num Comments */ - num_comments: number; + /** Shortid */ + shortId: string; + /** Numcomments */ + numComments: number; /** * Stats * @default { @@ -3055,24 +3055,24 @@ export interface components { user_count: number | null; /** Matching Event Id */ matching_event_id?: string | null; + /** + * Firstseen + * Format: date-time + */ + firstSeen: string; + /** + * Lastseen + * Format: date-time + */ + lastSeen: string; /** Title */ title: string; /** Metadata */ metadata: Record; /** Culprit */ culprit?: string | null; - /** - * First Seen - * Format: date-time - */ - first_seen?: string; - /** - * Last Seen - * Format: date-time - */ - last_seen?: string; - /** User Report Count */ - user_report_count: number; + /** Userreportcount */ + userReportCount: number; }; /** ProjectReference */ ProjectReference: { @@ -3132,8 +3132,8 @@ export interface components { project: components["schemas"]["ProjectReference"]; /** Short Id Display */ short_id_display: string; - /** Numcomments */ - numComments: number; + /** Num Comments */ + num_comments: number; /** * Stats * @default { @@ -3168,22 +3168,22 @@ export interface components { userCount: number | null; /** Matchingeventid */ matchingEventId?: string | null; + /** + * First Seen + * Format: date-time + */ + first_seen: string; + /** + * Last Seen + * Format: date-time + */ + last_seen: string; /** Title */ title: string; /** Metadata */ metadata: Record; /** Culprit */ culprit?: string | null; - /** - * First Seen - * Format: date-time - */ - firstSeen?: string; - /** - * Last Seen - * Format: date-time - */ - lastSeen?: string; }; /** IssueTagSchema */ IssueTagSchema: { diff --git a/src/app/api/issues/issues-api.service.ts b/src/app/api/issues/issues-api.service.ts index d5e9a978..c76ca6c0 100644 --- a/src/app/api/issues/issues-api.service.ts +++ b/src/app/api/issues/issues-api.service.ts @@ -1,15 +1,13 @@ import { Injectable, inject } from "@angular/core"; import { HttpClient, HttpParams } from "@angular/common/http"; -import { EMPTY, map } from "rxjs"; +import { EMPTY } from "rxjs"; import { baseUrl } from "../../constants"; import { APIBaseService } from "../api-base.service"; import { - IssueDetail, IssueStatus, IssueTags, UpdateStatusResponse, } from "src/app/issues/interfaces"; -import { normalizeID } from "../shared-api.utils"; @Injectable({ providedIn: "root", @@ -31,12 +29,7 @@ export class IssuesAPIService extends APIBaseService { } retrieve(id: string) { - return this.http.get(this.detailURL(id)).pipe( - map((issueDetail) => { - issueDetail.project.id = normalizeID(issueDetail.project.id); - return issueDetail; - }), - ); + return EMPTY; } update(status: IssueStatus, orgSlug: string, id: number) { diff --git a/src/app/api/user-reports/user-reports.service.ts b/src/app/api/user-reports/user-reports.service.ts index b33f6734..bc168bd7 100644 --- a/src/app/api/user-reports/user-reports.service.ts +++ b/src/app/api/user-reports/user-reports.service.ts @@ -37,7 +37,7 @@ export class UserReportsService extends PaginationStatefulService { - this.issueService.setParams(this.issueID(), this.eventID()); - }); - } - /** TODO fix these types */ generateQuery(tag: { [key: string]: string | null }) { // Assume unresolved if not present; tag overrides query otherwise diff --git a/src/app/issues/issue-detail/issue-detail.component.ts b/src/app/issues/issue-detail/issue-detail.component.ts index cbfc88d3..16b47cef 100644 --- a/src/app/issues/issue-detail/issue-detail.component.ts +++ b/src/app/issues/issue-detail/issue-detail.component.ts @@ -5,6 +5,7 @@ import { inject, computed, input, + effect, } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; import { ActivatedRoute, RouterModule } from "@angular/router"; @@ -47,7 +48,7 @@ export class IssueDetailComponent implements OnInit { issue = this.issueService.issue; issueTitle = computed(() => { const issue = this.issue(); - if (issue === null || issue.metadata === null) { + if (!issue || issue.metadata === null) { return ["", null] as [string, string | null]; } const metadata = issue.metadata; @@ -75,23 +76,23 @@ export class IssueDetailComponent implements OnInit { return [metadata.title!, null] as [string, string | null]; } }); - issueSubtitle = computed(() => { + issueSubtitle = computed(() => { const issue = this.issue(); - if (issue === null || issue.metadata === null) { + if (!issue || issue.metadata === null) { return ""; } const metadata = issue.metadata; switch (issue.type) { case "error": - return metadata.value; + return metadata.value as string; case "csp": - return metadata.message; + return metadata.message as string; case "expectct": case "expectstaple": case "hpkp": return ""; default: - return issue.culprit; + return issue.culprit as string; } }); initialLoadComplete = this.issueService.issueInitialLoadComplete; @@ -99,6 +100,7 @@ export class IssueDetailComponent implements OnInit { assignee: new FormControl(""), }); issueID = input.required({ alias: "issue-id" }); + eventID = input(null, { alias: "event-id" }); organization = this.organizationsService.activeOrganization; participantCountPluralMapping: { [k: string]: string } = { "=0": "No Participants", @@ -106,11 +108,14 @@ export class IssueDetailComponent implements OnInit { other: "# Participants", }; + constructor() { + effect(() => { + this.issueService.setParams(this.issueID(), this.eventID()); + }); + } + ngOnInit() { this.issueService.clearState(); - const issueID = this.issueID(); - // Consider moving to effect once ported to resource - this.issueService.retrieveIssue(+issueID).toPromise(); } markResolved() { @@ -137,7 +142,7 @@ export class IssueDetailComponent implements OnInit { } } - generateBackLink(projectId: number) { + generateBackLink(projectId: string) { return { ...this.route.snapshot.queryParams, project: projectId, diff --git a/src/app/issues/issue-detail/issue-detail.service.ts b/src/app/issues/issue-detail/issue-detail.service.ts index f35db336..8a893404 100644 --- a/src/app/issues/issue-detail/issue-detail.service.ts +++ b/src/app/issues/issue-detail/issue-detail.service.ts @@ -1,11 +1,9 @@ -import { HttpErrorResponse } from "@angular/common/http"; import { Injectable, computed, inject, resource, signal } from "@angular/core"; import { Router } from "@angular/router"; import { MatSnackBar } from "@angular/material/snack-bar"; -import { EMPTY, lastValueFrom } from "rxjs"; -import { catchError, filter, take, tap, withLatestFrom } from "rxjs/operators"; +import { EMPTY } from "rxjs"; +import { catchError, tap, withLatestFrom } from "rxjs/operators"; import { - IssueDetail, IssueStatus, ExceptionValueData, Request, @@ -28,23 +26,18 @@ import { client } from "src/app/api/api"; import { components } from "src/app/api/api-schema"; type EventDetail = components["schemas"]["IssueEventDetailSchema"]; +type IssueDetail = components["schemas"]["IssueDetailSchema"]; interface IssueDetailState { - issue: IssueDetail | null; - issueLoading: boolean; - issueInitialLoadComplete: boolean; tags: IssueTags[] | null; isReversed: boolean; showShowMore: boolean; } const initialState: IssueDetailState = { - issue: null, tags: null, isReversed: true, showShowMore: false, - issueLoading: false, - issueInitialLoadComplete: false, }; @Injectable({ @@ -56,9 +49,9 @@ export class IssueDetailService extends StatefulService { private snackBar = inject(MatSnackBar); private router = inject(Router); - readonly issue = computed(() => this.state().issue); - readonly issueInitialLoadComplete = computed( - () => this.state().issueInitialLoadComplete, + readonly issue = computed(() => this.#issueResource.value()); + readonly issueInitialLoadComplete = computed(() => + this.#issueResource.hasValue(), ); readonly event = computed(() => this.#eventResource.value()); readonly tags = computed(() => { @@ -82,7 +75,7 @@ export class IssueDetailService extends StatefulService { const event = this.event(); if (event && event.nextEventID) { - return this.eventUrl(orgSlug, issue, event.nextEventID); + return this.eventUrl(orgSlug, issue!, event.nextEventID); } return null; }); @@ -92,7 +85,7 @@ export class IssueDetailService extends StatefulService { const event = this.event(); if (event && event.previousEventID) { - return this.eventUrl(orgSlug, issue, event.previousEventID); + return this.eventUrl(orgSlug, issue!, event.previousEventID); } return null; }); @@ -131,6 +124,18 @@ export class IssueDetailService extends StatefulService { issueID: "", eventID: "", }); + #issueResource = resource({ + params: () => ({ issueID: this.#params().issueID }), + loader: async ({ params }) => { + if (!params.issueID) { + return; + } + const { data } = await client.GET("/api/0/issues/{issue_id}/", { + params: { path: { issue_id: parseInt(params.issueID) } }, + }); + return data; + }, + }); #eventResource = resource({ params: () => ({ params: this.#params() }), loader: async ({ params }) => { @@ -164,27 +169,6 @@ export class IssueDetailService extends StatefulService { super(initialState); } - retrieveIssue(id: number) { - this.setState({ issueLoading: true }); - return this.issuesAPIService.retrieve(id.toString()).pipe( - tap((issue) => this.setIssue(issue)), - catchError((error) => { - if (error instanceof HttpErrorResponse && error.status === 404) { - this.clearIssue(); - } - return EMPTY; - }), - ); - } - - setIssue(issue: IssueDetail) { - this.setState({ - issue, - issueLoading: false, - issueInitialLoadComplete: true, - }); - } - setParams(issueID: string, eventID: string | null) { this.#params.set({ issueID, eventID }); } @@ -205,24 +189,24 @@ export class IssueDetailService extends StatefulService { this.setState({ showShowMore: value }); } - setStatus(status: IssueStatus) { - const issue = this.state().issue; + async setStatus(status: IssueStatus) { + const issue = this.issue(); if (issue) { - lastValueFrom( - this.organization.activeOrganizationSlug$.pipe( - filter((slug) => !!slug), - take(1), - tap((slug) => { - if (slug) { - lastValueFrom( - this.issuesAPIService - .update(status, slug, issue.id) - .pipe(tap((resp) => this.setIssueStatus(resp.status))), - ); - } - }), - ), + const { data } = await client.PUT( + "/api/0/organizations/{organization_slug}/issues/{issue_id}/", + { + params: { + path: { + organization_slug: this.organization.activeOrganizationSlug(), + issue_id: parseInt(this.#params().issueID), + }, + }, + body: { status: status as any }, + }, ); + if (data) { + this.setIssueStatus(data.status as IssueStatus); + } } } @@ -287,31 +271,14 @@ export class IssueDetailService extends StatefulService { /** Set local state issue state */ private setIssueStatus(status: IssueStatus) { - const state = this.state(); - if (state.issue) { - const issue = { ...state.issue, status }; - this.setState({ issue }); - } - } - - private clearIssue() { - this.setState({ - issue: null, - issueLoading: false, - issueInitialLoadComplete: true, - }); + this.#issueResource.update((issue) => ({ ...issue!, status })); } private setUpdatedCommentCount(num: number) { - const state = this.state(); - if (state.issue) { - this.setState({ - issue: { - ...state.issue, - numComments: state.issue.numComments + num, - }, - }); - } + this.#issueResource.update((issue) => ({ + ...issue!, + numComments: issue!.numComments + num, + })); } setTags(tags: IssueTags[]) { diff --git a/src/app/settings/teams/new-team/slugify.directive.ts b/src/app/settings/teams/new-team/slugify.directive.ts index 195c1bfe..4057328e 100644 --- a/src/app/settings/teams/new-team/slugify.directive.ts +++ b/src/app/settings/teams/new-team/slugify.directive.ts @@ -15,7 +15,7 @@ export class SlugifyDirective { return true; } - @HostListener("paste", ["$event"]) blockPaste(event: KeyboardEvent) { + @HostListener("paste", ["$event"]) blockPaste(event: ClipboardEvent) { this.validateFields(); } diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts deleted file mode 100644 index 8694761b..00000000 --- a/src/environments/environment.prod.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const environment = { - production: true, - billingEmail: "sales@glitchtip.com", -}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 2afe1fbc..b5545acf 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,6 +3,5 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false, billingEmail: "sales@glitchtip.com", }; diff --git a/src/main.ts b/src/main.ts index 7b3d79ec..05cec15c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,21 +1,14 @@ import { - enableProdMode, ErrorHandler, - importProvidersFrom, inject, provideZonelessChangeDetection, Provider, } from "@angular/core"; import { loadTranslations } from "@angular/localize"; -import { environment } from "./environments/environment"; import { AppComponent } from "./app/app.component"; -import { MicroSentryModule } from "@micro-sentry/angular"; -import { - MAT_SNACK_BAR_DEFAULT_OPTIONS, - MatSnackBarModule, -} from "@angular/material/snack-bar"; -import { provideAnimationsAsync } from "@angular/platform-browser/animations/async"; +import { provideMicroSentry } from "@micro-sentry/angular"; +import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from "@angular/material/snack-bar"; import { routes, TemplatePageTitleStrategy } from "./app/app.routes"; import { bootstrapApplication } from "@angular/platform-browser"; import { LessAnnoyingErrorStateMatcher } from "./app/shared/less-annoying-error-state-matcher"; @@ -50,10 +43,6 @@ if (window.Cypress) { } const serverErrorsRegex = new RegExp(`403 Forbidden|404 OK`, "mi"); -if (environment.production) { - enableProdMode(); -} - // First locale is default, add additional after it const availableLocales = ["en", "fr", "nb"]; // Direct macrolanguages to specific ones. Example: Norwegian becomes Bokmål @@ -108,10 +97,9 @@ const bootstrap = () => }), ), provideMarkdown(), - importProvidersFrom( - MatSnackBarModule, - MicroSentryModule.forRoot({ ignoreErrors: [serverErrorsRegex] }), - ), + provideMicroSentry({ + ignoreErrors: [serverErrorsRegex], + }), { provide: MAT_SNACK_BAR_DEFAULT_OPTIONS, useValue: { duration: snackBarDuration }, @@ -122,7 +110,6 @@ const bootstrap = () => provide: ErrorStateMatcher, useClass: LessAnnoyingErrorStateMatcher, }, - provideAnimationsAsync(), provideHttpClient( withFetch(), withXsrfConfiguration({ diff --git a/tsconfig.app.json b/tsconfig.app.json index 1e248f43..d6312d15 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -4,12 +4,8 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - ], - "include": [ - "src/**/*.d.ts" - ], + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], "exclude": [ "src/test.ts", "src/**/*.spec.ts", diff --git a/tsconfig.json b/tsconfig.json index ddcb0ad7..cee34cbc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "declaration": false, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, - "module": "ES2022", + "module": "preserve", "moduleResolution": "bundler", "noUnusedLocals": true, "noImplicitReturns": true, @@ -25,8 +25,9 @@ }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, - "fullTemplateTypeCheck": true, - "strictTemplates": true, - "strictInjectionParameters": true + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "typeCheckHostBindings": true, + "strictTemplates": true } }