Repository: gitify-app/gitify
Pull request #1321 (2024-06-28 15:16:52)

feat: reset to default settings
Add a `reset default settings` option.  Of increasing usefulness as we've been adding, and may continue to add more settings in future.

<img width="502" alt="Screenshot 2024-06-28 at 8 14 28 AM" src="https://github.com/gitify-app/gitify/assets/386277/dd11531f-ed8a-45b3-86cd-6432f79300a6">


bmulholland: I perceive that icon as "undo my last change," not "undo all changes, ever." I could, therefore, click it and get effective data loss without intending...
setchy: Is there an alternative icon you'd propose - https://primer.style/foundations/icons?

Would there be a different location you'd prefer? 

I figured the hover text was enough 🤷‍♂️
afonsojramos: I'd argue more against the feature, than the icon itself. Why would we want this?

(But if we really want this, I'd say actual text aligned to the right saying "Reset to defaults \*currentUndoIconHere\*")

Patch:
diff --git a/package.json b/package.json
index ca31bf4c..c7c7f7e2 100644
--- a/package.json
+++ b/package.json
@@ -112,9 +112,9 @@
     "react": "18.3.1",
     "react-dom": "18.3.1",
     "react-final-form": "6.5.9",
-    "react-router-dom": "6.24.0",
+    "react-router-dom": "6.24.1",
     "ts-loader": "9.5.1",
-    "typescript": "5.5.2"
+    "typescript": "5.5.3"
   },
   "devDependencies": {
     "@biomejs/biome": "1.8.3",
@@ -143,7 +143,7 @@
     "ts-node": "10.9.2",
     "webpack": "5.92.1",
     "webpack-cli": "5.1.4",
-    "webpack-merge": "5.10.0"
+    "webpack-merge": "6.0.1"
   },
   "packageManager": "pnpm@9.4.0",
   "lint-staged": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0581cb2a..8b018a94 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -45,14 +45,14 @@ importers:
         specifier: 6.5.9
         version: 6.5.9(final-form@4.20.10)(react@18.3.1)
       react-router-dom:
-        specifier: 6.24.0
-        version: 6.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+        specifier: 6.24.1
+        version: 6.24.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
       ts-loader:
         specifier: 9.5.1
-        version: 9.5.1(typescript@5.5.2)(webpack@5.92.1(webpack-cli@5.1.4))
+        version: 9.5.1(typescript@5.5.3)(webpack@5.92.1(webpack-cli@5.1.4))
       typescript:
-        specifier: 5.5.2
-        version: 5.5.2
+        specifier: 5.5.3
+        version: 5.5.3
     devDependencies:
       '@biomejs/biome':
         specifier: 1.8.3
@@ -98,7 +98,7 @@ importers:
         version: 9.0.11
       jest:
         specifier: 29.7.0
-        version: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+        version: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       jest-environment-jsdom:
         specifier: 29.7.0
         version: 29.7.0
@@ -110,7 +110,7 @@ importers:
         version: 8.4.39
       postcss-loader:
         specifier: 8.1.1
-        version: 8.1.1(postcss@8.4.39)(typescript@5.5.2)(webpack@5.92.1(webpack-cli@5.1.4))
+        version: 8.1.1(postcss@8.4.39)(typescript@5.5.3)(webpack@5.92.1(webpack-cli@5.1.4))
       rimraf:
         specifier: 5.0.7
         version: 5.0.7
@@ -119,13 +119,13 @@ importers:
         version: 4.0.0(webpack@5.92.1(webpack-cli@5.1.4))
       tailwindcss:
         specifier: 3.4.4
-        version: 3.4.4(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+        version: 3.4.4(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       ts-jest:
         specifier: 29.1.5
-        version: 29.1.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)))(typescript@5.5.2)
+        version: 29.1.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)))(typescript@5.5.3)
       ts-node:
         specifier: 10.9.2
-        version: 10.9.2(@types/node@20.14.9)(typescript@5.5.2)
+        version: 10.9.2(@types/node@20.14.9)(typescript@5.5.3)
       webpack:
         specifier: 5.92.1
         version: 5.92.1(webpack-cli@5.1.4)
@@ -133,8 +133,8 @@ importers:
         specifier: 5.1.4
         version: 5.1.4(webpack@5.92.1)
       webpack-merge:
-        specifier: 5.10.0
-        version: 5.10.0
+        specifier: 6.0.1
+        version: 6.0.1
 
 packages:
 
@@ -548,8 +548,8 @@ packages:
     peerDependencies:
       react: '>=16.3'
 
-  '@remix-run/router@1.17.0':
-    resolution: {integrity: sha512-2D6XaHEVvkCn682XBnipbJjgZUU7xjLtA4dGJRBVUKpEaDYOZMENZoZjAOSb7qirxt5RupjzZxz4fK2FO+EFPw==}
+  '@remix-run/router@1.17.1':
+    resolution: {integrity: sha512-mCOMec4BKd6BRGBZeSnGiIgwsbLGp3yhVqAD8H+PxiRNEHgDpZb8J1TnrSDlg97t0ySKMQJTHCWBCmBpSmkF6Q==}
     engines: {node: '>=14.0.0'}
 
   '@sinclair/typebox@0.27.8':
@@ -2530,15 +2530,15 @@ packages:
   react-is@18.2.0:
     resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
 
-  react-router-dom@6.24.0:
-    resolution: {integrity: sha512-960sKuau6/yEwS8e+NVEidYQb1hNjAYM327gjEyXlc6r3Skf2vtwuJ2l7lssdegD2YjoKG5l8MsVyeTDlVeY8g==}
+  react-router-dom@6.24.1:
+    resolution: {integrity: sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
       react: '>=16.8'
       react-dom: '>=16.8'
 
-  react-router@6.24.0:
-    resolution: {integrity: sha512-sQrgJ5bXk7vbcC4BxQxeNa5UmboFm35we1AFK0VvQaz9g0LzxEIuLOhHIoZ8rnu9BO21ishGeL9no1WB76W/eg==}
+  react-router@6.24.1:
+    resolution: {integrity: sha512-PTXFXGK2pyXpHzVo3rR9H7ip4lSPZZc0bHG5CARmj65fTT6qG7sTngmb6lcYu1gf3y/8KxORoy9yn59pGpCnpg==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
       react: '>=16.8'
@@ -2962,8 +2962,8 @@ packages:
     resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
     engines: {node: '>=10'}
 
-  typescript@5.5.2:
-    resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==}
+  typescript@5.5.3:
+    resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==}
     engines: {node: '>=14.17'}
     hasBin: true
 
@@ -3047,6 +3047,10 @@ packages:
     resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==}
     engines: {node: '>=10.0.0'}
 
+  webpack-merge@6.0.1:
+    resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==}
+    engines: {node: '>=18.0.0'}
+
   webpack-sources@3.2.3:
     resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
     engines: {node: '>=10.13.0'}
@@ -3509,7 +3513,7 @@ snapshots:
       jest-util: 29.7.0
       slash: 3.0.0
 
-  '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))':
+  '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))':
     dependencies:
       '@jest/console': 29.7.0
       '@jest/reporters': 29.7.0
@@ -3523,7 +3527,7 @@ snapshots:
       exit: 0.1.2
       graceful-fs: 4.2.11
       jest-changed-files: 29.7.0
-      jest-config: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      jest-config: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       jest-haste-map: 29.7.0
       jest-message-util: 29.7.0
       jest-regex-util: 29.6.3
@@ -3721,7 +3725,7 @@ snapshots:
     dependencies:
       react: 18.3.1
 
-  '@remix-run/router@1.17.0': {}
+  '@remix-run/router@1.17.1': {}
 
   '@sinclair/typebox@0.27.8': {}
 
@@ -4453,7 +4457,7 @@ snapshots:
   config-file-ts@0.2.6:
     dependencies:
       glob: 10.3.10
-      typescript: 5.5.2
+      typescript: 5.5.3
 
   convert-source-map@2.0.0: {}
 
@@ -4462,14 +4466,14 @@ snapshots:
 
   core-util-is@1.0.3: {}
 
-  cosmiconfig@9.0.0(typescript@5.5.2):
+  cosmiconfig@9.0.0(typescript@5.5.3):
     dependencies:
       env-paths: 2.2.1
       import-fresh: 3.3.0
       js-yaml: 4.1.0
       parse-json: 5.2.0
     optionalDependencies:
-      typescript: 5.5.2
+      typescript: 5.5.3
 
   crc-32@1.2.2: {}
 
@@ -4483,13 +4487,13 @@ snapshots:
       buffer: 5.7.1
     optional: true
 
-  create-jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)):
+  create-jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)):
     dependencies:
       '@jest/types': 29.6.3
       chalk: 4.1.2
       exit: 0.1.2
       graceful-fs: 4.2.11
-      jest-config: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      jest-config: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       jest-util: 29.7.0
       prompts: 2.4.2
     transitivePeerDependencies:
@@ -5220,16 +5224,16 @@ snapshots:
       - babel-plugin-macros
       - supports-color
 
-  jest-cli@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)):
+  jest-cli@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)):
     dependencies:
-      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       '@jest/test-result': 29.7.0
       '@jest/types': 29.6.3
       chalk: 4.1.2
-      create-jest: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      create-jest: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       exit: 0.1.2
       import-local: 3.1.0
-      jest-config: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      jest-config: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       jest-util: 29.7.0
       jest-validate: 29.7.0
       yargs: 17.7.2
@@ -5239,7 +5243,7 @@ snapshots:
       - supports-color
       - ts-node
 
-  jest-config@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)):
+  jest-config@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)):
     dependencies:
       '@babel/core': 7.24.3
       '@jest/test-sequencer': 29.7.0
@@ -5265,7 +5269,7 @@ snapshots:
       strip-json-comments: 3.1.1
     optionalDependencies:
       '@types/node': 20.14.9
-      ts-node: 10.9.2(@types/node@20.14.9)(typescript@5.5.2)
+      ts-node: 10.9.2(@types/node@20.14.9)(typescript@5.5.3)
     transitivePeerDependencies:
       - babel-plugin-macros
       - supports-color
@@ -5506,12 +5510,12 @@ snapshots:
       merge-stream: 2.0.0
       supports-color: 8.1.1
 
-  jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)):
+  jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)):
     dependencies:
-      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       '@jest/types': 29.6.3
       import-local: 3.1.0
-      jest-cli: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      jest-cli: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
     transitivePeerDependencies:
       - '@types/node'
       - babel-plugin-macros
@@ -5858,17 +5862,17 @@ snapshots:
       camelcase-css: 2.0.1
       postcss: 8.4.39
 
-  postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)):
+  postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)):
     dependencies:
       lilconfig: 3.1.1
       yaml: 2.4.1
     optionalDependencies:
       postcss: 8.4.39
-      ts-node: 10.9.2(@types/node@20.14.9)(typescript@5.5.2)
+      ts-node: 10.9.2(@types/node@20.14.9)(typescript@5.5.3)
 
-  postcss-loader@8.1.1(postcss@8.4.39)(typescript@5.5.2)(webpack@5.92.1(webpack-cli@5.1.4)):
+  postcss-loader@8.1.1(postcss@8.4.39)(typescript@5.5.3)(webpack@5.92.1(webpack-cli@5.1.4)):
     dependencies:
-      cosmiconfig: 9.0.0(typescript@5.5.2)
+      cosmiconfig: 9.0.0(typescript@5.5.3)
       jiti: 1.21.0
       postcss: 8.4.39
       semver: 7.6.0
@@ -5983,16 +5987,16 @@ snapshots:
 
   react-is@18.2.0: {}
 
-  react-router-dom@6.24.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+  react-router-dom@6.24.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
     dependencies:
-      '@remix-run/router': 1.17.0
+      '@remix-run/router': 1.17.1
       react: 18.3.1
       react-dom: 18.3.1(react@18.3.1)
-      react-router: 6.24.0(react@18.3.1)
+      react-router: 6.24.1(react@18.3.1)
 
-  react-router@6.24.0(react@18.3.1):
+  react-router@6.24.1(react@18.3.1):
     dependencies:
-      '@remix-run/router': 1.17.0
+      '@remix-run/router': 1.17.1
       react: 18.3.1
 
   react@18.3.1:
@@ -6268,7 +6272,7 @@ snapshots:
 
   symbol-tree@3.2.4: {}
 
-  tailwindcss@3.4.4(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)):
+  tailwindcss@3.4.4(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)):
     dependencies:
       '@alloc/quick-lru': 5.2.0
       arg: 5.0.2
@@ -6287,7 +6291,7 @@ snapshots:
       postcss: 8.4.39
       postcss-import: 15.1.0(postcss@8.4.39)
       postcss-js: 4.0.1(postcss@8.4.39)
-      postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       postcss-nested: 6.0.1(postcss@8.4.39)
       postcss-selector-parser: 6.0.16
       resolve: 1.22.8
@@ -6382,17 +6386,17 @@ snapshots:
 
   ts-interface-checker@0.1.13: {}
 
-  ts-jest@29.1.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2)))(typescript@5.5.2):
+  ts-jest@29.1.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3)))(typescript@5.5.3):
     dependencies:
       bs-logger: 0.2.6
       fast-json-stable-stringify: 2.1.0
-      jest: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2))
+      jest: 29.7.0(@types/node@20.14.9)(ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3))
       jest-util: 29.7.0
       json5: 2.2.3
       lodash.memoize: 4.1.2
       make-error: 1.3.6
       semver: 7.6.0
-      typescript: 5.5.2
+      typescript: 5.5.3
       yargs-parser: 21.1.1
     optionalDependencies:
       '@babel/core': 7.24.3
@@ -6400,17 +6404,17 @@ snapshots:
       '@jest/types': 29.6.3
       babel-jest: 29.7.0(@babel/core@7.24.3)
 
-  ts-loader@9.5.1(typescript@5.5.2)(webpack@5.92.1(webpack-cli@5.1.4)):
+  ts-loader@9.5.1(typescript@5.5.3)(webpack@5.92.1(webpack-cli@5.1.4)):
     dependencies:
       chalk: 4.1.2
       enhanced-resolve: 5.16.0
       micromatch: 4.0.5
       semver: 7.6.0
       source-map: 0.7.4
-      typescript: 5.5.2
+      typescript: 5.5.3
       webpack: 5.92.1(webpack-cli@5.1.4)
 
-  ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.2):
+  ts-node@10.9.2(@types/node@20.14.9)(typescript@5.5.3):
     dependencies:
       '@cspotcode/source-map-support': 0.8.1
       '@tsconfig/node10': 1.0.11
@@ -6424,7 +6428,7 @@ snapshots:
       create-require: 1.1.1
       diff: 4.0.2
       make-error: 1.3.6
-      typescript: 5.5.2
+      typescript: 5.5.3
       v8-compile-cache-lib: 3.0.1
       yn: 3.1.1
 
@@ -6437,7 +6441,7 @@ snapshots:
 
   type-fest@0.21.3: {}
 
-  typescript@5.5.2: {}
+  typescript@5.5.3: {}
 
   undici-types@5.26.5: {}
 
@@ -6519,6 +6523,12 @@ snapshots:
       flat: 5.0.2
       wildcard: 2.0.1
 
+  webpack-merge@6.0.1:
+    dependencies:
+      clone-deep: 4.0.1
+      flat: 5.0.2
+      wildcard: 2.0.1
+
   webpack-sources@3.2.3: {}
 
   webpack@5.92.1(webpack-cli@5.1.4):
diff --git a/src/app.tsx b/src/app.tsx
index 843b5ccc..ba4c4e72 100644
--- a/src/app.tsx
+++ b/src/app.tsx
@@ -32,7 +32,7 @@ export const App = () => {
   return (
     <AppProvider>
       <Router>
-        <div className="flex h-full flex-col pl-14">
+        <div className="flex h-full overflow-y-auto flex-col pl-14">
           <Loading />
           <Sidebar />
           <Routes>
diff --git a/src/components/settings/AppearanceSettings.tsx b/src/components/settings/AppearanceSettings.tsx
index 4efd9134..8c6825e4 100644
--- a/src/components/settings/AppearanceSettings.tsx
+++ b/src/components/settings/AppearanceSettings.tsx
@@ -25,7 +25,7 @@ export const AppearanceSettings: FC = () => {
   }, [settings.theme]);
 
   return (
-    <fieldset className="mb-3">
+    <fieldset>
       <legend id="appearance" className="mb-1 mt-2 font-semibold">
         Appearance
       </legend>
diff --git a/src/components/settings/NotificationSettings.tsx b/src/components/settings/NotificationSettings.tsx
index c0880c22..2913c4fe 100644
--- a/src/components/settings/NotificationSettings.tsx
+++ b/src/components/settings/NotificationSettings.tsx
@@ -9,7 +9,7 @@ export const NotificationSettings: FC = () => {
   const { settings, updateSetting } = useContext(AppContext);
 
   return (
-    <fieldset className="mb-3">
+    <fieldset>
       <legend id="notifications" className="mb-1 mt-2 font-semibold">
         Notifications
       </legend>
diff --git a/src/components/settings/SystemSettings.tsx b/src/components/settings/SystemSettings.tsx
index 44e7a936..c121b278 100644
--- a/src/components/settings/SystemSettings.tsx
+++ b/src/components/settings/SystemSettings.tsx
@@ -8,7 +8,7 @@ export const SystemSettings: FC = () => {
   const { settings, updateSetting } = useContext(AppContext);
 
   return (
-    <fieldset className="mb-3">
+    <fieldset>
       <legend id="system" className="mb-1 mt-2 font-semibold">
         System
       </legend>
diff --git a/src/context/App.tsx b/src/context/App.tsx
index 986ea2a2..05ac5594 100644
--- a/src/context/App.tsx
+++ b/src/context/App.tsx
@@ -96,8 +96,9 @@ interface AppContextState {
   markRepoNotificationsDone: (notification: Notification) => Promise<void>;
 
   settings: SettingsState;
-  updateSetting: (name: keyof SettingsState, value: SettingsValue) => void;
   clearFilters: () => void;
+  resetSettings: () => void;
+  updateSetting: (name: keyof SettingsState, value: SettingsValue) => void;
 }
 
 export const AppContext = createContext<Partial<AppContextState>>({});
@@ -149,6 +150,17 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
     setKeyboardShortcut(settings.keyboardShortcut);
   }, [settings.keyboardShortcut]);
 
+  const clearFilters = useCallback(() => {
+    const newSettings = { ...settings, ...defaultFilters };
+    setSettings(newSettings);
+    saveState({ auth, settings: newSettings });
+  }, [auth]);
+
+  const resetSettings = useCallback(() => {
+    setSettings(defaultSettings);
+    saveState({ auth, settings: defaultSettings });
+  }, [auth]);
+
   const updateSetting = useCallback(
     (name: keyof SettingsState, value: SettingsValue) => {
       if (name === 'openAtStartup') {
@@ -162,12 +174,6 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
     [auth, settings],
   );
 
-  const clearFilters = useCallback(() => {
-    const newSettings = { ...settings, ...defaultFilters };
-    setSettings(newSettings);
-    saveState({ auth, settings: newSettings });
-  }, [auth]);
-
   const isLoggedIn = useMemo(() => {
     return auth.accounts.length > 0;
   }, [auth]);
@@ -299,8 +305,9 @@ export const AppProvider = ({ children }: { children: ReactNode }) => {
         markRepoNotificationsDone: markRepoNotificationsDoneWithAccounts,
 
         settings,
-        updateSetting,
         clearFilters,
+        resetSettings,
+        updateSetting,
       }}
     >
       {children}
diff --git a/src/routes/Settings.tsx b/src/routes/Settings.tsx
index 878a6e1d..5cc98ed4 100644
--- a/src/routes/Settings.tsx
+++ b/src/routes/Settings.tsx
@@ -1,19 +1,31 @@
-import type { FC } from 'react';
+import { type FC, useContext } from 'react';
 import { Header } from '../components/Header';
 import { AppearanceSettings } from '../components/settings/AppearanceSettings';
 import { NotificationSettings } from '../components/settings/NotificationSettings';
 import { SettingsFooter } from '../components/settings/SettingsFooter';
 import { SystemSettings } from '../components/settings/SystemSettings';
+import { AppContext } from '../context/App';
 
 export const SettingsRoute: FC = () => {
+  const { resetSettings } = useContext(AppContext);
   return (
     <div className="flex h-screen flex-col" data-testid="settings">
       <Header fetchOnBack={true}>Settings</Header>
 
-      <div className="flex-grow overflow-x-auto px-8">
+      <div className="flex flex-col flex-grow overflow-x-auto px-8 gap-3">
         <AppearanceSettings />
         <NotificationSettings />
         <SystemSettings />
+        <button
+          type="button"
+          onClick={() => {
+            confirm('Are you sure you want to reset all settings?') &&
+              resetSettings();
+          }}
+          className="text-sm hover:underline mb-4 hover:cursor-pointer"
+        >
+          Restore settings to their defaults
+        </button>
       </div>
 
       <SettingsFooter />


Test patch:
diff --git a/src/context/App.test.tsx b/src/context/App.test.tsx
index 0a9f368a..415aac0b 100644
--- a/src/context/App.test.tsx
+++ b/src/context/App.test.tsx
@@ -475,5 +475,37 @@ describe('context/App.tsx', () => {
         },
       });
     });
+
+    it('should call resetSettings', async () => {
+      const saveStateMock = jest
+        .spyOn(storage, 'saveState')
+        .mockImplementation(jest.fn());
+
+      const TestComponent = () => {
+        const { resetSettings } = useContext(AppContext);
+
+        return (
+          <button type="button" onClick={() => resetSettings()}>
+            Test Case
+          </button>
+        );
+      };
+
+      const { getByText } = customRender(<TestComponent />);
+
+      act(() => {
+        fireEvent.click(getByText('Test Case'));
+      });
+
+      expect(saveStateMock).toHaveBeenCalledWith({
+        auth: {
+          accounts: [],
+          enterpriseAccounts: [],
+          token: null,
+          user: null,
+        } as AuthState,
+        settings: defaultSettings,
+      });
+    });
   });
 });
diff --git a/src/routes/Settings.test.tsx b/src/routes/Settings.test.tsx
index 962984fa..6b645ae8 100644
--- a/src/routes/Settings.test.tsx
+++ b/src/routes/Settings.test.tsx
@@ -14,6 +14,7 @@ jest.mock('react-router-dom', () => ({
 describe('routes/Settings.tsx', () => {
   let originalPlatform: NodeJS.Platform;
   const fetchNotifications = jest.fn();
+  const resetSettings = jest.fn();
 
   beforeAll(() => {
     // Save the original platform value
@@ -72,4 +73,50 @@ describe('routes/Settings.tsx', () => {
     expect(fetchNotifications).toHaveBeenCalledTimes(1);
     expect(mockNavigate).toHaveBeenNthCalledWith(1, -1);
   });
+
+  it('should reset default settings when `OK`', async () => {
+    window.confirm = jest.fn(() => true); // always click 'OK'
+
+    await act(async () => {
+      render(
+        <AppContext.Provider
+          value={{
+            auth: mockAuth,
+            settings: mockSettings,
+            resetSettings,
+          }}
+        >
+          <MemoryRouter>
+            <SettingsRoute />
+          </MemoryRouter>
+        </AppContext.Provider>,
+      );
+    });
+
+    fireEvent.click(screen.getByText('Restore settings to their defaults'));
+    expect(resetSettings).toHaveBeenCalled();
+  });
+
+  it('should skip reset default settings when `cancelled`', async () => {
+    window.confirm = jest.fn(() => false); // always click 'cancel'
+
+    await act(async () => {
+      render(
+        <AppContext.Provider
+          value={{
+            auth: mockAuth,
+            settings: mockSettings,
+            resetSettings,
+          }}
+        >
+          <MemoryRouter>
+            <SettingsRoute />
+          </MemoryRouter>
+        </AppContext.Provider>,
+      );
+    });
+
+    fireEvent.click(screen.getByText('Restore settings to their defaults'));
+    expect(resetSettings).not.toHaveBeenCalled();
+  });
 });
diff --git a/src/routes/__snapshots__/Settings.test.tsx.snap b/src/routes/__snapshots__/Settings.test.tsx.snap
index 83afa974..f52fe819 100644
--- a/src/routes/__snapshots__/Settings.test.tsx.snap
+++ b/src/routes/__snapshots__/Settings.test.tsx.snap
@@ -36,11 +36,9 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
     </h3>
   </div>
   <div
-    class="flex-grow overflow-x-auto px-8"
+    class="flex flex-col flex-grow overflow-x-auto px-8 gap-3"
   >
-    <fieldset
-      class="mb-3"
-    >
+    <fieldset>
       <legend
         class="mb-1 mt-2 font-semibold"
         id="appearance"
@@ -247,9 +245,7 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
         </div>
       </div>
     </fieldset>
-    <fieldset
-      class="mb-3"
-    >
+    <fieldset>
       <legend
         class="mb-1 mt-2 font-semibold"
         id="notifications"
@@ -437,9 +433,7 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
         </div>
       </div>
     </fieldset>
-    <fieldset
-      class="mb-3"
-    >
+    <fieldset>
       <legend
         class="mb-1 mt-2 font-semibold"
         id="system"
@@ -605,6 +599,12 @@ exports[`routes/Settings.tsx should render itself & its children 1`] = `
         </div>
       </div>
     </fieldset>
+    <button
+      class="text-sm hover:underline mb-4 hover:cursor-pointer"
+      type="button"
+    >
+      Restore settings to their defaults
+    </button>
   </div>
   <div
     class="flex items-center justify-between bg-gray-200 px-8 py-1 text-sm dark:bg-gray-darker"