From eefd442aca9de5c16b6c80ccf9d31c4302da5ff2 Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 12 Oct 2024 20:25:14 -0700 Subject: [PATCH 01/14] Move tags field into optional fields expandable section --- src/features/todos/components/TodoForm.svelte | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/features/todos/components/TodoForm.svelte b/src/features/todos/components/TodoForm.svelte index 9088465..0218132 100644 --- a/src/features/todos/components/TodoForm.svelte +++ b/src/features/todos/components/TodoForm.svelte @@ -66,10 +66,18 @@ onDestroy(() => disableShortcut('saveTodo')); -
- - -
+
+ + Optional fields + + +
+
+ + +
+
+
@@ -112,9 +120,9 @@ label kbd { div[contenteditable] { display: block; min-height: 7.2rem; - padding: 8px 1.2rem; + padding: 0.8rem 1.2rem; border: 2px solid var(--dimmed-300); - border-radius: 8px; + border-radius: 0.8rem; line-height: 2rem; resize: none; } @@ -123,8 +131,21 @@ div[contenteditable] { border-color: var(--danger); } +.OptionalFields label { + font-size: 1.5rem; +} + +.OptionalFieldsSummary span { + margin-left: 0.8rem; + cursor: pointer; +} + +.OptionalFieldsContent { + padding-top: 0.8rem; +} + .Error { - margin-bottom: 8px; + margin-bottom: 0.8rem; color: var(--danger); } From 51dfd6e67d0dedb2636f65aff0d83c9c34249782 Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 12 Oct 2024 21:46:30 -0700 Subject: [PATCH 02/14] Configure Prettier to organize imports --- .prettierrc.json | 17 +- package-lock.json | 931 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 3 files changed, 934 insertions(+), 15 deletions(-) diff --git a/.prettierrc.json b/.prettierrc.json index 04abc21..7e26c95 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -5,8 +5,21 @@ "singleQuote": true, "printWidth": 120, "bracketSameLine": false, - "plugins": ["prettier-plugin-svelte"], - + "plugins": [ + "prettier-plugin-svelte", + "@ianvs/prettier-plugin-sort-imports" + ], + "importOrder": [ + "", + "", + "", + "^(@components|.*/components/.*)", + "", + "^@(?!components)", + "^[.]", + "", + ".css$" + ], "overrides": [ { "files": "*.svelte", diff --git a/package-lock.json b/package-lock.json index 4f58627..955dddc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ }, "devDependencies": { "@faker-js/faker": "^8.4.0", + "@ianvs/prettier-plugin-sort-imports": "^4.3.1", "@lhci/cli": "^0.12.0", "@sveltejs/vite-plugin-svelte": "^2.4.5", "cypress": "^13.3.0", @@ -37,6 +38,317 @@ "vite": "^4.4.9" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.25.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.8", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.8", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -494,12 +806,82 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" }, + "node_modules/@ianvs/prettier-plugin-sort-imports": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.1.tgz", + "integrity": "sha512-ZHwbyjkANZOjaBm3ZosADD2OUYGFzQGxfy67HmGZU94mHqe7g1LCMA7YYKB1Cq+UTPCBqlAYapY0KXAjKEw8Sg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/core": "^7.24.0", + "@babel/generator": "^7.23.6", + "@babel/parser": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "semver": "^7.5.2" + }, + "peerDependencies": { + "@vue/compiler-sfc": "2.7.x || 3.x", + "prettier": "2 || 3" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@lhci/cli": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@lhci/cli/-/cli-0.12.0.tgz", @@ -1318,6 +1700,39 @@ "concat-map": "0.0.1" } }, + "node_modules/browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -1406,6 +1821,27 @@ "node": ">=6" } }, + "node_modules/caniuse-lite": { + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -1742,6 +2178,13 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -2252,6 +2695,13 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "node_modules/electron-to-chromium": { + "version": "1.5.36", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.36.tgz", + "integrity": "sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==", + "dev": true, + "license": "ISC" + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2309,10 +2759,11 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2731,6 +3182,16 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2823,6 +3284,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", @@ -3305,6 +3776,13 @@ "node": ">=12" } }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -3324,6 +3802,19 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -3336,6 +3827,19 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -20414,6 +20918,13 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -20644,10 +21155,11 @@ "dev": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true, + "license": "ISC" }, "node_modules/pify": { "version": "2.3.0", @@ -21423,6 +21935,16 @@ "rimraf": "bin.js" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -21577,6 +22099,37 @@ "node": ">=8" } }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", @@ -21976,6 +22529,229 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@babel/code-frame": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.25.7", + "picocolors": "^1.0.0" + } + }, + "@babel/compat-data": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", + "dev": true + }, + "@babel/core": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.8", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.8", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", + "dev": true, + "requires": { + "@babel/types": "^7.25.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "@babel/helper-module-imports": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", + "dev": true, + "requires": { + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" + } + }, + "@babel/helper-string-parser": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", + "dev": true, + "requires": { + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" + } + }, + "@babel/highlight": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.25.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + } + }, + "@babel/parser": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "dev": true, + "requires": { + "@babel/types": "^7.25.8" + } + }, + "@babel/template": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" + } + }, + "@babel/traverse": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "to-fast-properties": "^2.0.0" + } + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -22220,12 +22996,59 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz", "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==" }, + "@ianvs/prettier-plugin-sort-imports": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.3.1.tgz", + "integrity": "sha512-ZHwbyjkANZOjaBm3ZosADD2OUYGFzQGxfy67HmGZU94mHqe7g1LCMA7YYKB1Cq+UTPCBqlAYapY0KXAjKEw8Sg==", + "dev": true, + "requires": { + "@babel/core": "^7.24.0", + "@babel/generator": "^7.23.6", + "@babel/parser": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "semver": "^7.5.2" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true + }, "@jridgewell/sourcemap-codec": { "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, + "@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "@lhci/cli": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@lhci/cli/-/cli-0.12.0.tgz", @@ -22865,6 +23688,18 @@ "concat-map": "0.0.1" } }, + "browserslist": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" + } + }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -22920,6 +23755,12 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", + "dev": true + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -23191,6 +24032,12 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -23567,6 +24414,12 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", "dev": true }, + "electron-to-chromium": { + "version": "1.5.36", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.36.tgz", + "integrity": "sha512-HYTX8tKge/VNp6FGO+f/uVDmUkq+cEfcxYhKf15Akc4M5yxt5YmorwlAitKWjWhWQnKcDRBAQKXkhqqXMqcrjw==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -23615,9 +24468,9 @@ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-html": { @@ -23940,6 +24793,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -24008,6 +24867,12 @@ "ini": "2.0.0" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", @@ -24360,6 +25225,12 @@ "integrity": "sha512-c80Qupofp43y4cJ7+8TTDN/AsDwLi5oOm/plBrWI+iQt485vKXCco+yVmOwEgdo9VOdsYTuV0UlTeetVPTriXA==", "dev": true }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -24376,6 +25247,12 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, + "jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true + }, "json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -24388,6 +25265,12 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -37089,6 +37972,12 @@ "optional": true, "peer": true }, + "node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -37262,9 +38151,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "dev": true }, "pify": { @@ -37858,6 +38747,12 @@ } } }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -37978,6 +38873,16 @@ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true }, + "update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "requires": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + } + }, "url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", diff --git a/package.json b/package.json index d257df9..9498b66 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ }, "devDependencies": { "@faker-js/faker": "^8.4.0", + "@ianvs/prettier-plugin-sort-imports": "^4.3.1", "@lhci/cli": "^0.12.0", "@sveltejs/vite-plugin-svelte": "^2.4.5", "cypress": "^13.3.0", From 9b23985cd629a5503cbf50845cce8cda0830fa4b Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 12 Oct 2024 22:00:14 -0700 Subject: [PATCH 03/14] Add optional date field in TodoForm --- src/app/App.svelte | 22 +++++------ src/components/Input.svelte | 23 ++++++++++++ src/features/todos/components/TodoForm.svelte | 37 +++++++++++++++---- src/features/todos/store.js | 8 ++-- 4 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 src/components/Input.svelte diff --git a/src/app/App.svelte b/src/app/App.svelte index df31b70..d49e084 100644 --- a/src/app/App.svelte +++ b/src/app/App.svelte @@ -1,21 +1,21 @@ + + + + diff --git a/src/features/todos/components/TodoForm.svelte b/src/features/todos/components/TodoForm.svelte index 0218132..8c734d5 100644 --- a/src/features/todos/components/TodoForm.svelte +++ b/src/features/todos/components/TodoForm.svelte @@ -1,16 +1,17 @@ + +{#if variant === 'li'} +
  • + {#if icon} +
    + {/if} + +
  • +{:else if variant === 'span'} + + {#if icon} +
    + {/if} + +
    +{/if} + + diff --git a/src/features/todos/components/TodoItem.svelte b/src/features/todos/components/TodoItem.svelte index 78faecc..4cb428d 100644 --- a/src/features/todos/components/TodoItem.svelte +++ b/src/features/todos/components/TodoItem.svelte @@ -2,14 +2,17 @@ import { createEventDispatcher } from 'svelte'; import { SHADOW_ITEM_MARKER_PROPERTY_NAME } from 'svelte-dnd-action'; -import { settings } from '@features/settings/store'; - import Checkbox from '@components/Checkbox.svelte'; + +import { settings } from '@features/settings/store'; +import TodoItemDate from './TodoItemDate.svelte'; import TodoItemMenu from './TodoItemMenu.svelte'; import TodoItemTags from './TodoItemTags.svelte'; export let todo; $: hasTags = (todo.tags?.length ?? 0) > 0; +$: hasDate = Boolean(todo.date); +$: hasBadges = hasTags || hasDate; const dispatch = createEventDispatcher(); const toggleTodoDone = (event) => dispatch('update', { id: todo.id, done: event.detail }); @@ -25,8 +28,16 @@ const toggleTodoDone = (event) => dispatch('update', { id: todo.id, done: event.

    {todo.body}

    - {#if hasTags} - + + {#if hasBadges} +
      + {#if hasDate} + + {/if} + {#if hasTags} + + {/if} +
    {/if}
    @@ -87,6 +98,15 @@ li.done p { color: var(--dimmed-400); } +.TodoBadges { + display: flex; + flex-wrap: wrap; + gap: 4px; + padding: 0; + margin-top: 1.6rem; + list-style: none; +} + .TodoItemShadow { position: absolute; top: 0; @@ -109,8 +129,4 @@ li :global(.TodoItemMenu) { li:not(:hover) :global(.TodoItemMenu) { display: none; } - -li :global(.TodoItemTags) { - margin-top: 1.6rem; -} diff --git a/src/features/todos/components/TodoItemDate.svelte b/src/features/todos/components/TodoItemDate.svelte new file mode 100644 index 0000000..e33ccca --- /dev/null +++ b/src/features/todos/components/TodoItemDate.svelte @@ -0,0 +1,25 @@ + + + + + + + {dateDisplay} + diff --git a/src/features/todos/components/TodoItemTags.svelte b/src/features/todos/components/TodoItemTags.svelte index 471c4d6..171d336 100644 --- a/src/features/todos/components/TodoItemTags.svelte +++ b/src/features/todos/components/TodoItemTags.svelte @@ -1,32 +1,9 @@ -
      - {#each tags as tag (tag)} -
    • {tag}
    • - {/each} -
    - - +{#each tags as tag (tag)} + {tag} +{/each} diff --git a/src/features/todos/constants.js b/src/features/todos/constants.js index 4e10b7f..289b6ab 100644 --- a/src/features/todos/constants.js +++ b/src/features/todos/constants.js @@ -1,3 +1,6 @@ export const TODOS_TODAY = 'TODAY'; export const TODOS_THIS_WEEK = 'THIS_WEEK'; export const TODOS_EVENTUALLY = 'EVENTUALLY'; + +export const TODOS_DATE_ABSOLUTE = 'DATE_ABSOLUTE'; +export const TODOS_DATE_RELATIVE = 'DATE_RELATIVE'; diff --git a/src/features/todos/lib/format.js b/src/features/todos/lib/format.js new file mode 100644 index 0000000..7e4d68b --- /dev/null +++ b/src/features/todos/lib/format.js @@ -0,0 +1,40 @@ +const today = new Date(); +today.setHours(0, 0, 0, 0); + +export const getRelativeDateParams = (date) => { + const days = Math.round((date.getTime() - today.getTime()) / 1000 / 60 / 60 / 24); + if (days < 31) { + return [days, 'day']; + } + const weeks = Math.round(days / 7); + if (weeks < 4) { + return [weeks, 'week']; + } + const months = Math.round(weeks / 4); + if (months < 12) { + return [months, 'month']; + } + const years = Math.round(months / 12); + return [years, 'year']; +}; + +export const formatAbsoluteDate = (date) => { + const formatterOptions = { + month: 'short', + day: 'numeric', + }; + if (date.getFullYear() !== today.getFullYear()) { + formatterOptions.year = 'numeric'; + } + const formatter = new Intl.DateTimeFormat(undefined, formatterOptions); + return formatter.format(date); +}; + +export const formatRelativeDate = (date) => { + const params = getRelativeDateParams(date); + const formatter = new Intl.RelativeTimeFormat(undefined, { + style: 'long', + numeric: 'auto', + }); + return formatter.format(...params); +}; From c0c2fb9401ee280eb4432ecaab35fff5630c30a3 Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 19 Oct 2024 20:29:13 -0700 Subject: [PATCH 05/14] Open optional fields section when there are values set --- src/features/todos/components/TodoForm.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/features/todos/components/TodoForm.svelte b/src/features/todos/components/TodoForm.svelte index 8c734d5..d1abddb 100644 --- a/src/features/todos/components/TodoForm.svelte +++ b/src/features/todos/components/TodoForm.svelte @@ -27,6 +27,7 @@ const listChoices = [ ]; $: tagsChoices = orderBy($tags, (tag) => tag.label.toUpperCase()); $: formValid = data.body && data.list; +$: hasOptionalFields = data.date || data.tags?.length; let errors = {}; const handlePaste = async () => { @@ -67,7 +68,7 @@ onDestroy(() => disableShortcut('saveTodo'));
    -
    +
    Optional fields From fe777c657d5eedc8159a4e94cb9c4289ea5e580c Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 19 Oct 2024 21:18:21 -0700 Subject: [PATCH 06/14] Move todos to the appropriate list based on the todo date --- src/features/todos/index.js | 31 +++++++++++++++++++++++++++++++ src/features/todos/lib/format.js | 6 +++++- src/index.js | 7 +++++-- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/features/todos/index.js diff --git a/src/features/todos/index.js b/src/features/todos/index.js new file mode 100644 index 0000000..58fcc0b --- /dev/null +++ b/src/features/todos/index.js @@ -0,0 +1,31 @@ +import { TODOS_THIS_WEEK, TODOS_TODAY } from '@features/todos/constants'; +import { getDifferenceInDays } from './lib/format'; +import { todos } from './store'; + +export function initializeTodos() { + const today = new Date(); + today.setHours(0, 0, 0, 0); + + let isFirstRun = true; + const unsubscribe = todos.subscribe((todosData) => { + if (!isFirstRun) return; + isFirstRun = false; + + const updatedTodos = todosData.map((todo) => { + if (!todo.date) { + return todo; + } + + const date = new Date(`${todo.date}T00:00:00`); + const difference = getDifferenceInDays(date); + if (difference === 0) { + todo.list = TODOS_TODAY; + } else if (difference < 7) { + todo.list = TODOS_THIS_WEEK; + } + return todo; + }); + todos.set(updatedTodos); + }); + unsubscribe(); +} diff --git a/src/features/todos/lib/format.js b/src/features/todos/lib/format.js index 7e4d68b..dd7daaa 100644 --- a/src/features/todos/lib/format.js +++ b/src/features/todos/lib/format.js @@ -1,8 +1,12 @@ const today = new Date(); today.setHours(0, 0, 0, 0); +export const getDifferenceInDays = (date) => { + return Math.ceil((date.getTime() - today.getTime()) / 1000 / 60 / 60 / 24); +}; + export const getRelativeDateParams = (date) => { - const days = Math.round((date.getTime() - today.getTime()) / 1000 / 60 / 60 / 24); + const days = getDifferenceInDays(date); if (days < 31) { return [days, 'day']; } diff --git a/src/index.js b/src/index.js index ec968ab..5637b75 100644 --- a/src/index.js +++ b/src/index.js @@ -1,14 +1,17 @@ import App from '@app/App.svelte'; -import { initializeSentry } from '@lib/sentry'; -import { initializeThemes } from '@features/themes'; import { initializeBackgrounds } from '@features/backgrounds'; import { initializeKeyBindings } from '@features/shortcuts'; +import { initializeThemes } from '@features/themes'; +import { initializeTodos } from '@features/todos'; +import { initializeSentry } from '@lib/sentry'; + import '@app/app.css'; initializeSentry(); initializeThemes(); initializeBackgrounds(); initializeKeyBindings(); +initializeTodos(); const app = new App({ target: document.body, From 58cff4d88d3101e79ab977b81416a620cfcaa8b9 Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 19 Oct 2024 21:44:29 -0700 Subject: [PATCH 07/14] Move todos to the appropriate list only once per day --- src/features/settings/config.js | 8 ++-- src/features/settings/store.js | 14 +++++- src/features/todos/index.js | 46 +++++++++++-------- .../todos/settings/TodosSettings.svelte | 0 src/features/todos/settings/index.js | 10 ++++ 5 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 src/features/todos/settings/TodosSettings.svelte create mode 100644 src/features/todos/settings/index.js diff --git a/src/features/settings/config.js b/src/features/settings/config.js index dca44a5..31ed3da 100644 --- a/src/features/settings/config.js +++ b/src/features/settings/config.js @@ -1,16 +1,18 @@ -import * as ThemeSettings from '@features/themes/settings'; import * as BackgroundSettings from '@features/backgrounds/settings'; import * as QuickLinksSettings from '@features/quick-links/settings'; -import * as TagsSettings from '@features/tags/settings'; import * as SearchSettings from '@features/search/settings'; -import * as ShortcutsSettings from '@features/shortcuts/settings'; import * as MiscellaneousSettings from '@features/settings/settings'; +import * as ShortcutsSettings from '@features/shortcuts/settings'; +import * as TagsSettings from '@features/tags/settings'; +import * as ThemeSettings from '@features/themes/settings'; +import * as TodosSettings from '@features/todos/settings'; export const settingsTabs = [ ThemeSettings, BackgroundSettings, QuickLinksSettings, TagsSettings, + TodosSettings, SearchSettings, ShortcutsSettings, MiscellaneousSettings, diff --git a/src/features/settings/store.js b/src/features/settings/store.js index 6492343..c082e14 100644 --- a/src/features/settings/store.js +++ b/src/features/settings/store.js @@ -1,7 +1,7 @@ -import { writable } from 'svelte/store'; import cloneDeep from 'lodash/cloneDeep'; import get from 'lodash/get'; import pick from 'lodash/pick'; +import { writable } from 'svelte/store'; import { STORAGE_KEY_SETTINGS } from '@lib/constants'; import { settingsTabs } from './config'; @@ -41,6 +41,16 @@ function createStore() { saveInStorage(data); } + function saveKey(key, value) { + update((settings) => { + settings[key] = value; + if (!settings.preview) { + save(settings); + } + return settings; + }); + } + function saveInStorage(data) { const settings = JSON.parse(localStorage.getItem(STORAGE_KEY_SETTINGS) || '{}'); settingsTabs.forEach((tab) => { @@ -61,7 +71,7 @@ function createStore() { }); } - return { subscribe, set, update, preview, restore, save, saveInStorage, togglePrivacyMode }; + return { subscribe, set, update, preview, restore, save, saveKey, saveInStorage, togglePrivacyMode }; } export const settings = createStore(); diff --git a/src/features/todos/index.js b/src/features/todos/index.js index 58fcc0b..18ac8e4 100644 --- a/src/features/todos/index.js +++ b/src/features/todos/index.js @@ -1,3 +1,4 @@ +import { settings } from '@features/settings/store'; import { TODOS_THIS_WEEK, TODOS_TODAY } from '@features/todos/constants'; import { getDifferenceInDays } from './lib/format'; import { todos } from './store'; @@ -7,25 +8,32 @@ export function initializeTodos() { today.setHours(0, 0, 0, 0); let isFirstRun = true; - const unsubscribe = todos.subscribe((todosData) => { - if (!isFirstRun) return; - isFirstRun = false; + settings.subscribe((settingsData) => { + todos.subscribe((todosData) => { + if (!isFirstRun) return; + isFirstRun = false; - const updatedTodos = todosData.map((todo) => { - if (!todo.date) { - return todo; - } + const todosListLastUpdated = new Date(settingsData.todosListLastUpdated); + todosListLastUpdated.setHours(0, 0, 0, 0); + + if (getDifferenceInDays(todosListLastUpdated) >= 0) return; + settings.saveKey('todosListLastUpdated', new Date().getTime()); - const date = new Date(`${todo.date}T00:00:00`); - const difference = getDifferenceInDays(date); - if (difference === 0) { - todo.list = TODOS_TODAY; - } else if (difference < 7) { - todo.list = TODOS_THIS_WEEK; - } - return todo; - }); - todos.set(updatedTodos); - }); - unsubscribe(); + const updatedTodos = todosData.map((todo) => { + if (!todo.date) { + return todo; + } + + const date = new Date(`${todo.date}T00:00:00`); + const difference = getDifferenceInDays(date); + if (difference === 0) { + todo.list = TODOS_TODAY; + } else if (difference < 7) { + todo.list = TODOS_THIS_WEEK; + } + return todo; + }); + todos.set(updatedTodos); + })(); + })(); } diff --git a/src/features/todos/settings/TodosSettings.svelte b/src/features/todos/settings/TodosSettings.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/features/todos/settings/index.js b/src/features/todos/settings/index.js new file mode 100644 index 0000000..e9ef4d1 --- /dev/null +++ b/src/features/todos/settings/index.js @@ -0,0 +1,10 @@ +import TodosSettings from './TodosSettings.svelte'; + +export const id = 'TODOS'; +export const label = 'Todos'; +export const component = TodosSettings; + +export const getDefaultSettings = () => ({ + openOptionalFields: false, +}); +export const allowedFields = ['openOptionalFields', 'todosListLastUpdated']; From fc84e5dfd49ef7590ebcb8765c2352319429e3b8 Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sat, 19 Oct 2024 21:58:36 -0700 Subject: [PATCH 08/14] Add todos settings for toggling optional fields --- src/features/todos/components/TodoForm.svelte | 4 +- .../todos/settings/TodosSettings.svelte | 60 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/features/todos/components/TodoForm.svelte b/src/features/todos/components/TodoForm.svelte index d1abddb..69b9ca9 100644 --- a/src/features/todos/components/TodoForm.svelte +++ b/src/features/todos/components/TodoForm.svelte @@ -7,6 +7,7 @@ import Input from '@components/Input.svelte'; import Selector from '@components/Selector.svelte'; import TagsInput from '@features/tags/components/TagsInput.svelte'; +import { settings } from '@features/settings/store'; import { disableShortcut, enableShortcut } from '@features/shortcuts'; import { tags } from '@features/tags/store'; import { TODOS_EVENTUALLY, TODOS_THIS_WEEK, TODOS_TODAY } from '../constants'; @@ -28,6 +29,7 @@ const listChoices = [ $: tagsChoices = orderBy($tags, (tag) => tag.label.toUpperCase()); $: formValid = data.body && data.list; $: hasOptionalFields = data.date || data.tags?.length; +$: shouldOpenOptionalFields = hasOptionalFields || $settings.openOptionalFields; let errors = {}; const handlePaste = async () => { @@ -68,7 +70,7 @@ onDestroy(() => disableShortcut('saveTodo')); -
    +
    Optional fields diff --git a/src/features/todos/settings/TodosSettings.svelte b/src/features/todos/settings/TodosSettings.svelte index e69de29..15f0899 100644 --- a/src/features/todos/settings/TodosSettings.svelte +++ b/src/features/todos/settings/TodosSettings.svelte @@ -0,0 +1,60 @@ + + +
    +
    + + +
    +
    + + From 70e065322b4b4cdad4e0f61156302aee042b8bcb Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sun, 20 Oct 2024 01:24:16 -0700 Subject: [PATCH 09/14] Add button to clear the date field in the todo form --- .prettierrc.json | 2 ++ src/features/todos/components/TodoForm.svelte | 15 +++++++----- .../todos/components/TodoFormDateField.svelte | 24 +++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/features/todos/components/TodoFormDateField.svelte diff --git a/.prettierrc.json b/.prettierrc.json index 7e26c95..be93f11 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -16,6 +16,8 @@ "^(@components|.*/components/.*)", "", "^@(?!components)", + "^[.]{2}", + "", "^[.]", "", ".css$" diff --git a/src/features/todos/components/TodoForm.svelte b/src/features/todos/components/TodoForm.svelte index 69b9ca9..6178a3b 100644 --- a/src/features/todos/components/TodoForm.svelte +++ b/src/features/todos/components/TodoForm.svelte @@ -3,7 +3,6 @@ import orderBy from 'lodash/orderBy'; import { createEventDispatcher, onDestroy, onMount } from 'svelte'; import Button from '@components/Button.svelte'; -import Input from '@components/Input.svelte'; import Selector from '@components/Selector.svelte'; import TagsInput from '@features/tags/components/TagsInput.svelte'; @@ -13,6 +12,8 @@ import { tags } from '@features/tags/store'; import { TODOS_EVENTUALLY, TODOS_THIS_WEEK, TODOS_TODAY } from '../constants'; import { sanitizeText, unsanitizeText } from '../lib/sanitize'; +import TodoFormDateField from './TodoFormDateField.svelte'; + export let data = { list: TODOS_EVENTUALLY, }; @@ -26,11 +27,13 @@ const listChoices = [ { label: 'This week', value: TODOS_THIS_WEEK }, { label: 'Eventually', value: TODOS_EVENTUALLY }, ]; +let errors = {}; +let isOptionalFieldsToggled = false; + $: tagsChoices = orderBy($tags, (tag) => tag.label.toUpperCase()); $: formValid = data.body && data.list; $: hasOptionalFields = data.date || data.tags?.length; -$: shouldOpenOptionalFields = hasOptionalFields || $settings.openOptionalFields; -let errors = {}; +$: shouldOpenOptionalFields = hasOptionalFields || $settings.openOptionalFields || isOptionalFieldsToggled; const handlePaste = async () => { // Svelte's tick() doesn't work here, so setTimeout() to the rescue! @@ -40,6 +43,7 @@ const handlePaste = async () => { data.body = unsanitizeText(sanitizeText(data.body)); }, 0); }; +const handleToggle = () => (isOptionalFieldsToggled = true); const dispatch = createEventDispatcher(); const submitForm = () => { @@ -47,7 +51,6 @@ const submitForm = () => { data.body = sanitizeText(data.body); dispatch('submit', data); } - if (!data.body) { errors.body = 'Todo body is required'; } @@ -70,7 +73,7 @@ onDestroy(() => disableShortcut('saveTodo')); -
    +
    Optional fields @@ -85,7 +88,7 @@ onDestroy(() => disableShortcut('saveTodo')); Info - +
    diff --git a/src/features/todos/components/TodoFormDateField.svelte b/src/features/todos/components/TodoFormDateField.svelte new file mode 100644 index 0000000..8fd5b14 --- /dev/null +++ b/src/features/todos/components/TodoFormDateField.svelte @@ -0,0 +1,24 @@ + + +
    + + +
    + + From 50a72fc12b28cc5eafe4474f369f0b7bcd5f842d Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sun, 20 Oct 2024 01:42:33 -0700 Subject: [PATCH 10/14] Move optional fields into a separate component --- src/features/todos/components/TodoForm.svelte | 73 +--------------- .../components/TodoFormOptionalFields.svelte | 84 +++++++++++++++++++ 2 files changed, 86 insertions(+), 71 deletions(-) create mode 100644 src/features/todos/components/TodoFormOptionalFields.svelte diff --git a/src/features/todos/components/TodoForm.svelte b/src/features/todos/components/TodoForm.svelte index 6178a3b..27bc3d0 100644 --- a/src/features/todos/components/TodoForm.svelte +++ b/src/features/todos/components/TodoForm.svelte @@ -1,18 +1,14 @@ + +
    + + Optional fields + + +
    +
    + + +
    + +
    + + +
    +
    +
    + + From 26170f1413c97c2ece17bc3a11691eedffb548cd Mon Sep 17 00:00:00 2001 From: Arnelle Balane Date: Sun, 20 Oct 2024 02:03:40 -0700 Subject: [PATCH 11/14] Add setting for moving todos to appropriate list automatically --- .../todos/components/TodoFormOptionalFields.svelte | 12 +----------- src/features/todos/index.js | 5 ++++- src/features/todos/settings/TodosSettings.svelte | 13 +++++++++++++ src/features/todos/settings/index.js | 3 ++- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/features/todos/components/TodoFormOptionalFields.svelte b/src/features/todos/components/TodoFormOptionalFields.svelte index 776fcd0..c384df9 100644 --- a/src/features/todos/components/TodoFormOptionalFields.svelte +++ b/src/features/todos/components/TodoFormOptionalFields.svelte @@ -26,12 +26,7 @@ const handleToggle = () => (isOptionalFieldsToggled = true);
    - +
    @@ -57,11 +52,6 @@ label span { color: var(--dimmed-500); } -label span[data-tooltip] { - text-decoration: underline; - text-decoration-style: dotted; -} - label kbd { padding: 2px 6px; border-radius: 4px; diff --git a/src/features/todos/index.js b/src/features/todos/index.js index 18ac8e4..ac4212a 100644 --- a/src/features/todos/index.js +++ b/src/features/todos/index.js @@ -1,5 +1,6 @@ import { settings } from '@features/settings/store'; import { TODOS_THIS_WEEK, TODOS_TODAY } from '@features/todos/constants'; + import { getDifferenceInDays } from './lib/format'; import { todos } from './store'; @@ -7,8 +8,10 @@ export function initializeTodos() { const today = new Date(); today.setHours(0, 0, 0, 0); - let isFirstRun = true; settings.subscribe((settingsData) => { + if (!settingsData.moveTodosAutomatically) return; + + let isFirstRun = true; todos.subscribe((todosData) => { if (!isFirstRun) return; isFirstRun = false; diff --git a/src/features/todos/settings/TodosSettings.svelte b/src/features/todos/settings/TodosSettings.svelte index 15f0899..64d1d7e 100644 --- a/src/features/todos/settings/TodosSettings.svelte +++ b/src/features/todos/settings/TodosSettings.svelte @@ -19,6 +19,19 @@ export let data = getDefaultSettings(); data-cy="open-optional-fields-toggle" />
    + +
    + + +