From 7dcca7ac19fd520455b0bd301bc903d766af0a99 Mon Sep 17 00:00:00 2001 From: Simon Reinisch Date: Mon, 22 Apr 2024 16:57:02 +0200 Subject: [PATCH] feat: allow entering data for years in the past closes #35 --- .../base/context-menu/ContextMenu.types.ts | 1 + .../base/context-menu/ContextMenu.vue | 1 + .../base/context-menu/ContextMenuButton.vue | 9 ++++++- .../pages/navigation/tools/ToolsButton.vue | 4 +++- .../tools/delete-year/DeleteYearButton.vue | 24 +++++++++++++++++++ .../{demo => load-demo-data}/DemoData.json | 0 .../LoadDemoDataButton.vue | 0 .../navigation/year/ChangeYearButton.vue | 5 ++-- src/i18n/locales/de.json | 4 ++++ src/i18n/locales/en.json | 4 ++++ src/store/state/index.ts | 11 +++++++++ src/styles/themes/dark.scss | 1 + src/styles/themes/light.scss | 1 + 13 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 src/app/pages/navigation/tools/delete-year/DeleteYearButton.vue rename src/app/pages/navigation/tools/{demo => load-demo-data}/DemoData.json (100%) rename src/app/pages/navigation/tools/{demo => load-demo-data}/LoadDemoDataButton.vue (100%) diff --git a/src/app/components/base/context-menu/ContextMenu.types.ts b/src/app/components/base/context-menu/ContextMenu.types.ts index 71dac81..17b944a 100644 --- a/src/app/components/base/context-menu/ContextMenu.types.ts +++ b/src/app/components/base/context-menu/ContextMenu.types.ts @@ -10,6 +10,7 @@ export type ContextMenuOptionId = number | string; export interface ContextMenuOption { id: ContextMenuOptionId; + muted?: boolean; icon?: Component; label?: string; } diff --git a/src/app/components/base/context-menu/ContextMenu.vue b/src/app/components/base/context-menu/ContextMenu.vue index 82c1988..d2f2916 100644 --- a/src/app/components/base/context-menu/ContextMenu.vue +++ b/src/app/components/base/context-menu/ContextMenu.vue @@ -12,6 +12,7 @@ :pad-icon="hasOptionWithIcon" :text="option.label ?? option.id" :icon="option.icon" + :muted="option.muted" :highlight="option.id === highlight" @click="select(option)" /> diff --git a/src/app/components/base/context-menu/ContextMenuButton.vue b/src/app/components/base/context-menu/ContextMenuButton.vue index 50de1f7..e775178 100644 --- a/src/app/components/base/context-menu/ContextMenuButton.vue +++ b/src/app/components/base/context-menu/ContextMenuButton.vue @@ -22,12 +22,14 @@ const props = withDefaults( class?: ClassNames; text: string | number; icon?: Component; + muted?: boolean; padIcon?: boolean; highlight?: boolean; }>(), { highlight: false, - padIcon: false + padIcon: false, + muted: false } ); @@ -38,6 +40,7 @@ const classes = computed(() => [ props.class, styles.btn, { + [styles.muted]: props.muted, [styles.highlight]: props.highlight, [styles.padIcon]: props.padIcon && !props.icon } @@ -86,6 +89,10 @@ const onClick = (evt: MouseEvent) => { padding-left: calc(12px + 20px); } + &.muted { + color: var(--context-menu-item-color-muted); + } + &:hover, &.highlight { color: var(--context-menu-item-color-hover); diff --git a/src/app/pages/navigation/tools/ToolsButton.vue b/src/app/pages/navigation/tools/ToolsButton.vue index e427fdb..3f0995e 100644 --- a/src/app/pages/navigation/tools/ToolsButton.vue +++ b/src/app/pages/navigation/tools/ToolsButton.vue @@ -14,6 +14,7 @@ + @@ -30,9 +31,10 @@ import { ClassNames } from '@utils'; import ChangePasswordButton from './change-password/ChangePasswordButton.vue'; import CopyButton from './copy-paste/CopyButton.vue'; import PasteButton from './copy-paste/PasteButton.vue'; -import LoadDemoDataButton from './demo/LoadDemoDataButton.vue'; +import DeleteYearButton from './delete-year/DeleteYearButton.vue'; import ExportButton from './export/ExportButton.vue'; import ImportButton from './import/ImportButton.vue'; +import LoadDemoDataButton from './load-demo-data/LoadDemoDataButton.vue'; import PrivacyModeButton from './privacy-mode/PrivacyModeButton.vue'; const props = defineProps<{ diff --git a/src/app/pages/navigation/tools/delete-year/DeleteYearButton.vue b/src/app/pages/navigation/tools/delete-year/DeleteYearButton.vue new file mode 100644 index 0000000..2244016 --- /dev/null +++ b/src/app/pages/navigation/tools/delete-year/DeleteYearButton.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/app/pages/navigation/tools/demo/DemoData.json b/src/app/pages/navigation/tools/load-demo-data/DemoData.json similarity index 100% rename from src/app/pages/navigation/tools/demo/DemoData.json rename to src/app/pages/navigation/tools/load-demo-data/DemoData.json diff --git a/src/app/pages/navigation/tools/demo/LoadDemoDataButton.vue b/src/app/pages/navigation/tools/load-demo-data/LoadDemoDataButton.vue similarity index 100% rename from src/app/pages/navigation/tools/demo/LoadDemoDataButton.vue rename to src/app/pages/navigation/tools/load-demo-data/LoadDemoDataButton.vue diff --git a/src/app/pages/navigation/year/ChangeYearButton.vue b/src/app/pages/navigation/year/ChangeYearButton.vue index 94069f5..38fb5d6 100644 --- a/src/app/pages/navigation/year/ChangeYearButton.vue +++ b/src/app/pages/navigation/year/ChangeYearButton.vue @@ -36,12 +36,13 @@ const time = useTime(); const classes = computed(() => props.class); const options = computed((): ContextMenuOption[] => { const yearsStored = state.years.map((v) => v.year); - const offset = Math.min(...yearsStored); + const firstYear = Math.min(...yearsStored); const list: ContextMenuOption[] = []; - for (let year = offset; year <= time.year.value + PRE_PLANNABLE_YEARS; year++) { + for (let year = firstYear - 1; year <= time.year.value + PRE_PLANNABLE_YEARS; year++) { list.push({ id: year, + muted: year === firstYear - 1, icon: state.activeYear === year ? RiCalendarCheckLine : RiCalendarTodoLine }); } diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index 59e9e6b..99bd81d 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -28,6 +28,10 @@ "demo": { "loadDemoData": "Demo-Daten laden" }, + "deleteYear": { + "delete": "Jahr {year} entfernen", + "confirm": "Sind Sie sicher, dass Sie das Jahr {year} löschen möchten?" + }, "export": { "export": "Als JSON-Datei exportieren" }, diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 0cb1b21..0a64488 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -28,6 +28,10 @@ "demo": { "loadDemoData": "Load demo data" }, + "deleteYear": { + "delete": "Remove {year}", + "confirm": "Are you sure you want to remove {year}?" + }, "export": { "export": "Export as json file" }, diff --git a/src/store/state/index.ts b/src/store/state/index.ts index 5dd609a..73de31f 100644 --- a/src/store/state/index.ts +++ b/src/store/state/index.ts @@ -31,6 +31,7 @@ interface Store { deserialize(file: File): Promise; deserialize(file: DataState): Promise; + shiftYears(): void; changeYear(year: number): void; changeLocale(locale: AvailableLocale): void; changeCurrency(currency: AvailableCurrency): void; @@ -181,6 +182,16 @@ export const createDataStore = (storage?: Storage): Store => { } }, + shiftYears() { + if (state.years.length > 1) { + const item = state.years.shift(); + + if (item?.year === activeYear.value) { + activeYear.value = state.years.at(0)?.year as number; + } + } + }, + changeYear(year: number) { let data = state.years.find((v) => v.year === year); diff --git a/src/styles/themes/dark.scss b/src/styles/themes/dark.scss index 2055fba..1627022 100644 --- a/src/styles/themes/dark.scss +++ b/src/styles/themes/dark.scss @@ -144,6 +144,7 @@ --dialog-box-shadow: 0 2px 10px #00000080; --context-menu-item-color: #c1c1cf; + --context-menu-item-color-muted: #6e6e72; --context-menu-item-color-hover: #ededf6; --context-menu-item-background-hover: #00000080; --context-menu-backdrop: blur(4px) brightness(0.25); diff --git a/src/styles/themes/light.scss b/src/styles/themes/light.scss index 37c31d0..01be827 100644 --- a/src/styles/themes/light.scss +++ b/src/styles/themes/light.scss @@ -144,6 +144,7 @@ --dialog-box-shadow: 0 2px 5px #00000012; --context-menu-item-color: #777788; + --context-menu-item-color-muted: #cacfda; --context-menu-item-color-hover: #222228; --context-menu-item-background-hover: #0000000d; --context-menu-backdrop: brightness(10);