Skip to content

Commit

Permalink
Merge pull request #43 from ya-erm/dev
Browse files Browse the repository at this point in the history
Time zone for each operation (Version 2.7.0)
  • Loading branch information
ya-erm authored Nov 20, 2023
2 parents ed0a8d5 + 3d50d02 commit f3d5211
Show file tree
Hide file tree
Showing 22 changed files with 335 additions and 41 deletions.
15 changes: 13 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "client",
"version": "2.6.2",
"version": "2.7.0",
"private": true,
"scripts": {
"dev": "vite dev",
Expand Down Expand Up @@ -55,6 +55,7 @@
"dayjs": "^1.11.7",
"idb": "^7.1.1",
"svelte-dnd-action": "^0.9.24",
"timezones-list": "^3.0.2",
"uuid": "^9.0.0"
},
"prisma": {
Expand Down
3 changes: 3 additions & 0 deletions src/lib/data/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export type MemberSettings = {
currency?: string | null;
encryption?: EncryptionVersion;
accountsOrder?: string[];
lastAnotherCurrency?: string | null;
favoriteTimeZones?: string[];
groupingId?: string | null;
};

Expand Down Expand Up @@ -96,6 +98,7 @@ export type Transaction = {
accountId: string;
categoryId: string;
date: string;
timeZone?: string | null;
amount: number;
comment?: string | null;
description?: string | null;
Expand Down
8 changes: 8 additions & 0 deletions src/lib/translate/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ export const enDict: Dictionary = {
'common.count': '{count} pcs.',
'common.show': 'Show',
'common.hide': 'Hide',
// Timezones
'timezones.select_time_zone': 'Select time zone',
'timezones.current_time_zone': 'Current time zone',
'timezones.favorite_time_zones': 'Favorite time zones',
'timezones.all_time_zones': 'All time zones',
'timezones.timezone_added_to_favorites': 'Time zone was added to favorites',
'timezones.timezone_removed_from_favorites': 'Time zone was removed from favorites',
// Tags
'tags.add_modal_header': 'Add tag',
'tags.edit_modal_header': 'Edit tag',
Expand Down Expand Up @@ -252,6 +259,7 @@ export const enDict: Dictionary = {
'settings.collaboration.workspaces': 'Workspaces',
'settings.collaboration.invites': 'Invites',
'settings.collaboration.blocklist': 'Blocklist',
'settings.debug_tools': 'Debug tools',
'settings.logs': 'Logs',
'settings.logs.filters': 'Filters',
'settings.logs.show_filters': 'Show filters',
Expand Down
8 changes: 8 additions & 0 deletions src/lib/translate/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export type Messages =
| 'common.count'
| 'common.show'
| 'common.hide'
// Timezones
| 'timezones.select_time_zone'
| 'timezones.current_time_zone'
| 'timezones.favorite_time_zones'
| 'timezones.all_time_zones'
| 'timezones.timezone_added_to_favorites'
| 'timezones.timezone_removed_from_favorites'
// Tags
| 'tags.add_modal_header'
| 'tags.edit_modal_header'
Expand Down Expand Up @@ -244,6 +251,7 @@ export type Messages =
| 'settings.collaboration.invites'
| 'settings.collaboration.blocklist'
| 'settings.encryption'
| 'settings.debug_tools'
| 'settings.logs'
| 'settings.logs.filters'
| 'settings.logs.show_filters'
Expand Down
8 changes: 8 additions & 0 deletions src/lib/translate/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ export const ruDict: Dictionary = {
'common.count': '{count} шт.',
'common.show': 'Показать',
'common.hide': 'Скрыть',
// Timezones
'timezones.select_time_zone': 'Выберите часовой пояс',
'timezones.current_time_zone': 'Текущий часовой пояс',
'timezones.favorite_time_zones': 'Избранные часовые пояса',
'timezones.all_time_zones': 'Все часовые пояса',
'timezones.timezone_added_to_favorites': 'Часовой пояс добавлен в избранные',
'timezones.timezone_removed_from_favorites': 'Часовой пояс удалён из избранных',
// Tags
'tags.add_modal_header': 'Добавить тег',
'tags.edit_modal_header': 'Редактировать тег',
Expand Down Expand Up @@ -254,6 +261,7 @@ export const ruDict: Dictionary = {
'settings.collaboration.invites': 'Приглашения',
'settings.collaboration.blocklist': 'Чёрный список',
'settings.encryption': 'Шифрование',
'settings.debug_tools': 'Инструменты отладки',
'settings.logs': 'Журнал логов',
'settings.logs.filters': 'Фильтры',
'settings.logs.show_filters': 'Показать фильтры',
Expand Down
1 change: 1 addition & 0 deletions src/lib/ui/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

<style>
button {
min-width: 0;
font-size: 1rem;
font-weight: normal;
padding: 0.75rem;
Expand Down
27 changes: 16 additions & 11 deletions src/lib/ui/list/ListGroup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,45 @@
export let title: string = '';
</script>

<div class="settings-group">
<div class="settings-group-title">{title}</div>
<div class="settings-group-container">
<div class="list-group">
<div class="list-group-title">{title}</div>
<ul class="list-group-container">
<slot />
</div>
</ul>
{#if $$slots.description}
<div class="settings-group-description">
<div class="list-group-description">
<slot name="description" />
</div>
{/if}
</div>

<style>
.settings-group {
padding: 10px;
.list-group {
padding: 1rem;
padding-bottom: 0;
}
.settings-group-title {
.list-group-title {
color: var(--secondary-text-color);
text-transform: uppercase;
margin-bottom: 10px;
margin-left: 10px;
font-size: 12px;
}
.settings-group-container {
ul {
margin: 0;
padding: 0;
list-style: none;
}
.list-group-container {
background-color: var(--header-background-color);
}
.settings-group-description {
.list-group-description {
color: var(--secondary-text-color);
line-height: 1.5;
font-size: 13px;
margin: 10px;
}
.settings-group-container {
.list-group-container {
border-radius: 10px;
}
</style>
21 changes: 12 additions & 9 deletions src/lib/ui/list/ListGroupItem.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,33 @@
</script>

{#if href}
<a class="settings-group-item" {href}>
<slot />
</a>
<li class="list-group-item">
<a class="link" {href}>
<slot />
</a>
</li>
{:else}
<div class="settings-group-item">
<li class="list-group-item">
<slot />
</div>
</li>
{/if}

<style>
a.settings-group-item {
.list-group-item .link {
text-decoration: inherit;
color: inherit;
flex-grow: 1;
}
.settings-group-item {
.list-group-item {
min-height: 36px;
display: flex;
align-items: center;
position: relative;
}
.settings-group-item:not(:last-child) {
.list-group-item:not(:last-child) {
margin-bottom: 1px;
}
.settings-group-item:not(:last-child):after {
.list-group-item:not(:last-child):after {
position: absolute;
content: '';
left: 0;
Expand Down
4 changes: 4 additions & 0 deletions src/lib/utils/formatMoney.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export function formatMoney(value: number, options?: FormatMoneyOptions) {
const minPrecision = options?.minPrecision ?? 0;
const maxPrecision = options?.maxPrecision ?? 2;

if (Number(value.toFixed(maxPrecision)) === 0) {
value = 0;
}

const sign = withSign && value > 0 ? '+' : '';

const parts = value.toFixed(maxPrecision).split('.');
Expand Down
24 changes: 24 additions & 0 deletions src/lib/utils/getTimeZoneOffset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Gets the time zone offset for a given time zone name.
* @param timeZone The time zone to get the offset for, e.g. 'Europe/London'.
* @param format The format of the offset. Defaults to 'shortOffset'.
* @returns The time zone offset in the specified format: '+HH:mm' or '+h'.
*/
export function getTimeZoneOffset(timeZone: string, format: 'shortOffset' | 'longOffset' = 'shortOffset') {
try {
const date = Intl.DateTimeFormat([], { timeZone, timeZoneName: format });
return date.format(new Date()).split(' ')[1].slice(3) || '+00:00';
} catch (e) {
console.warn(`Failed to get time zone offset for '${timeZone}'`, e);
return undefined;
}
}

/**
* Converts a long time zone offset to a short time zone offset.
* @param longTimezoneOffset The long time zone offset to convert, e.g. '+02:00' or '-05:00'.
* @returns The short time zone offset, e.g. '+2' or '-5'.
*/
export function toShortTimezoneOffset(longTimezoneOffset: string) {
return longTimezoneOffset.replace(/([+-])0?(\d+):00/, '$1$2');
}
1 change: 1 addition & 0 deletions src/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { deepEqual } from './deepEqual';
export { filterNotEmpty } from './filterNotEmpty';
export { formatMoney } from './formatMoney';
export { deleteSearchParam, getNumberSearchParam, getSearchParam, setSearchParam } from './getSearchParam';
export { getTimeZoneOffset, toShortTimezoneOffset } from './getTimeZoneOffset';
export { groupByKey, groupByKeyToMap, groupBySelector, groupBySelectorToMap } from './groupBy';
export { handleError } from './handleError';
export { join } from './join';
Expand Down
71 changes: 71 additions & 0 deletions src/lib/widgets/TimeZoneList.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<script lang="ts">
import dayjs from 'dayjs';
import timezones from 'timezones-list';
import { memberSettingsStore, membersService } from '$lib/data';
import { translate } from '$lib/translate';
import Input from '$lib/ui/Input.svelte';
import ListGroup from '$lib/ui/list/ListGroup.svelte';
import { showSuccessToast } from '$lib/ui/toasts';
import TimeZoneListItem from './TimeZoneListItem.svelte';
export let onClick: (timezone: string, shift: string) => void;
export let showCurrentTimeZone = true;
$: settings = $memberSettingsStore;
let search: string = '';
$: filteredTimeZones = timezones.filter(
(tz) =>
!search ||
tz.label.toLowerCase().includes(search.toLowerCase()) ||
tz.label.includes(search.replace(/([+-])(\d){1}/, '$10$2')),
);
const currentTimeZoneCode = dayjs.tz.guess();
const currentTimeZone = timezones.find((timezone) => timezone.tzCode == currentTimeZoneCode);
$: favoriteTimeZones = timezones.filter((timezone) => settings?.favoriteTimeZones?.includes(timezone.tzCode));
const addToFavorite = (timezone: string) => {
membersService.updateSettings({
favoriteTimeZones: [...(settings?.favoriteTimeZones ?? []), timezone],
});
showSuccessToast($translate('timezones.timezone_added_to_favorites'));
};
const removeFromFavorite = (timezone: string) => {
membersService.updateSettings({
favoriteTimeZones: settings?.favoriteTimeZones?.filter((x) => x !== timezone) ?? [],
});
showSuccessToast($translate('timezones.timezone_removed_from_favorites'));
};
</script>

<div class="flex-grow pt-1 px-1 pb-0">
<Input bind:value={search} placeholder={$translate('common.search')} clearable />
</div>

{#if showCurrentTimeZone && currentTimeZone}
<ListGroup title={$translate('timezones.current_time_zone')}>
<TimeZoneListItem timezone={currentTimeZone} {onClick} />
</ListGroup>
{/if}

{#if favoriteTimeZones.length > 0}
<ListGroup title={$translate('timezones.favorite_time_zones')}>
{#each favoriteTimeZones as timezone (timezone.tzCode)}
<TimeZoneListItem {timezone} {onClick} onLongClick={removeFromFavorite} />
{/each}
</ListGroup>
{/if}

<ListGroup title={$translate('timezones.all_time_zones')}>
{#each filteredTimeZones as timezone (timezone.tzCode)}
<TimeZoneListItem {timezone} {onClick} onLongClick={addToFavorite} />
{/each}
</ListGroup>

<div class="pb-1" />
Loading

1 comment on commit f3d5211

@vercel
Copy link

@vercel vercel bot commented on f3d5211 Nov 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.