modify localstorage close #48

This commit is contained in:
Adrian Zürcher
2026-02-13 12:27:30 +01:00
parent 3f02afde85
commit 0026f68320
5 changed files with 139 additions and 27 deletions

View File

@@ -14,6 +14,21 @@
:val="opt.value" :val="opt.value"
:label="opt.label" :label="opt.label"
/> />
<q-tabs
v-model="activeTab"
dense
class="text-primary"
active-color="primary"
indicator-color="primary"
align="justify"
narrow-indicator
@update:model-value="onTabChange"
>
<q-tab no-caps name="today" :label="$t('today')" />
<q-tab no-caps name="week" :label="$t('week')" />
<q-tab no-caps name="month" :label="$t('month')" />
<q-tab no-caps name="year" :label="$t('year')" />
</q-tabs>
</div> </div>
<div class="row"> <div class="row">
<q-date v-model="dateRange" range flat /> <q-date v-model="dateRange" range flat />
@@ -22,7 +37,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, watch } from 'vue'; import { ref, onMounted, watch, type PropType } from 'vue';
import { date } from 'quasar'; import { date } from 'quasar';
import { i18n } from 'src/boot/lang'; import { i18n } from 'src/boot/lang';
@@ -32,11 +47,17 @@ const props = defineProps({
width: { type: Number, default: 300 }, width: { type: Number, default: 300 },
}); });
const weekdays = defineModel('weekdays', {
type: Array as PropType<number[]>,
default: () => [0, 3],
});
const startDate = new Date(); const startDate = new Date();
const activeTab = ref('');
// Initial range (format: YYYY-MM-DD) // Initial range (format: YYYY-MM-DD)
const dateRange = ref<string | { to: string; from: string }>(''); const dateRange = ref<string | { to: string; from: string }>('');
const selectedWeekdays = ref([0, 3]); // Default to weekdays const selectedWeekdays = ref(weekdays); // Default to weekdays
const emit = defineEmits(['update:dates']); const emit = defineEmits(['update:dates']);
onMounted(() => { onMounted(() => {
@@ -53,6 +74,14 @@ const weekdayOptions = [
{ label: i18n.global.t('SundayShort'), value: 0 }, { label: i18n.global.t('SundayShort'), value: 0 },
]; ];
const onTabChange = (val: 'today' | 'week' | 'month' | 'year') => {
if (val) setRange(val);
// Optional: Reset tab to empty so user can click the same tab again later
setTimeout(() => {
activeTab.value = '';
}, 500);
};
// The Logic: Calculate all specific dates within the range that match weekdays // The Logic: Calculate all specific dates within the range that match weekdays
watch(dateRange, () => { watch(dateRange, () => {
if (!dateRange.value) { if (!dateRange.value) {
@@ -81,4 +110,81 @@ watch(dateRange, () => {
emit('update:dates', result); emit('update:dates', result);
return result; return result;
}); });
/**
* Logic for 1 Week / 1 Month / 1 Year
*/
const setRange = (type: 'today' | 'week' | 'month' | 'year') => {
const anchor =
typeof dateRange.value === 'string'
? new Date(dateRange.value)
: new Date(dateRange.value.from);
let from: Date;
let to: Date;
if (type === 'today') {
const now = new Date();
dateRange.value = date.formatDate(date.startOfDate(now, 'day'), 'YYYY-MM-DD');
return;
} else if (type === 'week') {
// getDay() returns 0 for Sunday.
// We calculate how many days to subtract to get to Monday (1).
const day = anchor.getDay();
const diffToMonday = day === 0 ? -6 : 1 - day;
from = date.addToDate(anchor, { days: diffToMonday });
from = date.startOfDate(from, 'day'); // Reset time to 00:00
to = date.addToDate(from, { days: 6 });
to = date.endOfDate(to, 'day'); // Set time to 23:59
} else if (type === 'month') {
// 'month' is a valid unit for startOfDate
from = date.startOfDate(anchor, 'month');
to = date.endOfDate(anchor, 'month');
} else {
// 'year' is a valid unit for startOfDate
from = date.startOfDate(anchor, 'year');
to = date.endOfDate(anchor, 'year');
}
dateRange.value = {
from: date.formatDate(from, 'YYYY/MM/DD'),
to: date.formatDate(to, 'YYYY/MM/DD'),
};
};
watch(
[dateRange, selectedWeekdays],
() => {
if (!dateRange.value) {
emit('update:dates', []);
return;
}
let start: Date, end: Date;
if (typeof dateRange.value === 'string') {
start = new Date(dateRange.value);
end = new Date(dateRange.value);
} else {
start = new Date(dateRange.value.from);
end = new Date(dateRange.value.to);
}
const result = [];
let current = start;
while (current <= end) {
if (selectedWeekdays.value.includes(current.getDay())) {
result.push(date.formatDate(current, 'YYYY-MM-DD'));
}
current = date.addToDate(current, { days: 1 });
}
emit('update:dates', result);
},
{ deep: true },
);
</script> </script>

View File

@@ -1,6 +1,5 @@
import { Dark } from 'quasar'; import { Dark } from 'quasar';
import { appName, databaseName, type Settings } from 'src/vueLib/models/settings'; import { appName, databaseName, type Settings } from 'src/vueLib/models/settings';
import { updateOrAddObject } from 'src/vueLib/utils/utils';
import { ref } from 'vue'; import { ref } from 'vue';
export function setLocalSettings(settings: Settings) { export function setLocalSettings(settings: Settings) {
@@ -79,30 +78,19 @@ export function getLocalLanguage(): string | null {
type pageDefault = { type pageDefault = {
page: string; page: string;
stringValue: string; data: unknown;
filteredValues: string[];
}; };
type pageDefaults = pageDefault[]; type pageDefaults = pageDefault[];
const pageDefaults = ref<pageDefaults>([]); const pageDefaults = ref<pageDefaults>([]);
export function setLocalPageDefaults( export function setLocalPageDefaults(page: string, data: unknown) {
page: string, localStorage.setItem(page + 'Defaults', JSON.stringify(data));
filteredColumn?: string,
filteredValue?: string[],
) {
updateOrAddObject(
pageDefaults.value,
{ page: page, stringValue: filteredColumn, filteredValues: filteredValue },
'page',
);
localStorage.setItem('pageDefaults', JSON.stringify(pageDefaults.value));
} }
export function getLocalPageDefaults(page: string): pageDefault | null { export function getLocalPageDefaults(page: string): unknown {
const defaults = localStorage.getItem('pageDefaults'); const defaults = localStorage.getItem(page + 'Defaults');
if (!defaults) return null; if (!defaults) return null;
pageDefaults.value = JSON.parse(defaults); return JSON.parse(defaults);
return pageDefaults.value.find((e) => e.page === page) || null;
} }

View File

@@ -0,0 +1,8 @@
import type { Group } from './group';
export type PageDefault = {
groups?: Group[];
selectedColumnFilter?: string;
selectedColumnOptions?: string[];
weekdays?: number[];
};

View File

@@ -66,6 +66,7 @@ import { ref } from 'vue';
import { useAttendeesTable } from './AttendeesTable'; import { useAttendeesTable } from './AttendeesTable';
import { useMemberTable } from '../members/MembersTable'; import { useMemberTable } from '../members/MembersTable';
import { getLocalPageDefaults } from 'src/localstorage/localStorage'; import { getLocalPageDefaults } from 'src/localstorage/localStorage';
import type { PageDefault } from 'src/vueLib/models/pagedefaults';
//use constants and function of imports //use constants and function of imports
const { attendees, updateAttendees } = useAttendeesTable(); const { attendees, updateAttendees } = useAttendeesTable();
@@ -95,8 +96,10 @@ const open = async (eventArray: number, event: Event) => {
await updateMembers(event.attendees); await updateMembers(event.attendees);
// set custom filter // set custom filter
const defaults = getLocalPageDefaults('attendance'); const settings = getLocalPageDefaults('attendance') as PageDefault;
setNewFilter(defaults?.stringValue || '', ...(defaults?.filteredValues ?? [])); if (settings) {
setNewFilter(settings.selectedColumnFilter || '', ...(settings.selectedColumnOptions ?? []));
}
// set amount of missing attendace // set amount of missing attendace
missingAttendanceAmount.value = filteredMembers.value.length; missingAttendanceAmount.value = filteredMembers.value.length;

View File

@@ -209,12 +209,13 @@ import AddToEvent from 'src/components/AddToEvent.vue';
import { databaseName } from 'src/vueLib/models/settings'; import { databaseName } from 'src/vueLib/models/settings';
import { useUserStore } from 'src/vueLib/login/userStore'; import { useUserStore } from 'src/vueLib/login/userStore';
import { i18n } from 'src/boot/lang'; import { i18n } from 'src/boot/lang';
import { getLocalPageDefaults, setLocalPageDefaults } from 'src/localstorage/localStorage';
import type { Responsible } from 'src/vueLib/models/responsible'; import type { Responsible } from 'src/vueLib/models/responsible';
import type { QTableColumn } from 'quasar'; import type { QTableColumn } from 'quasar';
import SearchableInput from '../components/SearchableInput.vue'; import SearchableInput from '../components/SearchableInput.vue';
import FilterSelect from '../components/FilterSelect.vue'; import FilterSelect from '../components/FilterSelect.vue';
import TopButtonGroup from '../components/TopButtonGroup.vue'; import TopButtonGroup from '../components/TopButtonGroup.vue';
import { getLocalPageDefaults, setLocalPageDefaults } from 'src/localstorage/localStorage';
import type { PageDefault } from 'src/vueLib/models/pagedefaults';
const inProps = defineProps({ const inProps = defineProps({
addAttendees: { type: Boolean }, addAttendees: { type: Boolean },
@@ -285,9 +286,11 @@ onMounted(() => {
loading.value = true; loading.value = true;
localCompareMembers.value = inProps.compareMembers; localCompareMembers.value = inProps.compareMembers;
const defaults = getLocalPageDefaults(page.value); const settings = getLocalPageDefaults(page.value) as PageDefault;
selectedColumnFilter.value = defaults?.stringValue || ''; if (settings) {
selectedColumnOptions.value = defaults?.filteredValues ?? []; selectedColumnFilter.value = settings.selectedColumnFilter || '';
selectedColumnOptions.value = settings.selectedColumnOptions || [];
}
// set custom filter // set custom filter
setNewFilter(selectedColumnFilter.value, ...selectedColumnOptions.value); setNewFilter(selectedColumnFilter.value, ...selectedColumnOptions.value);
@@ -369,7 +372,11 @@ function setColumnOptions(columnName: string) {
async function filterMembers() { async function filterMembers() {
setNewFilter(selectedColumnFilter.value, ...(selectedColumnOptions.value || [])); setNewFilter(selectedColumnFilter.value, ...(selectedColumnOptions.value || []));
setLocalPageDefaults(page.value, selectedColumnFilter.value, selectedColumnOptions.value || []); const settings = <PageDefault>{
selectedColumnFilter: selectedColumnFilter.value,
selectedColumnOptions: selectedColumnOptions.value,
};
setLocalPageDefaults(page.value, settings);
await updateTable(); await updateTable();
} }