Compare commits

...

89 Commits

Author SHA1 Message Date
Weblate
02c0453ff3 Translated using Weblate (French)
Currently translated at 94.4% (85 of 90 strings)

Co-authored-by: Jean-Philippe Baril <weblate.org@alias.trebaxis.net>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translation: Homebox/Frontend
2024-09-04 18:48:34 +00:00
Weblate
09358aa5b2 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Dutch)

Currently translated at 96.6% (87 of 90 strings)

Co-authored-by: Andreas Olsson <basen82@icloud.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: SKNTim <timmy444074@gmail.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/sv/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hant/
Translation: Homebox/Frontend
2024-09-03 01:00:07 +00:00
Weblate
dbe77ea19d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (90 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hant/
Translation: Homebox/Frontend
2024-09-02 02:01:14 +00:00
Weblate
85e5c7e8e7 Translated using Weblate (Chinese (Simplified))
Currently translated at 97.7% (88 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 97.7% (88 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:38:10 +00:00
Weblate
3c273b370d Translated using Weblate (Chinese (Simplified))
Currently translated at 96.6% (87 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 96.6% (87 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:37:09 +00:00
Weblate
343e56b440 Translated using Weblate (Chinese (Simplified))
Currently translated at 95.5% (86 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 95.5% (86 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:36:35 +00:00
Weblate
3a949aee5a Translated using Weblate (Chinese (Simplified))
Currently translated at 70.0% (63 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 70.0% (63 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:26:19 +00:00
Weblate
1601e52c9c Translated using Weblate (Chinese (Simplified))
Currently translated at 65.5% (59 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 65.5% (59 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:21:10 +00:00
Weblate
760cc8e35c Translated using Weblate (Chinese (Simplified))
Currently translated at 46.6% (42 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 46.6% (42 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:13:52 +00:00
Weblate
6051e1fb8b Translated using Weblate (Chinese (Simplified))
Currently translated at 45.5% (41 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 45.5% (41 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:13:02 +00:00
Weblate
7b146947df Translated using Weblate (Chinese (Simplified))
Currently translated at 36.6% (33 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 36.6% (33 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:08:11 +00:00
Weblate
5497a10f9f Translated using Weblate (Chinese (Simplified))
Currently translated at 25.5% (23 of 90 strings)

Translated using Weblate (Chinese (Simplified))

Currently translated at 25.5% (23 of 90 strings)

Co-authored-by: Jackxwb <xwb9606@163.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hans/
Translation: Homebox/Frontend
2024-09-01 16:01:32 +00:00
Weblate
3e6f4b3657 Added translation using Weblate (Chinese (Simplified))
Co-authored-by: Jackxwb <xwb9606@163.com>
2024-09-01 15:45:59 +00:00
Weblate
7baf58ad61 Translated using Weblate (Turkish)
Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (90 of 90 strings)

Co-authored-by: Hakan Bildir <divxtr@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-09-01 10:42:51 +00:00
Matt Kilgore
d72437d18c Update config.mts 2024-08-31 22:38:55 -04:00
Weblate
ea57981953 Translated using Weblate (Turkish)
Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (90 of 90 strings)

Co-authored-by: Hakan Bildir <divxtr@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-31 19:57:38 +00:00
Weblate
c2d0cce02d Translated using Weblate (Turkish)
Currently translated at 71.1% (64 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 71.1% (64 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 71.1% (64 of 90 strings)

Co-authored-by: Hakan Bildir <divxtr@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Salad <selcuk.erbek@gmail.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-31 19:51:29 +00:00
Weblate
9f7a119e95 Translated using Weblate (Russian)
Currently translated at 100.0% (90 of 90 strings)

Translated using Weblate (Turkish)

Currently translated at 58.8% (53 of 90 strings)

Co-authored-by: Fedor M <k930bx@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/ru/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-31 19:48:29 +00:00
Weblate
0dacc97e99 Translated using Weblate (French)
Currently translated at 94.4% (85 of 90 strings)

Translated using Weblate (French)

Currently translated at 94.4% (85 of 90 strings)

Co-authored-by: Jean-Philippe Baril <weblate.org@alias.trebaxis.net>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translation: Homebox/Frontend
2024-08-30 19:48:35 +00:00
Weblate
52a44da56b Translated using Weblate (French)
Currently translated at 91.1% (82 of 90 strings)

Translated using Weblate (French)

Currently translated at 91.1% (82 of 90 strings)

Co-authored-by: Jean-Philippe Baril <weblate.org@alias.trebaxis.net>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translation: Homebox/Frontend
2024-08-29 19:28:00 +00:00
Weblate
7114f262c2 Translated using Weblate (French)
Currently translated at 90.0% (81 of 90 strings)

Translated using Weblate (French)

Currently translated at 90.0% (81 of 90 strings)

Co-authored-by: Jean-Philippe Baril <weblate.org@alias.trebaxis.net>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translation: Homebox/Frontend
2024-08-29 19:13:29 +00:00
Cosmo
7647ea96d1 added the ability to add a photo in the item creation modal (#173)
* added the ability to add a photo in the item creation modal

* fixed problem with create button being hidden on tiny screens

* fix: ui, translations

---------

Co-authored-by: Matt Kilgore <matthew@kilgore.dev>
2024-08-28 20:26:45 -04:00
Oliver Larsson
593da25cdb fix: CSV export not including item notes (#180) 2024-08-28 19:44:37 -04:00
Weblate
f22bce7ccb Translated using Weblate (Russian)
Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (German)

Currently translated at 100.0% (89 of 89 strings)

Co-authored-by: Dominik <account@kowanda.net>
Co-authored-by: Fedor M <k930bx@gmail.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/de/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/ru/
Translation: Homebox/Frontend
2024-08-28 05:09:49 +00:00
Romulo Gatto
1688773bba adding email validator (#178) 2024-08-25 18:46:55 -04:00
Weblate
b56b5d2400 Translated using Weblate (Russian)
Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Russian)

Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Turkish)

Currently translated at 57.3% (51 of 89 strings)

Co-authored-by: Fedor M <k930bx@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/ru/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-25 18:48:35 +00:00
Weblate
33ee208071 Translated using Weblate (Russian)
Currently translated at 33.7% (30 of 89 strings)

Translated using Weblate (Russian)

Currently translated at 33.7% (30 of 89 strings)

Co-authored-by: Fedor M <k930bx@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/ru/
Translation: Homebox/Frontend
2024-08-24 18:39:26 +00:00
Weblate
fe880cc2c7 Translated using Weblate (Russian)
Currently translated at 25.8% (23 of 89 strings)

Translated using Weblate (Russian)

Currently translated at 25.8% (23 of 89 strings)

Co-authored-by: Fedor M <k930bx@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/ru/
Translation: Homebox/Frontend
2024-08-24 18:37:51 +00:00
Weblate
cffe57b74e Added translation using Weblate (Russian)
Co-authored-by: Fedor M <k930bx@gmail.com>
2024-08-24 18:25:04 +00:00
Weblate
66882d6fd9 Translated using Weblate (Spanish)
Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (89 of 89 strings)

Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Slydite4 <39199098+Slydite4@users.noreply.github.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/es/
Translation: Homebox/Frontend
2024-08-22 18:36:20 +00:00
Weblate
050f22f051 Translated using Weblate (Spanish)
Currently translated at 60.6% (54 of 89 strings)

Translated using Weblate (Spanish)

Currently translated at 60.6% (54 of 89 strings)

Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Slydite4 <39199098+Slydite4@users.noreply.github.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/es/
Translation: Homebox/Frontend
2024-08-22 07:24:54 +00:00
Weblate
7891af3a9a Translated using Weblate (Spanish)
Currently translated at 58.4% (52 of 89 strings)

Translated using Weblate (Spanish)

Currently translated at 58.4% (52 of 89 strings)

Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Slydite4 <39199098+Slydite4@users.noreply.github.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/es/
Translation: Homebox/Frontend
2024-08-22 07:23:48 +00:00
Weblate
40cbccf50a Translated using Weblate (Spanish)
Currently translated at 56.1% (50 of 89 strings)

Translated using Weblate (Spanish)

Currently translated at 56.1% (50 of 89 strings)

Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Slydite4 <39199098+Slydite4@users.noreply.github.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/es/
Translation: Homebox/Frontend
2024-08-22 07:23:06 +00:00
Weblate
0348da362c Translated using Weblate (Spanish)
Currently translated at 51.6% (46 of 89 strings)

Translated using Weblate (Spanish)

Currently translated at 51.6% (46 of 89 strings)

Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Slydite4 <39199098+Slydite4@users.noreply.github.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/es/
Translation: Homebox/Frontend
2024-08-22 07:21:48 +00:00
Weblate
f0a3780f3a Added translation using Weblate (Spanish)
Co-authored-by: Slydite4 <39199098+Slydite4@users.noreply.github.com>
2024-08-22 07:00:49 +00:00
Weblate
39163f3cfc Translated using Weblate (French)
Currently translated at 88.7% (79 of 89 strings)

Translated using Weblate (French)

Currently translated at 88.7% (79 of 89 strings)

Co-authored-by: Julien <hydreliox@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translation: Homebox/Frontend
2024-08-16 06:40:28 +00:00
Weblate
43676ab407 Translated using Weblate (French)
Currently translated at 77.5% (69 of 89 strings)

Translated using Weblate (French)

Currently translated at 77.5% (69 of 89 strings)

Translated using Weblate (French)

Currently translated at 77.5% (69 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 96.6% (86 of 89 strings)

Co-authored-by: Julien <hydreliox@gmail.com>
Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translation: Homebox/Frontend
2024-08-15 18:28:54 +00:00
Lukas
639f795b9a [LANGUAGE UPDATE] Frontend translations for Italian and German (#170)
* Update it.json

Translate all strings into italian and reorder alphabetically

* Update de.json

Translated all strings into German and sorted them alphabetically.

* Update it.json

Added missing commas

* Update it.json

Fix indentation and remove unnecessary curly bracket left behind during the translation

* Replace 'Edit', 'Create', and 'Other' with their Italian equivalents

* Replace 'Edit', 'Create', and 'Other' with their German equivalents
2024-08-14 09:08:12 -04:00
Weblate
fc95d2cab8 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 94.3% (84 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 94.3% (84 of 89 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: SKNTim <timmy444074@gmail.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/zh_Hant/
Translation: Homebox/Frontend
2024-08-13 18:48:34 +00:00
Weblate
695b6d68e6 Added translation using Weblate (Chinese (Traditional))
Co-authored-by: SKNTim <timmy444074@gmail.com>
2024-08-13 02:40:59 +00:00
Weblate
b6c265098d Translated using Weblate (Swedish)
Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (89 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 91.0% (81 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 91.0% (81 of 89 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: Andreas Olsson <basen82@icloud.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/sv/
Translation: Homebox/Frontend
2024-08-12 15:05:56 +00:00
Weblate
2a80d348bd Translated using Weblate (Swedish)
Currently translated at 80.8% (72 of 89 strings)

Translated using Weblate (Turkish)

Currently translated at 47.1% (42 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 74.1% (66 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 74.1% (66 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 74.1% (66 of 89 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: Andreas Olsson <basen82@icloud.com>
Co-authored-by: Hakan Bildir <divxtr@gmail.com>
Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/sv/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-12 10:16:48 +00:00
Weblate
c6542de93d Translated using Weblate (Swedish)
Currently translated at 58.4% (52 of 89 strings)

Translated using Weblate (Turkish)

Currently translated at 39.3% (35 of 89 strings)

Translated using Weblate (Turkish)

Currently translated at 39.3% (35 of 89 strings)

Translated using Weblate (French)

Currently translated at 65.1% (58 of 89 strings)

Translated using Weblate (German)

Currently translated at 58.4% (52 of 89 strings)

Translated using Weblate (Italian)

Currently translated at 39.3% (35 of 89 strings)

Translated using Weblate (Italian)

Currently translated at 39.3% (35 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 61.7% (55 of 89 strings)

Translated using Weblate (Dutch)

Currently translated at 61.7% (55 of 89 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/de/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/it/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/sv/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-11 23:45:32 +00:00
Weblate
5928678564 Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/
Translation: Homebox/Frontend
2024-08-11 23:44:45 +00:00
Matt Kilgore
fac52ca122 chore: alphabetize english JSON 2024-08-11 19:42:03 -04:00
Matt Kilgore
e9d270269f Merge remote-tracking branch 'origin/main' 2024-08-11 19:40:27 -04:00
Matt Kilgore
0a4c5fbb28 chore: translate items page 2024-08-11 19:40:13 -04:00
Weblate
2bfb0283d9 Translated using Weblate (Dutch)
Currently translated at 90.1% (55 of 61 strings)

Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translation: Homebox/Frontend
2024-08-11 19:46:14 +00:00
Weblate
94e8aee36f Translated using Weblate (French)
Currently translated at 96.7% (59 of 61 strings)

Translated using Weblate (Dutch)

Currently translated at 85.2% (52 of 61 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: Chevdor <chevdor@gmail.com>
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translate-URL: https://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translation: Homebox/Frontend
2024-08-11 19:45:11 +00:00
Matthew Kilgore
8051956a2e Deleted translation using Weblate (English (Pirate)) 2024-08-11 18:51:00 +00:00
Matt Kilgore
c7020503be Merge remote-tracking branch 'origin/main' 2024-08-11 14:09:58 -04:00
Matt Kilgore
28edce96d9 chore: Finish profile page translations 2024-08-11 14:09:51 -04:00
Weblate
b4481fcc84 Translated using Weblate (German)
Currently translated at 100.0% (53 of 53 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (53 of 53 strings)

Co-authored-by: Andreas Olsson <basen82@icloud.com>
Co-authored-by: Philipp Walter <philippwalter21@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/de/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/sv/
Translation: Homebox/Frontend
2024-08-11 07:11:39 +00:00
Weblate
2be2bebb4e Translated using Weblate (Swedish)
Currently translated at 100.0% (53 of 53 strings)

Translated using Weblate (Swedish)

Currently translated at 100.0% (53 of 53 strings)

Co-authored-by: Andreas Olsson <basen82@icloud.com>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/sv/
Translation: Homebox/Frontend
2024-08-10 05:47:28 +00:00
Weblate
d4bb8def62 Added translation using Weblate (Swedish)
Co-authored-by: Andreas Olsson <basen82@icloud.com>
2024-08-10 05:22:48 +00:00
Weblate
7442cb01b7 Translated using Weblate (French)
Currently translated at 96.2% (51 of 53 strings)

Translated using Weblate (English)

Currently translated at 100.0% (53 of 53 strings)

Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Co-authored-by: MyMemory <noreply-mt-mymemory@weblate.org>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/en/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translation: Homebox/Frontend
2024-08-09 14:48:19 +00:00
Weblate
95ba8275e8 Translated using Weblate (Dutch)
Currently translated at 92.4% (49 of 53 strings)

Translated using Weblate (French)

Currently translated at 98.1% (52 of 53 strings)

Translated using Weblate (English (Pirate))

Currently translated at 13.3% (6 of 45 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: thhurt <th.hurtado+weblate@gmail.com>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/en@pirate/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translation: Homebox/Frontend
2024-08-08 14:45:24 +00:00
Matt Kilgore
2f4a0dd212 fix: #146 add version info to every page 2024-08-07 21:55:05 -04:00
Matt Kilgore
52a621e9ba fix: use the browser default language 2024-08-07 20:57:40 -04:00
Matt Kilgore
1f77fad829 fix: i18n ICU loading failure due to original auto-loading. 2024-08-07 20:26:40 -04:00
Weblate
8d93a3f56e Translated using Weblate (German)
Currently translated at 100.0% (35 of 35 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (35 of 35 strings)

Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/de/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/it/
Translation: Homebox/Frontend
2024-08-06 13:54:10 +00:00
Weblate
9c572e7ab2 Translated using Weblate (French)
Currently translated at 100.0% (35 of 35 strings)

Translated using Weblate (Turkish)

Currently translated at 100.0% (35 of 35 strings)

Translated using Weblate (German)

Currently translated at 100.0% (35 of 35 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (35 of 35 strings)

Co-authored-by: Hakan Bildir <divxtr@gmail.com>
Co-authored-by: Jean-Philippe Baril <weblate.org@alias.trebaxis.net>
Co-authored-by: Lukas Hofer <naluso@protonmail.com>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/de/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/fr/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/it/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/tr/
Translation: Homebox/Frontend
2024-08-05 13:04:00 +00:00
A3
1f15e74730 changed companyname and url to sysadminsmedia.com (#158) 2024-08-05 08:59:53 -04:00
Weblate
7570a04c02 Added translation using Weblate (Turkish)
Co-authored-by: Hakan Bildir <divxtr@gmail.com>
2024-08-05 07:56:36 +00:00
Weblate
fc2e89c448 Added translation using Weblate (French)
Co-authored-by: Jean-Philippe Baril <weblate.org@alias.trebaxis.net>
2024-08-05 07:56:25 +00:00
Weblate
be216ff7fe Translated using Weblate (German)
Currently translated at 40.0% (14 of 35 strings)

Co-authored-by: Benjamin Kahlau <nyhkkbjyek@roanapur.de>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/de/
Translation: Homebox/Frontend
2024-08-05 00:10:39 +00:00
Weblate
388208571b Added translation using Weblate (German)
Co-authored-by: Benjamin Kahlau <nyhkkbjyek@roanapur.de>
2024-08-04 22:34:52 +00:00
Weblate
1891903007 Translated using Weblate (English (Pirate))
Currently translated at 11.4% (4 of 35 strings)

Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/en@pirate/
Translation: Homebox/Frontend
2024-08-04 22:25:05 +00:00
Matt Kilgore
41a7e73ff4 Merge remote-tracking branch 'origin/main' 2024-08-04 17:36:11 -04:00
Matt Kilgore
81d9fb0700 chore: add translations to contributions sections 2024-08-04 17:36:02 -04:00
Weblate
76312d6eb6 Added translation using Weblate (Italian)
Co-authored-by: Lukas Hofer <naluso@protonmail.com>
2024-08-04 21:26:53 +00:00
Weblate
f31528c841 Added translation using Weblate (English (Pirate))
Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
2024-08-04 20:53:17 +00:00
Weblate
6d869fdece Translated using Weblate (Dutch)
Currently translated at 100.0% (35 of 35 strings)

Translated using Weblate (English)

Currently translated at 100.0% (35 of 35 strings)

Co-authored-by: 101br03k <warmerdamm03@gmail.com>
Co-authored-by: Weblate Admin <admin@sysadminsmedia.com>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/en/
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/nl/
Translation: Homebox/Frontend
2024-08-04 20:16:58 +00:00
Weblate
d0784a7773 Added translation using Weblate (Dutch)
Co-authored-by: Matthew Kilgore <matthew@kilgore.dev>
2024-08-04 19:27:09 +00:00
Weblate Admin
791f843bc8 Deleted translation using Weblate (Chinese (Simplified)) 2024-08-04 18:21:20 +00:00
Matt Kilgore
a0cdb231fd chore: translate components 2024-08-04 14:08:05 -04:00
Matt Kilgore
e0004842e6 fix: bad translation 2024-08-04 13:37:37 -04:00
Matt Kilgore
fdbfa0e76f refactor: better translation formatting 2024-08-04 13:11:27 -04:00
Matt Kilgore
005516013f chore: delete unneeded translation file 2024-08-04 12:56:12 -04:00
Weblate
9ec3dd4b16 Added translation using Weblate (Chinese (Simplified))
Translated using Weblate (English)

Currently translated at 100.0% (19 of 19 strings)

Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Weblate Admin <admin@sysadminsmedia.com>
Translate-URL: http://translate.sysadminsmedia.com/projects/homebox/frontend/en/
Translation: Homebox/Frontend
2024-08-04 16:47:43 +00:00
Matt Kilgore
4dacf981a9 Merge branch 'refs/heads/mk/i18n'
# Conflicts:
#	frontend/pages/index.vue
2024-08-04 11:35:37 -04:00
Matt Kilgore
9f7b76b37d chore: minor tweak 2024-08-04 11:31:16 -04:00
Matt Kilgore
0d51558e74 chore: more translations 2024-08-04 11:26:07 -04:00
Matt Kilgore
236c257892 feat: adding initial i18n support (#155) 2024-08-04 11:02:29 -04:00
Matt Kilgore
3540ce4297 feat: adding initial i18n support 2024-08-03 23:04:26 -04:00
Rylie Pavlik
0bcb155756 Fixes to the Tools page (#154)
* Correct the description of the import feature on the tools page.

* Fix page title on Tools page.
2024-08-01 21:52:13 -04:00
Fuzzy
12219522ab Document search tips, cleanup documentation (#152)
* Update tips-tricks.md

Add instructions for search by ID

* Update get-started.md

Fixing typos and redundancies
2024-07-31 19:51:43 -04:00
Katos
13864997ab Merge pull request #149 from victorhooi/patch-1
Fix small typo in label discussion thread URL
2024-07-27 16:01:35 +01:00
Victor Hooi
2ab2766534 Fix small typo in label discussion thread URL 2024-07-28 00:56:49 +10:00
36 changed files with 9070 additions and 5441 deletions

View File

@@ -49,6 +49,11 @@ Contributions are what make the open source community such an amazing place to l
If you are not a coder, you can still contribute financially. Financial contributions help me prioritize working on this project over others and helps me know that there is a real demand for project development. If you are not a coder, you can still contribute financially. Financial contributions help me prioritize working on this project over others and helps me know that there is a real demand for project development.
## Help us Translate
We want to make sure that Homebox is available in as many languages as possible. If you are interested in helping us translate Homebox, please help us via our [Weblate instance](https://translate.sysadminsmedia.com/projects/homebox/).
[![Translation status](http://translate.sysadminsmedia.com/widget/homebox/multi-auto.svg)](http://translate.sysadminsmedia.com/engage/homebox/)
## Credits ## Credits
- Original project by [@hay-kot](https://github.com/hay-kot) - Original project by [@hay-kot](https://github.com/hay-kot)

View File

@@ -4,12 +4,6 @@ import (
"embed" "embed"
"errors" "errors"
"fmt" "fmt"
"io"
"mime"
"net/http"
"path"
"path/filepath"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/hay-kot/httpkit/errchain" "github.com/hay-kot/httpkit/errchain"
httpSwagger "github.com/swaggo/http-swagger/v2" // http-swagger middleware httpSwagger "github.com/swaggo/http-swagger/v2" // http-swagger middleware
@@ -19,6 +13,11 @@ import (
_ "github.com/sysadminsmedia/homebox/backend/app/api/static/docs" _ "github.com/sysadminsmedia/homebox/backend/app/api/static/docs"
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles" "github.com/sysadminsmedia/homebox/backend/internal/data/ent/authroles"
"github.com/sysadminsmedia/homebox/backend/internal/data/repo" "github.com/sysadminsmedia/homebox/backend/internal/data/repo"
"io"
"mime"
"net/http"
"path"
"path/filepath"
) )
const prefix = "/api" const prefix = "/api"

View File

@@ -222,6 +222,7 @@ func (s *IOSheet) ReadItems(ctx context.Context, items []repo.ItemOut, GID uuid.
SoldPrice: item.SoldPrice, SoldPrice: item.SoldPrice,
SoldNotes: item.SoldNotes, SoldNotes: item.SoldNotes,
Notes: item.Notes,
Fields: customFields, Fields: customFields,
} }
} }

View File

@@ -29,9 +29,9 @@ func (tp *TemplateProps) Set(key, value string) {
func DefaultTemplateData() TemplateProps { func DefaultTemplateData() TemplateProps {
return TemplateProps{ return TemplateProps{
Defaults: TemplateDefaults{ Defaults: TemplateDefaults{
CompanyName: "Haybytes.com", CompanyName: "sysadminsmedia.com",
CompanyAddress: "123 Main St, Anytown, CA 12345", CompanyAddress: "123 Main St, Anytown, CA 12345",
CompanyURL: "https://haybytes.com", CompanyURL: "https://sysadminsmedia.com",
ActivateAccountURL: "https://google.com", ActivateAccountURL: "https://google.com",
UnsubscribeURL: "https://google.com", UnsubscribeURL: "https://google.com",
}, },

View File

@@ -6,7 +6,7 @@ export default defineConfig({
description: "A simple home inventory management software", description: "A simple home inventory management software",
lastUpdated: true, lastUpdated: true,
sitemap: { sitemap: {
hostname: 'https://homebox.sysadminsmedia.com', hostname: 'https://homebox.software',
}, },
locales: { locales: {

View File

@@ -47,24 +47,28 @@ type checking `task ui:check`
## Documentation ## Documentation
We use [Vitepress](https://vitepress.dev/) for the web documentation of homebox. Anyone is welcome to contribute the documentation if they wish. We use [Vitepress](https://vitepress.dev/) for the web documentation of homebox. Anyone is welcome to contribute the documentation if they wish.
Anyone is welcome to contribute the documentation if they wish. For documentation contributions, you only need Node.js and PNPM. For documentation contributions, you only need Node.js and PNPM.
::: info Notes ::: info Notes
- Languages are separated by folder (e.g `/en`, `/fr`, etc.) - Languages are separated by folder (e.g `/en`, `/fr`, etc.)
- The Sidebar must be updated on a per language basis - The Sidebar must be updated on a per language basis
+ The Sidebar must be updated on a per-language basis - Each language's files can be named independently (slugs can match the language)
- Each languages files can be named independently (slugs can match the language)
- The `public/_redirects` file is used to redirect the default to english - The `public/_redirects` file is used to redirect the default to english
- Redirects can also be configured per language by adding `Language=` after the redirect code - Redirects can also be configured per language by adding `Language=` after the redirect code
::: :::
## Translations
We use our own [Weblate instance](https://translate.sysadminsmedia.com/projects/homebox/) for translations. If you would like to help translate Homebox, please visit the Weblate instance and help us translate the project.
[![Translation status](http://translate.sysadminsmedia.com/widget/homebox/multi-auto.svg)](http://translate.sysadminsmedia.com/engage/homebox/)
## Branch Flow ## Branch Flow
We use the `main` branch as the development branch. All PRs should be made to the `main` branch form a feature branch. We use the `main` branch as the development branch. All PRs should be made to the `main` branch from a feature branch.
To create a pull request you can use the following steps: To create a pull request you can use the following steps:
1. Fork the repo and create a new branch from `main` 1. Fork the repo and create a new branch from `main`
2. If you added code that should be tested, add tests 2. If you added code that should be tested, add tests
3. If you've changed APIs update the documentation 3. If you've changed APIs, update the documentation
4. Ensure that the test suite and linters pass 4. Ensure that the test suite and linters pass
5. Create your PR 5. Create your PR

View File

@@ -21,6 +21,8 @@ Homebox provides the option to auto-set asset IDs, this is the default behavior.
Example ID: `000-001` Example ID: `000-001`
To search for an Asset ID: type `#` in the search bar followed by the ID you're searching for, e.g. `#000-001`.
Asset IDs are partially managed by Homebox, but have a flexible implementation to allow for unique use cases. IDs are non-unique at the database level, so there is nothing stopping a user from manually setting duplicate IDs for various items. There are two recommended approaches to manage Asset IDs: Asset IDs are partially managed by Homebox, but have a flexible implementation to allow for unique use cases. IDs are non-unique at the database level, so there is nothing stopping a user from manually setting duplicate IDs for various items. There are two recommended approaches to manage Asset IDs:
### 1. Auto Incrementing IDs ### 1. Auto Incrementing IDs

View File

@@ -1,9 +1,8 @@
<template> <template>
<BaseModal v-model="dialog"> <BaseModal v-model="dialog">
<template #title> Import CSV File </template> <template #title> {{ $t("components.app.import_dialog.title") }} </template>
<p> <p>
Import a CSV file containing your items, labels, and locations. See documentation for more information on the {{ $t("components.app.import_dialog.description") }}
required format.
</p> </p>
<div class="alert alert-warning shadow-lg mt-4"> <div class="alert alert-warning shadow-lg mt-4">
<div> <div>
@@ -21,8 +20,7 @@
/> />
</svg> </svg>
<span class="text-sm"> <span class="text-sm">
Behavior for imports with existing import_refs has changed. If an import_ref is present in the CSV file, the {{ $t("components.app.import_dialog.change_warning") }}
item will be updated with the values in the CSV file.
</span> </span>
</div> </div>
</div> </div>
@@ -33,7 +31,7 @@
<BaseButton type="button" @click="uploadCsv"> <BaseButton type="button" @click="uploadCsv">
<MdiUpload class="h-5 w-5 mr-2" /> <MdiUpload class="h-5 w-5 mr-2" />
Upload {{ $t("components.app.import_dialog.upload") }}
</BaseButton> </BaseButton>
<p class="text-center pt-4 -mb-5"> <p class="text-center pt-4 -mb-5">
{{ importCsv?.name }} {{ importCsv?.name }}
@@ -41,7 +39,7 @@
</div> </div>
<div class="modal-action"> <div class="modal-action">
<BaseButton type="submit" :disabled="!importCsv"> Submit </BaseButton> <BaseButton type="submit" :disabled="!importCsv"> {{ $t("global.submit") }} </BaseButton>
</div> </div>
</form> </form>
</BaseModal> </BaseModal>

View File

@@ -1,19 +1,25 @@
<template> <template>
<BaseModal v-model="modal"> <BaseModal v-model="modal">
<template #title> Create Item </template> <template #title> {{ $t("components.item.create_modal.title") }} </template>
<form @submit.prevent="create()"> <form @submit.prevent="create()">
<LocationSelector v-model="form.location" /> <LocationSelector v-model="form.location" />
<FormTextField ref="nameInput" v-model="form.name" :trigger-focus="focused" :autofocus="true" label="Item Name" /> <FormTextField ref="nameInput" v-model="form.name" :trigger-focus="focused" :autofocus="true" label="Item Name" />
<FormTextArea v-model="form.description" label="Item Description" /> <FormTextArea v-model="form.description" label="Item Description" />
<FormMultiselect v-model="form.labels" label="Labels" :items="labels ?? []" /> <FormMultiselect v-model="form.labels" label="Labels" :items="labels ?? []" />
<div class="modal-action"> <div class="modal-action">
<div class="flex justify-center"> <div class="flex justify-center">
<div>
<label for="photo" class="btn">{{ $t("components.item.create_modal.photo_button") }}</label>
<input type="file" accept="image/*" @change="previewImage" style="visibility:hidden;" id="photo">
</div>
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> <BaseButton class="rounded-r-none" :loading="loading" type="submit">
<template #icon> <template #icon>
<MdiPackageVariant class="swap-off h-5 w-5" /> <MdiPackageVariant class="swap-off h-5 w-5" />
<MdiPackageVariantClosed class="swap-on h-5 w-5" /> <MdiPackageVariantClosed class="swap-on h-5 w-5" />
</template> </template>
Create {{ $t("global.create") }}
</BaseButton> </BaseButton>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl"> <label tabindex="0" class="btn rounded-l-none rounded-r-xl">
@@ -21,12 +27,23 @@
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li> <li>
<button type="button" @click="create(false)">Create and Add Another</button> <button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<!-- photo preview area is AFTER the create button, to avoid pushing the button below the screen on small displays -->
<div class="border-t border-gray-300 p-4">
<template v-if="form.preview">
<p class="mb-0">file name: {{ form.photo.name }}</p>
<img :src="form.preview" class="h-[100px] w-full object-cover rounded-t shadow-sm border-gray-300" />
</template>
</div>
</form> </form>
<p class="text-sm text-center mt-4"> <p class="text-sm text-center mt-4">
use <kbd class="kbd kbd-xs">Shift</kbd> + <kbd class="kbd kbd-xs"> Enter </kbd> to create and add another use <kbd class="kbd kbd-xs">Shift</kbd> + <kbd class="kbd kbd-xs"> Enter </kbd> to create and add another
@@ -41,6 +58,7 @@
import MdiPackageVariant from "~icons/mdi/package-variant"; import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPackageVariantClosed from "~icons/mdi/package-variant-closed"; import MdiPackageVariantClosed from "~icons/mdi/package-variant-closed";
import MdiChevronDown from "~icons/mdi/chevron-down"; import MdiChevronDown from "~icons/mdi/chevron-down";
import { AttachmentTypes } from "~~/lib/api/types/non-generated";
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
@@ -85,10 +103,40 @@
description: "", description: "",
color: "", // Future! color: "", // Future!
labels: [] as LabelOut[], labels: [] as LabelOut[],
preview: null,
photo: null
}); });
const { shift } = useMagicKeys(); const { shift } = useMagicKeys();
function previewImage(event) {
var input = event.target;
if (input.files) {
var reader = new FileReader();
reader.onload = (e) => {
form.preview = e.target.result;
}
form.photo=input.files[0];
reader.readAsDataURL(input.files[0]);
}
}
function uploadImage(e: Event) {
const files = (e.target as HTMLInputElement).files;
if (!files || !files.item(0)) {
return;
}
const first = files.item(0);
if (!first) {
return;
}
uploadAttachment([first], null);
}
whenever( whenever(
() => modal.value, () => modal.value,
() => { () => {
@@ -133,10 +181,25 @@
toast.success("Item created"); toast.success("Item created");
// if the photo was provided, upload it
if(form.photo){
const { data2, error } = await api.items.attachments.add(data.id, form.photo, form.photo.name, AttachmentTypes.Photo);
if (error) {
toast.error("Failed to upload Photo");
return;
}
toast.success("Photo uploaded");
}
// Reset // Reset
form.name = ""; form.name = "";
form.description = ""; form.description = "";
form.color = ""; form.color = "";
form.preview = null;
form.photo = null;
focused.value = false; focused.value = false;
loading.value = false; loading.value = false;

View File

@@ -29,7 +29,7 @@
<template> <template>
<section> <section>
<BaseSectionHeader class="mb-2 flex justify-between items-center"> <BaseSectionHeader class="mb-2 flex justify-between items-center">
Items {{ $t("components.item.view.selectable.items") }}
<template #description> <template #description>
<div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left"> <div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left">
<label tabindex="0" class="btn btn-ghost m-1"> <label tabindex="0" class="btn btn-ghost m-1">
@@ -39,13 +39,13 @@
<li> <li>
<button @click="setViewPreference('card')"> <button @click="setViewPreference('card')">
<MdiCardTextOutline class="h-5 w-5" /> <MdiCardTextOutline class="h-5 w-5" />
Card {{ $t("components.item.view.selectable.card") }}
</button> </button>
</li> </li>
<li> <li>
<button @click="setViewPreference('table')"> <button @click="setViewPreference('table')">
<MdiTable class="h-5 w-5" /> <MdiTable class="h-5 w-5" />
Table {{ $t("components.item.view.selectable.table") }}
</button> </button>
</li> </li>
</ul> </ul>
@@ -59,7 +59,7 @@
<template v-else> <template v-else>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4"> <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
<ItemCard v-for="item in items" :key="item.id" :item="item" /> <ItemCard v-for="item in items" :key="item.id" :item="item" />
<div class="first:block hidden text-lg">No Items to Display</div> <div class="first:block hidden text-lg">{{ $t("components.item.view.selectable.no_items") }}</div>
</div> </div>
</template> </template>
</section> </section>

View File

@@ -1,6 +1,6 @@
<template> <template>
<BaseModal v-model="modal"> <BaseModal v-model="modal">
<template #title> Create Label </template> <template #title>{{ $t("components.label.create_modal.title") }}</template>
<form @submit.prevent="create()"> <form @submit.prevent="create()">
<FormTextField <FormTextField
ref="locationNameRef" ref="locationNameRef"
@@ -12,14 +12,14 @@
<FormTextArea v-model="form.description" label="Label Description" /> <FormTextArea v-model="form.description" label="Label Description" />
<div class="modal-action"> <div class="modal-action">
<div class="flex justify-center"> <div class="flex justify-center">
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> Create </BaseButton> <BaseButton class="rounded-r-none" :loading="loading" type="submit"> {{ $t("global.create") }} </BaseButton>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl"> <label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<MdiChevronDown class="h-5 w-5" /> <MdiChevronDown class="h-5 w-5" />
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li> <li>
<button type="button" @click="create(false)">Create and Add Another</button> <button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
</li> </li>
</ul> </ul>
</div> </div>

View File

@@ -1,6 +1,6 @@
<template> <template>
<BaseModal v-model="modal"> <BaseModal v-model="modal">
<template #title> Create Location </template> <template #title>{{ $t("components.location.create_modal.title") }}</template>
<form @submit.prevent="create()"> <form @submit.prevent="create()">
<FormTextField <FormTextField
ref="locationNameRef" ref="locationNameRef"
@@ -13,14 +13,14 @@
<LocationSelector v-model="form.parent" /> <LocationSelector v-model="form.parent" />
<div class="modal-action"> <div class="modal-action">
<div class="flex justify-center"> <div class="flex justify-center">
<BaseButton class="rounded-r-none" type="submit" :loading="loading"> Create </BaseButton> <BaseButton class="rounded-r-none" type="submit" :loading="loading">{{ $t("global.create") }}</BaseButton>
<div class="dropdown dropdown-top"> <div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl"> <label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<MdiChevronDown class="h-5 w-5" /> <MdiChevronDown class="h-5 w-5" />
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li> <li>
<button type="button" @click="create(false)">Create and Add Another</button> <button type="button" @click="create(false)">{{ $t("global.create_and_add") }}</button>
</li> </li>
</ul> </ul>
</div> </div>

View File

@@ -1,11 +1,11 @@
<template> <template>
<BaseModal v-model="isRevealed" readonly @cancel="cancel(false)"> <BaseModal v-model="isRevealed" readonly @cancel="cancel(false)">
<template #title> Confirm </template> <template #title> {{ $t("global.confirm") }} </template>
<div> <div>
<p>{{ text }}</p> <p>{{ text }}</p>
</div> </div>
<div class="modal-action"> <div class="modal-action">
<BaseButton type="submit" @click="confirm(true)"> Confirm </BaseButton> <BaseButton type="submit" @click="confirm(true)"> {{ $t("global.confirm") }} </BaseButton>
</div> </div>
</BaseModal> </BaseModal>
</template> </template>

View File

@@ -7,7 +7,7 @@
</slot> </slot>
<div tabindex="0" class="card compact dropdown-content shadow-lg bg-base-100 rounded-box w-64"> <div tabindex="0" class="card compact dropdown-content shadow-lg bg-base-100 rounded-box w-64">
<div class="card-body"> <div class="card-body">
<h2 class="text-center">Page URL</h2> <h2 class="text-center">{{ $t("components.global.page_qr_code.page_url") }}</h2>
<img :src="getQRCodeUrl()" /> <img :src="getQRCodeUrl()" />
</div> </div>
</div> </div>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="py-4"> <div class="py-4">
<p class="text-sm">Password Strength: {{ message }}</p> <p class="text-sm">{{ $t("components.global.password_score.password_strength") }}: {{ message }}</p>
<progress <progress
class="progress w-full progress-bar" class="progress w-full progress-bar"
:value="score" :value="score"

View File

@@ -29,6 +29,12 @@
</div> </div>
<slot></slot> <slot></slot>
<footer v-if="status" class="text-center w-full bottom-0 pb-4 bg-base-300 text-secondary-content">
<p class="text-center text-sm">
{{ $t("global.version", { version: status.build.version }) }} ~
{{ $t("global.build", { build: status.build.commit }) }}
</p>
</footer>
</div> </div>
<!-- Sidebar --> <!-- Sidebar -->
@@ -39,7 +45,7 @@
<div class="w-60 py-5 md:py-10 bg-base-200 flex flex-grow-1 flex-col"> <div class="w-60 py-5 md:py-10 bg-base-200 flex flex-grow-1 flex-col">
<div class="space-y-8"> <div class="space-y-8">
<div class="flex flex-col items-center gap-4"> <div class="flex flex-col items-center gap-4">
<p>Welcome, {{ username }}</p> <p>{{ $t("global.welcome", { username: username }) }}</p>
<NuxtLink class="avatar placeholder" to="/home"> <NuxtLink class="avatar placeholder" to="/home">
<div class="bg-base-300 text-neutral-content rounded-full w-24 p-4"> <div class="bg-base-300 text-neutral-content rounded-full w-24 p-4">
<AppLogo /> <AppLogo />
@@ -53,7 +59,7 @@
<span> <span>
<MdiPlus class="mr-1 -ml-1" /> <MdiPlus class="mr-1 -ml-1" />
</span> </span>
Create {{ $t("global.create") }}
</label> </label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-40"> <ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-40">
<li v-for="btn in dropdown" :key="btn.name"> <li v-for="btn in dropdown" :key="btn.name">
@@ -83,7 +89,9 @@
</div> </div>
<!-- Bottom --> <!-- Bottom -->
<button class="mt-auto mx-2 hover:bg-base-300 p-3 rounded-btn" @click="logout">Sign Out</button> <button class="mt-auto mx-2 hover:bg-base-300 p-3 rounded-btn" @click="logout">
{{ $t("global.sign_out") }}
</button>
</div> </div>
</div> </div>
</div> </div>
@@ -101,12 +109,17 @@
import MdiMagnify from "~icons/mdi/magnify"; import MdiMagnify from "~icons/mdi/magnify";
import MdiAccount from "~icons/mdi/account"; import MdiAccount from "~icons/mdi/account";
import MdiCog from "~icons/mdi/cog"; import MdiCog from "~icons/mdi/cog";
const username = computed(() => authCtx.user?.name || "User"); const username = computed(() => authCtx.user?.name || "User");
const pubApi = usePublicApi();
const { data: status } = useAsyncData(async () => {
const { data } = await pubApi.status();
return data;
});
// Preload currency format // Preload currency format
useFormatCurrency(); useFormatCurrency();
const modals = reactive({ const modals = reactive({
item: false, item: false,
location: false, location: false,

127
frontend/locales/de.json Normal file
View File

@@ -0,0 +1,127 @@
{
"components": {
"app": {
"import_dialog": {
"change_warning": "Das Verhalten beim Importieren vorhandener import_refs hat sich geändert. Wenn ein import_ref in der CSV-Datei vorhanden ist, wird der Gegenstand mit den Werten in der CSV-Datei aktualisiert.",
"description": "Importiere eine CSV-Datei, die deine Gegenstände, Etiketten und Standorte enthält. Siehe Dokumentation für weitere Informationen zum \nerforderlichen Format.",
"title": "Importiere CSV-Datei",
"upload": "Hochladen"
}
},
"global": {
"page_qr_code": {
"page_url": "Seiten-URL"
},
"password_score": {
"password_strength": "Passwortstärke"
}
},
"item": {
"create_modal": {
"title": "Erstelle Gegenstand"
},
"view": {
"selectable": {
"card": "Karte",
"items": "Gegenstände",
"no_items": "Keine Gegenstände anzuzeigen",
"table": "Tabelle"
}
}
},
"label": {
"create_modal": {
"title": "Erstelle Etikette"
}
},
"location": {
"create_modal": {
"title": "Erstelle Standort"
}
}
},
"global": {
"build": "Build: { build }",
"confirm": "Bestätigen",
"create": "Erstellen",
"create_and_add": "Erstellen und weiteren hinzufügen",
"created": "Erstellt",
"email": "E-Mail",
"follow_dev": "Dem Entwickler folgen",
"github": "GitHub-Projekt",
"items": "Gegenstände",
"join_discord": "Discord beitreten",
"labels": "Etiketten",
"locations": "Standorte",
"name": "Name",
"password": "Passwort",
"read_docs": "Dokumentation lesen",
"search": "Suchen",
"sign_out": "Abmelden",
"submit": "Einreichen",
"version": "Version: { version }",
"welcome": "Willkommen, { username }"
},
"index": {
"disabled_registration": "Registrierung deaktiviert",
"dont_join_group": "Möchtest du nicht einer Gruppe beitreten?",
"joining_group": "Du trittst einer bereits bestehenden Gruppe bei!",
"login": "Anmelden",
"register": "Registrieren",
"remember_me": "Angemeldet bleiben",
"set_email": "Was ist deine E-Mail?",
"set_name": "Wie heißt du?",
"set_password": "Setze dein Passwort",
"tagline": "Verfolgen, Organisieren und Verwalten deiner Sachen."
},
"items": {
"add": "Hinzufügen",
"created_at": "Erstellt am",
"custom_fields": "Benutzerdefinierte Felder",
"field_selector": "Feldauswahl",
"field_value": "Feldwert",
"first": "Erste",
"include_archive": "Archivierte Elemente einbeziehen",
"last": "Letzte",
"negate_labels": "Ausgewählte Etiketten negieren",
"next_page": "Nächste Seite",
"no_results": "Keine Elemente gefunden",
"options": "Optionen",
"order_by": "Sortieren nach",
"pages": "Seite { page } von { totalPages }",
"prev_page": "Vorherige Seite",
"query_id": "Abfrage Asset-ID-Nummer: { id }",
"reset_search": "Suche zurücksetzen",
"results": "{ total } Ergebnisse",
"tip_1": "Standort- und Etikettenfilter verwenden die 'ODER'-Operation. Wenn mehr als eines ausgewählt ist, wird\n nur eines für eine Übereinstimmung benötigt.",
"tip_2": "Suchen, die mit '#' beginnen, fragen nach einer Asset-ID (Beispiel '#000-001')",
"tip_3": "Feldfilter verwenden die 'ODER'-Operation. Wenn mehr als eines ausgewählt ist, wird nur eines\n für eine Übereinstimmung benötigt.",
"tips": "Tipps",
"tips_sub": "Suchtipps",
"updated_at": "Aktualisiert am"
},
"profile": {
"active": "Aktiv",
"change_password": "Passwort ändern",
"currency_format": "Währungsformat",
"current_password": "Aktuelles Passwort",
"delete_account": "Konto löschen",
"delete_account_sub": "Löschen Sie Ihr Konto und alle zugehörigen Daten. Dies kann nicht rückgängig gemacht werden.",
"enabled": "Aktiviert",
"gen_invite": "Einladungslink generieren",
"group_settings": "Gruppeneinstellungen",
"group_settings_sub": "Geteilte Gruppeneinstellungen. Möglicherweise müssen Sie Ihren Browser aktualisieren, damit einige Einstellungen wirksam werden.",
"inactive": "Inaktiv",
"new_password": "Neues Passwort",
"notifier_modal": "{ type, select, true {Bearbeiten} false {Erstellen} other {Andere}} Melder",
"notifiers": "Melder",
"notifiers_sub": "Erhalten Sie Benachrichtigungen für bevorstehende Wartungserinnerungen",
"test": "Test",
"theme_settings": "Themeneinstellungen",
"theme_settings_sub": "Themeneinstellungen werden im lokalen Speicher Ihres Browsers gespeichert. Sie können das Thema jederzeit ändern. Wenn Sie Probleme haben, Ihr Thema einzustellen, versuchen Sie, Ihren Browser zu aktualisieren.",
"update_group": "Gruppe aktualisieren",
"url": "URL",
"user_profile": "Benutzerprofil",
"user_profile_sub": "Benutzer einladen und Ihr Konto verwalten."
}
}

128
frontend/locales/en.json Normal file
View File

@@ -0,0 +1,128 @@
{
"components": {
"app": {
"import_dialog": {
"change_warning": "Behavior for imports with existing import_refs has changed. If an import_ref is present in the CSV file, the \nitem will be updated with the values in the CSV file.",
"description": "Import a CSV file containing your items, labels, and locations. See documentation for more information on the \nrequired format.",
"title": "Import CSV File",
"upload": "Upload"
}
},
"global": {
"page_qr_code": {
"page_url": "Page URL"
},
"password_score": {
"password_strength": "Password Strength"
}
},
"item": {
"create_modal": {
"title": "Create Item",
"photo_button": "Photo \uD83D\uDCF7"
},
"view": {
"selectable": {
"card": "Card",
"items": "Items",
"no_items": "No Items to Display",
"table": "Table"
}
}
},
"label": {
"create_modal": {
"title": "Create Label"
}
},
"location": {
"create_modal": {
"title": "Create Location"
}
}
},
"global": {
"build": "Build: { build }",
"confirm": "Confirm",
"create": "Create",
"create_and_add": "Create and Add Another",
"created": "Created",
"email": "Email",
"follow_dev": "Follow the Developer",
"github": "GitHub Project",
"items": "Items",
"join_discord": "Join the Discord",
"labels": "Labels",
"locations": "Locations",
"name": "Name",
"password": "Password",
"read_docs": "Read the Docs",
"search": "Search",
"sign_out": "Sign Out",
"submit": "Submit",
"version": "Version: { version }",
"welcome": "Welcome, { username }"
},
"index": {
"disabled_registration": "Registration Disabled",
"dont_join_group": "Don't want to join a group?",
"joining_group": "You're Joining an Existing Group!",
"login": "Login",
"register": "Register",
"remember_me": "Remember Me",
"set_email": "What's your email?",
"set_name": "What's your name?",
"set_password": "Set your password",
"tagline": "Track, Organize, and Manage your Things."
},
"items": {
"add": "Add",
"created_at": "Created At",
"custom_fields": "Custom Fields",
"field_selector": "Field Selector",
"field_value": "Field Value",
"first": "First",
"include_archive": "Include Archived Items",
"last": "Last",
"negate_labels": "Negate Selected Labels",
"next_page": "Next Page",
"no_results": "No Items Found",
"options": "Options",
"order_by": "Order By",
"pages": "Page { page } of { totalPages }",
"prev_page": "Previous Page",
"query_id": "Querying Asset ID Number: { id }",
"reset_search": "Reset Search",
"results": "{ total } Results",
"tip_1": "Location and label filters use the 'OR' operation. If more than one is selected only one will be\n required for a match.",
"tip_2": "Searches prefixed with '#'' will query for a asset ID (example '#000-001')",
"tip_3": "Field filters use the 'OR' operation. If more than one is selected only one will be required for a\n match.",
"tips": "Tips",
"tips_sub": "Search Tips",
"updated_at": "Updated At"
},
"profile": {
"active": "Active",
"change_password": "Change Password",
"currency_format": "Currency Format",
"current_password": "Current Password",
"delete_account": "Delete Account",
"delete_account_sub": "Delete your account and all its associated data. This can not be undone.",
"enabled": "Enabled",
"gen_invite": "Generate Invite Link",
"group_settings": "Group Settings",
"group_settings_sub": "Shared Group Settings. You may need to refresh your browser for some settings to apply.",
"inactive": "Inactive",
"new_password": "New Password",
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Notifier",
"notifiers": "Notifiers",
"notifiers_sub": "Get notifications for upcoming maintenance reminders",
"test": "Test",
"theme_settings": "Theme Settings",
"theme_settings_sub": "Theme settings are stored in your browser's local storage. You can change the theme at any time. If you're\n having trouble setting your theme try refreshing your browser.",
"update_group": "Update Group",
"url": "URL",
"user_profile": "User Profile",
"user_profile_sub": "Invite users, and manage your account."
}
}

127
frontend/locales/es.json Normal file
View File

@@ -0,0 +1,127 @@
{
"components": {
"app": {
"import_dialog": {
"change_warning": "Se ha modificado el comportamiento de las importaciones con import_refs existentes. Si existe una import_ref en el archivo CSV, el \nelemento se actualizará con los valores del archivo CSV.",
"description": "Importa un archivo CSV que contenga tus elementos, etiquetas y ubicaciones. Consulta la documentación para obtener más información sobre el \nformato requerido.",
"title": "Importar Archivo CSV",
"upload": "Subir"
}
},
"global": {
"page_qr_code": {
"page_url": "URL de página"
},
"password_score": {
"password_strength": "Seguridad de la contraseña"
}
},
"item": {
"create_modal": {
"title": "Crear Elemento"
},
"view": {
"selectable": {
"card": "Tarjeta",
"items": "Elementos",
"no_items": "No hay elementos para mostrar",
"table": "Tabla"
}
}
},
"label": {
"create_modal": {
"title": "Crear Etiqueta"
}
},
"location": {
"create_modal": {
"title": "Crear Ubicación"
}
}
},
"global": {
"build": "Compilación: { build }",
"confirm": "Confirmar",
"create": "Crear",
"created": "Creado",
"email": "Email",
"github": "Proyecto GitHub",
"items": "Elementos",
"join_discord": "Únete al Discord",
"labels": "Etiquetas",
"locations": "Ubicaciones",
"name": "Nombre",
"password": "Contraseña",
"read_docs": "Lee la Documentación",
"search": "Buscar",
"sign_out": "Cerrar Sesión",
"submit": "Enviar",
"welcome": "Bienvenido/a, { username }",
"create_and_add": "Crear y Añadir Otro",
"follow_dev": "Seguir al Desarrollador",
"version": "Versión: { version }"
},
"index": {
"disabled_registration": "Registro Desactivado",
"dont_join_group": "¿No quieres unirte a un grupo?",
"login": "Iniciar sesión",
"register": "Registrarse",
"remember_me": "Recuérdame",
"set_email": "¿Cuál es tu email?",
"set_name": "¿Cómo te llamas?",
"set_password": "Establece tu contraseña",
"tagline": "Rastrea, Organiza y Gestiona tus Cosas.",
"joining_group": "¡Te estás uniendo a un grupo existente!"
},
"items": {
"add": "Añadir",
"created_at": "Creado El",
"custom_fields": "Campos Personalizados",
"field_selector": "Selector de Campo",
"field_value": "Valor del Campo",
"first": "Primer",
"include_archive": "Incluir Elementos Archivados",
"last": "Último",
"negate_labels": "Negar Etiquetas Seleccionadas",
"next_page": "Siguiente Página",
"no_results": "No se Encontraron Elementos",
"options": "Opciones",
"order_by": "Ordenar Por",
"pages": "Página { page } de { totalPages }",
"prev_page": "Anterior Página",
"query_id": "Consultar Número ID del Activo: { id }",
"reset_search": "Restablecer Búsqueda",
"results": "{ total } Resultados",
"tip_2": "Las búsquedas precedidas de \"#\" buscarán un ID de activo (por ejemplo, \"#000-001\")",
"tip_3": "Los filtros de campo utilizan el operador \"OR\". Si se selecciona más de uno, sólo se requerirá uno para una\n coincidencia.",
"tip_1": "Los filtros de ubicación y etiquetas utilizan el operador \"OR\". Si se selecciona más de uno, sólo uno será\n necesario para obtener una coincidencia.",
"tips": "Sugerencias",
"tips_sub": "Sugerencias de Búsqueda",
"updated_at": "Actualizado El"
},
"profile": {
"active": "Activo",
"change_password": "Cambiar Contraseña",
"currency_format": "Formato Divisa",
"current_password": "Contraseña Actual",
"delete_account": "Eliminar Cuenta",
"enabled": "Habilitado",
"gen_invite": "Generar Enlace de Invitación",
"group_settings": "Ajustes de Grupo",
"group_settings_sub": "Configuración de Grupo Compartido. Es posible que tengas que actualizar tu navegador para que se apliquen algunos ajustes.",
"inactive": "Inactivo",
"new_password": "Nueva Contraseña",
"notifiers": "Notificaciones",
"notifiers_sub": "Recibe notificaciones de los próximos recordatorios de mantenimiento",
"test": "Probar",
"theme_settings": "Ajustes de Tema",
"update_group": "Actualizar Grupo",
"url": "URL",
"user_profile": "Perfil de Usuario",
"user_profile_sub": "Invita a usuarios y gestiona tu cuenta.",
"delete_account_sub": "Elimina tu cuenta y todos sus datos asociados. Esto no se puede deshacer.",
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Notificación",
"theme_settings_sub": "La configuración del tema se guarda en el almacenamiento local de tu navegador. Puedes cambiar el tema en cualquier momento. Si tienes\n problemas para configurar el tema, prueba a actualizar el navegador."
}
}

128
frontend/locales/fr.json Normal file
View File

@@ -0,0 +1,128 @@
{
"global": {
"email": "Courriel",
"read_docs": "Lire la documentation",
"password": "Mot de passe",
"github": "Projet GitHub",
"join_discord": "Rejoindre le Discord",
"follow_dev": "Suivre le développeur",
"version": "Version : { version }",
"build": "Assemblage : { build }",
"create": "Créer",
"submit": "Soumettre",
"create_and_add": "Créer et en ajouter un autre",
"confirm": "Confirmer",
"sign_out": "Déconnexion",
"welcome": "Bienvenue, { username }",
"created": "Créé",
"labels": "Étiquettes",
"locations": "Emplacements",
"name": "Nom",
"search": "Rechercher",
"items": "Articles"
},
"index": {
"set_email": "Quel est vôtre courriel?",
"set_name": "Quel est votre nom?",
"login": "Se connecter",
"register": "S'enregistrer",
"remember_me": "Se souvenir de moi",
"set_password": "Définir votre mot de passe",
"dont_join_group": "Vous ne voulez pas joindre un groupe ?",
"tagline": "Répertoriez, organisez et gérez vos affaires.",
"disabled_registration": "Les inscriptions sont désactivées",
"joining_group": "Vous rejoignez un groupe existant!"
},
"components": {
"label": {
"create_modal": {
"title": "Créer une étiquette"
}
},
"item": {
"view": {
"selectable": {
"items": "Articles",
"no_items": "Nb. darticles à afficher",
"table": "Tableau",
"card": "Carte"
}
},
"create_modal": {
"title": "Créer un article",
"photo_button": "Photo 📷"
}
},
"location": {
"create_modal": {
"title": "Créer un emplacement"
}
},
"global": {
"password_score": {
"password_strength": "Solidité du mot de passe"
},
"page_qr_code": {
"page_url": "URL de la page"
}
},
"app": {
"import_dialog": {
"title": "Importer un fichier CSV",
"upload": "Téléverser",
"description": "Importer un fichier CSV contenant vos articles, étiquettes, et emplacements. Voir la documentation pour plus dinformations sur le format requis.",
"change_warning": "Le comportement lors dimportations avec des import_ref existants a changé. Si une valeur pour import_ref est présente dans le fichier CSV, alors lélément sera mis à jour avec celle-ci."
}
}
},
"profile": {
"notifiers_sub": "Recevez des notifications pour vous prévenir des prochaines maintenances.",
"active": "Actif",
"enabled": "Activé",
"test": "Test",
"current_password": "Mot de passe actuel",
"new_password": "Nouveau mot de passe",
"change_password": "Changer de mot de passe",
"inactive": "Inactif",
"notifiers": "Notifications",
"gen_invite": "Générer un lien dinvitation",
"user_profile": "Profil utilisateur",
"user_profile_sub": "Gérez votre compte et invitez des utilisateurs.",
"url": "URL",
"delete_account": "Effacer le compte",
"delete_account_sub": "Supprimer le compte et toutes ses données. Aucune récupération possible.",
"group_settings": "Paramètres du groupe",
"group_settings_sub": "Paramètres du groupe partagé. Il peut être nécessaire de recharger la page pour quils deviennent effectifs.",
"currency_format": "Format de la devise",
"update_group": "Mettre à jour le groupe",
"theme_settings": "Paramètres du thème",
"theme_settings_sub": "Les paramètres du thème sont stockés dans le navigateur. Vous pouvez les changer à tout moment. Si vous\nrencontrez des problèmes, il est conseillé de rafraichir la page.",
"notifier_modal": ""
},
"items": {
"add": "Ajouter",
"created_at": "",
"custom_fields": "Champs personnalisés",
"field_selector": "Sélecteur de champ",
"field_value": "Valeur du champ",
"first": "Premier",
"include_archive": "Inclure les éléments archivés",
"last": "Dernier",
"negate_labels": "Négliger les étiquettes sélectionnées",
"next_page": "Page suivante",
"no_results": "Aucun élément trouvé",
"options": "Options",
"order_by": "Trier par",
"pages": "Page { page } sur { totalPages }",
"prev_page": "Page précédente",
"query_id": "",
"reset_search": "Réinitialiser la recherche",
"tip_1": "Les filtres demplacement et détiquette utilisent lopérateur « OU ».\nUn seul des filtres na besoin de correspondre pour retourner un résultat.",
"tip_2": "",
"tip_3": "Les filtres de champ utilisent lopérateur « OU ».\nUn seul des filtres na besoin de correspondre pour retourner un résultat.",
"tips": "Conseils",
"tips_sub": "Conseils pour la recherche",
"updated_at": "",
"results": "{ total } résultats"
}
}

127
frontend/locales/it.json Normal file
View File

@@ -0,0 +1,127 @@
{
"components": {
"app": {
"import_dialog": {
"change_warning": "Il comportamento per le importazioni con import_ref esistenti è cambiato. Se un import_ref è presente nel file CSV,\n l'elemento verrà aggiornato con i valori presenti nel file CSV.",
"description": "Importa un file CSV contenente gli oggetti, le etichette e le posizioni. Vedi la documentazione per ulteriori informazioni sul \nformato richiesto.",
"title": "Importa File CSV",
"upload": "Carica"
}
},
"global": {
"page_qr_code": {
"page_url": "URL della Pagina"
},
"password_score": {
"password_strength": "Complessità della Password"
}
},
"item": {
"create_modal": {
"title": "Crea Oggetto"
},
"view": {
"selectable": {
"card": "Scheda",
"items": "Oggetti",
"no_items": "Nessun Oggetto da Visualizzare",
"table": "Tabella"
}
}
},
"label": {
"create_modal": {
"title": "Crea Etichetta"
}
},
"location": {
"create_modal": {
"title": "Crea Posizione"
}
}
},
"global": {
"build": "Build: { build }",
"confirm": "Conferma",
"create": "Crea",
"create_and_add": "Crea e aggiungi un altro",
"created": "Creato",
"email": "Email",
"follow_dev": "Segui lo Sviluppatore",
"github": "Progetto GitHub",
"items": "Articoli",
"join_discord": "Unisciti a Discord",
"labels": "Etichette",
"locations": "Posizioni",
"name": "Nome",
"password": "Password",
"read_docs": "Leggi la Documentazione",
"search": "Cerca",
"sign_out": "Disconnetti",
"submit": "Invia",
"version": "Versione: { version }",
"welcome": "Benvenuto, { username }"
},
"index": {
"disabled_registration": "Registrazione Disabilitata",
"dont_join_group": "Non vuoi unirti a un gruppo?",
"joining_group": "Stai unendoti a un gruppo esistente!",
"login": "Accedi",
"register": "Registrati",
"remember_me": "Ricordami",
"set_email": "Qual è la tua email?",
"set_name": "Come ti chiami?",
"set_password": "Imposta la tua password",
"tagline": "Tieni traccia, Organizza e Gestisci le tue Cose."
},
"items": {
"add": "Aggiungi",
"created_at": "Creato Il",
"custom_fields": "Campi Personalizzati",
"field_selector": "Selettore di Campo",
"field_value": "Valore del Campo",
"first": "Primo",
"include_archive": "Includi Articoli Archiviati",
"last": "Ultimo",
"negate_labels": "Negare Etichette Selezionate",
"next_page": "Pagina Successiva",
"no_results": "Nessun Articolo Trovato",
"options": "Opzioni",
"order_by": "Ordina Per",
"pages": "Pagina { page } di { totalPages }",
"prev_page": "Pagina Precedente",
"query_id": "ID dell'Asset in Ricerca: { id }",
"reset_search": "Reimposta Ricerca",
"results": "{ total } Risultati",
"tip_1": "I filtri di posizione ed etichetta utilizzano l'operazione 'OR'. Se ne viene selezionato più\n di uno, ne sarà richiesto solo uno per una corrispondenza.",
"tip_2": "Le ricerche con prefisso '#' cercheranno un ID asset (esempio '#000-001')",
"tip_3": "I filtri di campo utilizzano l'operazione 'OR'. Se ne viene selezionato più di uno, ne sarà\n richiesto solo uno per una corrispondenza.",
"tips": "Suggerimenti",
"tips_sub": "Suggerimenti per la Ricerca",
"updated_at": "Aggiornato Il"
},
"profile": {
"active": "Attivo",
"change_password": "Cambia Password",
"currency_format": "Formato Valuta",
"current_password": "Password Corrente",
"delete_account": "Elimina Account",
"delete_account_sub": "Elimina il tuo account e tutti i dati associati. Questa operazione non può essere annullata.",
"enabled": "Abilitato",
"gen_invite": "Genera Link di Invito",
"group_settings": "Impostazioni Gruppo",
"group_settings_sub": "Impostazioni Gruppo Condivise. Potrebbe essere necessario aggiornare il browser affinché alcune impostazioni vengano applicate.",
"inactive": "Inattivo",
"new_password": "Nuova Password",
"notifier_modal": "{ type, select, true {Modifica} false {Crea} other {Altro}} Notifier",
"notifiers": "Notifiche",
"notifiers_sub": "Ricevi notifiche per i prossimi promemoria di manutenzione",
"test": "Test",
"theme_settings": "Impostazioni Tema",
"theme_settings_sub": "Le impostazioni del tema sono memorizzate nella memoria locale del tuo browser. Puoi cambiare il tema \nin qualsiasi momento. Se hai problemi a impostare il tuo tema, prova a ricaricare la pagina.",
"update_group": "Aggiorna Gruppo",
"url": "URL",
"user_profile": "Profilo Utente",
"user_profile_sub": "Invita utenti e gestisci il tuo account."
}
}

128
frontend/locales/nl.json Normal file
View File

@@ -0,0 +1,128 @@
{
"global": {
"version": "Versie: { version }",
"github": "GitHub Project",
"join_discord": "Sluit je aan bij de Discord",
"follow_dev": "Volg de ontwikkelaar",
"read_docs": "Lees de documentatie",
"email": "E-mail",
"submit": "Indienen",
"confirm": "Bevestigen",
"create": "Maken",
"create_and_add": "Maak en voeg nog een toe",
"password": "Wachtwoord",
"build": "Bouw: { build }",
"created": "Gemaakt",
"welcome": "Welkom, { username }",
"sign_out": "Log uit",
"labels": "etiketten",
"locations": "Locaties",
"name": "Naam",
"items": "artikelen",
"search": "Zoeken"
},
"index": {
"disabled_registration": "Registratie uitgeschakeld",
"login": "Log in",
"register": "Registreer",
"remember_me": "Onthoud mij",
"set_email": "Wat is je mailadres?",
"set_password": "Stel je wachtwoord in",
"set_name": "Wat is je naam?",
"joining_group": "Je neemt deel aan een bestaande groep!",
"tagline": "Volg, Organiseer en beheer je dingen.",
"dont_join_group": "Wil je niet aan een groep deelnemen?"
},
"components": {
"global": {
"password_score": {
"password_strength": "Wachtwoord sterkte"
},
"page_qr_code": {
"page_url": "Pagina URL"
}
},
"app": {
"import_dialog": {
"title": "Importeer CSV bestand",
"change_warning": "Gedrag voor importeren met bestaande import_refs is veranderd. Als een import_refs reeds bestaat in het CSV bestand, het\nobject zal worden aangepast met de waardes van het CSV bestand.",
"upload": "Upload",
"description": "Importeer een CSV bestand met je objecten, labels en locaties. Zie documentatie voor meer informatie m.b.t.\n vereist format."
}
},
"item": {
"create_modal": {
"title": "Maak object",
"photo_button": "Foto 📷"
},
"view": {
"selectable": {
"items": "Objecten",
"card": "Kaart",
"table": "Tabel",
"no_items": "Geen objecten om te tonen"
}
}
},
"label": {
"create_modal": {
"title": "Maak label"
}
},
"location": {
"create_modal": {
"title": "Maak locatie"
}
}
},
"profile": {
"gen_invite": "Genereer Uitnodigingslink",
"notifier_modal": "{ type, select, true {Bewerk} false {Creëer} other {overig}} Notifier",
"change_password": "Verander Wachtwoord",
"current_password": "Huidig Wachtwoord",
"new_password": "Nieuw Wachtwoord",
"url": "URL",
"enabled": "ingeschakeld",
"test": "Test",
"user_profile": "Gebruikers Profiel",
"user_profile_sub": "Nodig gebruikers uit, en beheer je account.",
"active": "Actief",
"inactive": "Inactief",
"notifiers_sub": "Krijg notificaties voor opkomende onderhouds herinneringen",
"group_settings_sub": "Gedeelde groepsinstellingen",
"group_settings": "Groeps Instellingen",
"notifiers": "Notificatie",
"currency_format": "Valutanotatie",
"update_group": "Groep bijwerken",
"theme_settings": "Theme instellingen",
"theme_settings_sub": "",
"delete_account": "Verwijder account",
"delete_account_sub": "Verwijder je account en alle geassocieerde data. Deze actie kan niet ongedaan worden."
},
"items": {
"tip_1": "Locatie- en labelfilters gebruiken de 'OF' -werking. Als er meer dan een is geselecteerd,\nis er maar een nodig voor een overeenkomst.",
"tip_2": "Zoekopdrachten voorafgegaan door '#'' zullen om een object-ID vragen (bijvoorbeeld '#000-001')",
"tip_3": "",
"tips_sub": "Zoektips",
"updated_at": "Bijgewerkt op",
"pages": "Pagina { page } van { totalPages }",
"prev_page": "Vorige pagina",
"query_id": "ID-nummer van object opvragen: { id }",
"reset_search": "Reset Zoeken",
"tips": "Tips",
"no_results": "Geen Items Gevonden",
"options": "Opties",
"order_by": "Sorteren op",
"results": "{ total } Resultaten",
"add": "Toevoegen",
"created_at": "Aangemaakt op",
"custom_fields": "Aangepaste velden",
"field_selector": "Veld selectie",
"field_value": "Veldwaarde",
"first": "Eerst",
"include_archive": "Inclusief gearchiveerde items",
"last": "Laatste",
"negate_labels": "Negeer Geselecteerde Etiketten",
"next_page": "Volgende pagina"
}
}

128
frontend/locales/ru.json Normal file
View File

@@ -0,0 +1,128 @@
{
"components": {
"app": {
"import_dialog": {
"title": "Импорт CSV файла",
"change_warning": "Изменено поведение для импортов с существующими import_ref. Если в CSV-файле присутствует import_ref, \nто элемент будет обновлен значениями из CSV-файла.",
"description": "Импортируйте CSV-файл, содержащий ваши предметы, ярлыки и местоположения. Для получения информации о требуемом формате \nсм. документацию.",
"upload": "Загрузить"
}
},
"global": {
"page_qr_code": {
"page_url": "URL-адрес страницы"
},
"password_score": {
"password_strength": "Сложность пароля"
}
},
"item": {
"create_modal": {
"title": "Создать элемент",
"photo_button": "Фото 📷"
},
"view": {
"selectable": {
"items": "Элементы",
"no_items": "Нет элементов для отображения",
"table": "Таблица",
"card": "Карта"
}
}
},
"location": {
"create_modal": {
"title": "Создать локацию"
}
},
"label": {
"create_modal": {
"title": "Создать ярлык"
}
}
},
"global": {
"email": "Email",
"items": "Элементы",
"build": "Сборка: { build }",
"confirm": "Подтвердить",
"create": "Создать",
"create_and_add": "Создать и добавить еще",
"created": "Создано",
"follow_dev": "Следить за разработчиком",
"github": "Проект Github",
"labels": "Ярлыки",
"join_discord": "Присоединяйтесь к Discord",
"locations": "Локации",
"name": "Имя",
"password": "Пароль",
"read_docs": "Прочитать документацию",
"search": "Поиск",
"sign_out": "Выйти",
"submit": "Отправить",
"version": "Версия: { version }",
"welcome": "Добро пожаловать, { username }"
},
"index": {
"login": "Войти",
"register": "Зарегистрироваться",
"set_email": "Какой у вас адрес электронной почты?",
"set_name": "Как вас зовут?",
"set_password": "Установите пароль",
"tagline": "Отслеживайте, упорядочивайте и управляйте своими вещами.",
"disabled_registration": "Регистрация отключена",
"dont_join_group": "Не хотите ли вступить в группу?",
"remember_me": "Запомнить меня",
"joining_group": "Вы присоединяетесь к уже существующей группе!"
},
"items": {
"add": "Добавить",
"created_at": "Создано в",
"custom_fields": "Настраиваемые поля",
"first": "Первый",
"pages": "Страница {page} из {totalPages}",
"prev_page": "Предыдущая страница",
"reset_search": "Сбросить Поиск",
"field_selector": "Поле выбора",
"field_value": "Значение поля",
"last": "Последний",
"negate_labels": "Снять выбранные ярлыки",
"next_page": "Следующая страница",
"no_results": "Элементы не найдены",
"options": "Параметры",
"results": "{ total } Результатов",
"tips": "Подсказки",
"tips_sub": "Поисковые подсказки",
"updated_at": "Обновлено в",
"tip_3": "Фильтры по полю используют операцию «ИЛИ». Если выбрано несколько фильтров, для совпадения\n требуется только один.",
"tip_2": "Поисковые запросы с префиксом \"#\" должны включать в себя ID актива (прим. '#000-001')",
"include_archive": "Включить архивированные элементы",
"order_by": "Сортировка по",
"query_id": "Запрос идентификационного номера актива: { id }",
"tip_1": "При фильтрации по локации и по ярлыкам используется логический оператор «ИЛИ». Если выбрано несколько фильтров, то для срабатывания\n требуется лишь одно совпадение."
},
"profile": {
"new_password": "Новый пароль",
"update_group": "Обновить группу",
"active": "Активный",
"change_password": "Изменить пароль",
"currency_format": "Формат валюты",
"current_password": "Текущий пароль",
"delete_account": "Удалить аккаунт",
"group_settings": "Настройки группы",
"inactive": "Неактивный",
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Уведомитель",
"notifiers": "Уведомители",
"notifiers_sub": "Получить уведомление о предстоящем обслуживании",
"test": "Тест",
"theme_settings": "Настройки темы",
"url": "URL",
"user_profile": "Профиль пользователя",
"user_profile_sub": "Приглашайте пользователей и управляйте своим аккаунтом.",
"enabled": "Активен",
"theme_settings_sub": "Настройки темы хранятся в локальном хранилище браузера. Вы можете изменить тему в любое время. Если у вас\n не удается установить тему, попробуйте перезапустить браузер.",
"delete_account_sub": "Удалить свой аккаунт и все связанные с ним данные. Это действие невозможно отменить.",
"gen_invite": "Сгенерировать ссылку-приглашение",
"group_settings_sub": "Настройки общей группы. Для применения изменений возможно потребуется перезагрузить страницу."
}
}

128
frontend/locales/sv.json Normal file
View File

@@ -0,0 +1,128 @@
{
"profile": {
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Anmälare",
"change_password": "Ändra Lösenord",
"current_password": "Nuvarande lösenord",
"new_password": "Nytt lösenord",
"notifiers_sub": "Få aviseringar om kommande underhållspåminnelser",
"url": "URL",
"test": "Test",
"gen_invite": "Skapa inbjudningslänk",
"user_profile": "Användarprofil",
"user_profile_sub": "Bjud in användare och hantera ditt konto.",
"active": "Aktiv",
"inactive": "Inaktiv",
"notifiers": "Notiser",
"enabled": "Aktiverad",
"currency_format": "Valuta format",
"delete_account": "Radera konto",
"delete_account_sub": "Ta bort ditt konto och alla tillhörande data. Detta kan inte ångras.",
"group_settings": "Grupp inställningar",
"group_settings_sub": "Inställningar för delad grupp. Du kan behöva uppdatera din webbläsare för att vissa inställningar ska gälla.",
"theme_settings": "Temainställningar",
"theme_settings_sub": "Temainställningar sparas i din webbläsares lokala lagring. Du kan ändra tema när du vill. Om du\nhar problem att ställa in tema, pröva att ladda om din webbläsare.",
"update_group": "Uppdatera grupp"
},
"index": {
"set_name": "Vad heter du?",
"joining_group": "Du går med i en befintlig grupp!",
"dont_join_group": "Vill du inte gå med i en grupp?",
"tagline": "Spåra, organisera och hantera dina saker.",
"disabled_registration": "Registrering avaktiverad",
"login": "Logga in",
"register": "Registrera",
"remember_me": "Kom ihåg mig",
"set_email": "Vad är din e-post?",
"set_password": "Ställ in ditt lösenord"
},
"components": {
"app": {
"import_dialog": {
"upload": "Ladda upp",
"title": "Importera CSV fil",
"description": "Importera en CSV-fil som innehåller dina föremål, etiketter och platser. Se dokumentationen för mer information om \nönskat format.",
"change_warning": "Beteendet för importer med befintliga import_refs har ändrats. Om en import_ref finns i CSV-filen, \nobjektet kommer att uppdateras med värdena i CSV-filen."
}
},
"item": {
"view": {
"selectable": {
"card": "Kort",
"items": "Föremål",
"table": "Tabell",
"no_items": "Inga föremål att visa"
}
},
"create_modal": {
"title": "Skapa föremål",
"photo_button": "Foto 📷"
}
},
"label": {
"create_modal": {
"title": "Skapa etikett"
}
},
"location": {
"create_modal": {
"title": "Skapa plats"
}
},
"global": {
"password_score": {
"password_strength": "Lösenordsstyrka"
},
"page_qr_code": {
"page_url": "Sidans URL"
}
}
},
"global": {
"build": "Byggd: { build }",
"github": "GitHub Projekt",
"join_discord": "Gå med i Discord",
"follow_dev": "Följ utvecklaren",
"read_docs": "Läs dokumenten",
"password": "Lösenord",
"email": "Epost",
"submit": "Skicka",
"confirm": "Godkänn",
"create": "Skapa",
"created": "Skapad",
"welcome": "Välkommen, { username }",
"sign_out": "Logga ut",
"create_and_add": "Skapa och lägg till en annan",
"version": "Version: { version }",
"items": "Föremål",
"labels": "Etiketter",
"locations": "Platser",
"name": "Namn",
"search": "Sök"
},
"items": {
"add": "Lägg till",
"created_at": "Skapat",
"custom_fields": "Egna fält",
"field_selector": "Fält alternativ",
"field_value": "Fält värde",
"first": "Första",
"include_archive": "Inkludera arkiverade föremål",
"last": "Sista",
"negate_labels": "Negera valda etiketter",
"next_page": "Nästa sida",
"no_results": "Inga föremål hittades",
"options": "Alternativ",
"order_by": "Ordning via",
"pages": "Sida { page } av { totalPages }",
"prev_page": "Föregående sida",
"query_id": "Fråga efter tillgångs-ID-nummer: { id }",
"reset_search": "Återställ sökning",
"tip_1": "Platser och etiketter filter använder 'OR' funktionen. Om fler än en är valda, endast en kommer\nkrävas för en träff.",
"tip_2": "Sökningar med prefixet '#'' kommer att fråga efter ett tillgångs-ID (exempel '#000-001')",
"tip_3": "Fältfilter använder 'OR' funktion. Om fler än en är valda endast en kommer att bli krävande för en\nträff.",
"tips": "Tips",
"tips_sub": "Sök Tips",
"updated_at": "Uppdaterad",
"results": "{ total } Resultat"
}
}

128
frontend/locales/tr.json Normal file
View File

@@ -0,0 +1,128 @@
{
"global": {
"version": "Versiyon:{ version }",
"password": "Şifre",
"create": "Oluştur",
"github": "GitHub projesi",
"join_discord": "Discord'a Katılın",
"follow_dev": "Geliştiriciyi takip edin",
"read_docs": "Dokümanları okuyun",
"email": "Elektronik posta",
"submit": "Gönder",
"confirm": "Onaylayın",
"build": "Sürüm: { build }",
"create_and_add": "Oluştur ve Bir Tane Daha Ekle",
"created": "Oluşturuldu",
"items": "Öğeler",
"labels": "Etiketler",
"locations": "Konumlar",
"name": "İsim",
"search": "Ara",
"sign_out": "Oturumu kapat",
"welcome": "Hoşgeldib, { username }"
},
"components": {
"app": {
"import_dialog": {
"change_warning": "Mevcut import_refs ile içe aktarmaların davranışı değişti. CSV dosyasında bir import_ref varsa, \nöğe CSV dosyasındaki değerlerle güncellenecektir.",
"title": "CSV dosyasını içeri aktar",
"upload": "Yükle",
"description": "Öğelerinizi, etiketlerinizi ve konumlarınızı içeren bir CSV dosyasını içe aktarın. Daha fazla\nbilgi için dökümanları okuyun."
}
},
"global": {
"password_score": {
"password_strength": "Şifre güvenlik seviyesi"
},
"page_qr_code": {
"page_url": "Sayfa URL'si"
}
},
"item": {
"create_modal": {
"title": "Eşya Oluştur",
"photo_button": "Fotoğraf 📷"
},
"view": {
"selectable": {
"items": "Öğeler",
"card": "Kart",
"table": "Tablo",
"no_items": "Görüntülecek Öge Yok"
}
}
},
"label": {
"create_modal": {
"title": "Etiket oluştur"
}
},
"location": {
"create_modal": {
"title": "Konum oluştur"
}
}
},
"index": {
"remember_me": "Beni Hatırla",
"tagline": "Eşyalarınızı Takip Edin, Düzenleyin ve Yönetin.",
"disabled_registration": "Kayıt olma devre dışı",
"login": "Oturum Aç",
"register": "Kaydolun",
"set_email": "E-posta adresiniz nedir?",
"set_password": "Şifrenizi belirleyin",
"set_name": "Adın ne?",
"joining_group": "Mevcut bir gruba katılıyorsunuz!",
"dont_join_group": "Bir gruba katılmak istemiyor musunuz?"
},
"items": {
"add": "Ekle",
"created_at": "Oluşturulma",
"custom_fields": "Özel Alanlar",
"field_selector": "alan seçici",
"field_value": "Alan Değeri",
"first": "Birinci",
"include_archive": "Arşivlenen Öğeleri Dahil Et",
"last": "Son",
"negate_labels": "Seçili Etiketleri Yoksay",
"next_page": "Sonraki Sayfa",
"no_results": "Öğe Bulunamadı",
"options": "Seçenekler",
"order_by": "Sıralama ölçütü",
"pages": "Sayfa { page }/{ totalPages }",
"prev_page": "Önceki Sayfa",
"query_id": "Varlık Kimlik Numarası Sorgulanıyor: { id }",
"tip_1": "Konum ve etiket filtreleri 'veya' işlemini kullanır. Eğer birden fazla seçilirse sadece biri \neşleştirme için kullanılacaktır.",
"reset_search": "Aramayı Sıfırla",
"tips": "İpuçları",
"results": "{ total } Sonuç",
"tip_2": "'#' ile başlayan aramalar bir varlık kimliğini sorgular (örneğin '#000-001')",
"tip_3": "Alan filtreleri 'VEYA' işlemini kullanır. Birden fazla seçenek seçilirse, eşleşme için yalnızca birinin \nkarşılanması yeterlidir.",
"tips_sub": "Arama İpuçları",
"updated_at": "Güncellendiği Zaman"
},
"profile": {
"url": "URL",
"user_profile": "Kullanıcı Profili",
"user_profile_sub": "Kullanıcıları davet edin ve hesabınızı yönetin.",
"active": "Aktif",
"change_password": "Şifre Değiştir",
"currency_format": "Para Birimi Biçimi",
"current_password": "Mevcut Şifre",
"delete_account": "Hesabı Sil",
"delete_account_sub": "Hesabınızı ve ona bağlı tüm verileri silin. Bu işlem geri alınamaz.",
"enabled": "Etkinleştirildi",
"gen_invite": "Davet Bağlantısı Oluştur",
"group_settings": "Grup Ayarları",
"group_settings_sub": "Paylaşılan Grup Ayarları. Bazı ayarların uygulanabilmesi için tarayıcınızı yenilemeniz gerekebilir.",
"inactive": "Etkin Değil",
"new_password": "Yeni Şifre",
"notifier_modal": "{ type, select, true {Edit} false {Create} other {Other}} Bildirici",
"notifiers": "Bildirimde Bulunanlar",
"test": "Test",
"theme_settings": "Tema Ayarları",
"theme_settings_sub": "Tema ayarları tarayıcınızın yerel depolama alanında saklanır. Temayı istediğiniz zaman değiştirebilirsiniz. \nTemanızı ayarlamakta sorun yaşıyorsanız, tarayıcınızı yenilemeyi deneyin.",
"update_group": "Grubu Güncelle",
"notifiers_sub": "Yaklaşan bakım hatırlatmaları için bildirimler alın"
}
}

View File

@@ -0,0 +1,128 @@
{
"components": {
"app": {
"import_dialog": {
"title": "导入 CSV 文件",
"upload": "上传",
"description": "导入包含物品、标签和位置的CSV文件。更多有关信息\n请参阅文档查看所需格式。",
"change_warning": "导入行为会导致现有的 import_refs 的字段被覆盖。\n如果 CSV 文件中存在 import_ref则将使用 CSV 文件中的值更新该项。"
}
},
"item": {
"create_modal": {
"title": "创建物品",
"photo_button": "照片 📷"
},
"view": {
"selectable": {
"card": "卡片模式",
"items": "物品模式",
"no_items": "没有物品可用展示",
"table": "表格模式"
}
}
},
"location": {
"create_modal": {
"title": "创建位置"
}
},
"global": {
"page_qr_code": {
"page_url": "页面URL"
},
"password_score": {
"password_strength": "密码强度"
}
},
"label": {
"create_modal": {
"title": "创建标签"
}
}
},
"global": {
"create_and_add": "保存并继续创建",
"email": "邮箱",
"items": "物品",
"build": "编译:{build}",
"confirm": "确认",
"create": "创建",
"created": "已创建",
"follow_dev": "关注开发者",
"github": "Github项目",
"join_discord": "加入Discord讨论",
"labels": "标签",
"sign_out": "注销",
"version": "版本:{version}",
"welcome": "欢迎,{username}",
"name": "名称",
"password": "密码",
"read_docs": "查阅文档",
"search": "搜索",
"submit": "提交",
"locations": "位置"
},
"index": {
"disabled_registration": "已禁用注册",
"dont_join_group": "不想加入群组?",
"joining_group": "您正在加入现有群组!",
"login": "登录",
"register": "注册",
"set_name": "你的名称叫什么?",
"remember_me": "记住我",
"set_email": "您的电子邮箱是什么?",
"tagline": "跟踪、整理和管理您的物品。",
"set_password": "设置密码"
},
"items": {
"last": "最后一页",
"negate_labels": "取消选中的标签",
"next_page": "下一页",
"no_results": "没有可显示的物品",
"options": "选项",
"prev_page": "上一页",
"add": "添加",
"field_selector": "字段选择",
"first": "第一页",
"order_by": "排序方式",
"pages": "第{page}页,共{totalPages}页",
"query_id": "查询资产ID {id}",
"created_at": "创建于",
"custom_fields": "自定义字段",
"field_value": "字段值",
"include_archive": "包括已存档的项目",
"reset_search": "重置搜索",
"results": "{ total } 条结果",
"tip_1": "位置和标签过滤器使用“或”操作。如果选择了多个位置或标签,\n则只需要任意一个匹配上即可。",
"tip_2": "以“#”为前缀的搜索将变成查询资产ID例如“#000-001” ",
"tip_3": "字段过滤器使用“或”操作。如果选择了多个位置或标签,\n则只需要任意一个匹配上即可。",
"tips": "建议",
"tips_sub": "搜索提示",
"updated_at": "更新于"
},
"profile": {
"group_settings_sub": "共享组设置。您可能需要刷新浏览器来让某些设置生效。",
"notifier_modal": "通知 { type, select, true {Edit} false {Create} other {Other}}",
"active": "活跃",
"delete_account_sub": "删除您的帐户及其所有相关数据。这是无法撤消的。",
"inactive": "非活跃",
"theme_settings_sub": "主题设置存储在浏览器的本地存储中。您可以随时更改主题。\n如果您在设置主题时遇到问题请尝试刷新浏览器。",
"update_group": "更新组",
"change_password": "更改密码",
"currency_format": "货币格式",
"current_password": "原密码",
"delete_account": "删除帐户",
"enabled": "已启用",
"gen_invite": "生成邀请链接",
"group_settings": "组设置",
"new_password": "新密码",
"notifiers": "通知",
"notifiers_sub": "获取即将到来的维护提醒通知",
"test": "测试",
"theme_settings": "主题设置",
"url": "网址",
"user_profile": "用户资料",
"user_profile_sub": "邀请用户共同管理您的资产。"
}
}

View File

@@ -0,0 +1,128 @@
{
"items": {
"include_archive": "包括存檔項目",
"tip_1": "位置和標籤過濾器使用“OR”運算。如果選擇了多個則一次配對\n只會使用一個。",
"pages": "第{ page } 頁(共{ totalPages })",
"tip_3": "字段過濾器使用“OR”運算。如果選擇了多個則一次配對只需要選擇\n一個。",
"field_value": "欄位值",
"field_selector": "欄位選擇器",
"custom_fields": "自訂欄位",
"first": "第一項",
"add": "添加",
"created_at": "創建於",
"last": "最後一項",
"negate_labels": "取消選定的標籤",
"next_page": "下一頁",
"no_results": "沒有找到項目",
"options": "選項",
"order_by": "排序",
"prev_page": "上一頁",
"query_id": "查詢資產ID號碼:{ id }",
"reset_search": "重置搜尋",
"results": "{ total }結果",
"tips": "提示",
"tips_sub": "搜尋技巧",
"updated_at": "更新於",
"tip_2": "以「#」為前綴的搜尋將查詢資產 ID例如「#000-001」"
},
"components": {
"app": {
"import_dialog": {
"description": "匯入包含您的商品、標籤和位置的 CSV 檔案。有關所需格式的更多信息\n請參閱文件。",
"title": "匯入CSV檔案",
"upload": "上傳",
"change_warning": "現有 import_refs 的導入行為已變更。如果 CSV 檔案中存在 import_ref則\n項目將使用 CSV 檔案中的值進行更新。"
}
},
"global": {
"page_qr_code": {
"page_url": "頁面網址"
},
"password_score": {
"password_strength": "密碼強度"
}
},
"item": {
"create_modal": {
"title": "新增項目",
"photo_button": "相片 📷"
},
"view": {
"selectable": {
"card": "卡牌風",
"items": "項目",
"no_items": "沒有可顯示的項目",
"table": "表格"
}
}
},
"label": {
"create_modal": {
"title": "新增標籤"
}
},
"location": {
"create_modal": {
"title": "新增地點"
}
}
},
"global": {
"build": "建立{ build }",
"confirm": "確認",
"create": "新增",
"create_and_add": "創建並添加另一個",
"created": "已建立",
"email": "電子信箱",
"github": "GitHub項目",
"items": "項目",
"join_discord": "加入Discord",
"labels": "標籤",
"locations": "地點",
"name": "名字",
"password": "密碼",
"read_docs": "閱讀文件",
"search": "搜尋",
"sign_out": "登出",
"submit": "提交",
"version": "版本:{ version }",
"follow_dev": "關注開發者",
"welcome": "歡迎,{ username }"
},
"index": {
"disabled_registration": "已禁用註冊",
"dont_join_group": "不想加入群組?",
"joining_group": "您正在加入現有群組!",
"login": "登入",
"register": "註冊",
"remember_me": "記住帳號",
"set_email": "你的電子郵件是什麼?",
"set_name": "你叫什麼名字?",
"tagline": "追蹤、組織和管理您的物品。",
"set_password": "設定您的密碼"
},
"profile": {
"change_password": "變更密碼",
"currency_format": "貨幣格式",
"current_password": "當前密碼",
"delete_account": "刪除帳戶",
"enabled": "啟用",
"gen_invite": "產生邀請連結",
"group_settings": "群組設定",
"group_settings_sub": "共享群組設定。您可能需要刷新瀏覽器才能套用設定。",
"inactive": "不活躍",
"new_password": "新密碼",
"active": "活躍",
"delete_account_sub": "刪除您的帳戶及其所有相關資料。此操作無法撤回。",
"notifiers": "通知者",
"notifiers_sub": "獲取即將到來的維護提醒的通知",
"test": "測試",
"theme_settings": "主題設定",
"update_group": "更新群組",
"url": "網址",
"user_profile": "使用者資料",
"user_profile_sub": "邀請使用者並管理您的帳戶。",
"theme_settings_sub": "主題設定儲存在瀏覽器的本機儲存中。您可以隨時變更主題。如果你是\n 設定主題時遇到問題,請嘗試刷新瀏覽器。",
"notifier_modal": "通知 { type, select, true {Edit} false {Create} other {Other}}"
}
}

View File

@@ -3,6 +3,9 @@ import { defineNuxtConfig } from "nuxt/config";
// https://v3.nuxtjs.org/api/configuration/nuxt.config // https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({ export default defineNuxtConfig({
ssr: false, ssr: false,
build: {
transpile: ["vue-i18n"],
},
modules: [ modules: [
"@nuxtjs/tailwindcss", "@nuxtjs/tailwindcss",
"@pinia/nuxt", "@pinia/nuxt",

View File

@@ -16,6 +16,7 @@
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^8.0.0", "@faker-js/faker": "^8.0.0",
"@iconify-json/mdi": "^1.1.64", "@iconify-json/mdi": "^1.1.64",
"@intlify/unplugin-vue-i18n": "^4.0.0",
"@nuxtjs/eslint-config-typescript": "^12.0.0", "@nuxtjs/eslint-config-typescript": "^12.0.0",
"@types/dompurify": "^3.0.0", "@types/dompurify": "^3.0.0",
"@types/markdown-it": "^13.0.0", "@types/markdown-it": "^13.0.0",
@@ -27,13 +28,15 @@
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-vue": "^9.4.0", "eslint-plugin-vue": "^9.4.0",
"h3": "^1.7.1", "h3": "^1.7.1",
"intl-messageformat": "^10.5.14",
"isomorphic-fetch": "^3.0.0", "isomorphic-fetch": "^3.0.0",
"nuxt": "3.6.5", "nuxt": "3.6.5",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"unplugin-icons": "^0.18.5", "unplugin-icons": "^0.18.5",
"vite-plugin-eslint": "^1.8.1", "vite-plugin-eslint": "^1.8.1",
"vitest": "^1.0.0" "vitest": "^1.0.0",
"vue-i18n": "^9.13.1"
}, },
"dependencies": { "dependencies": {
"@headlessui/vue": "^1.7.9", "@headlessui/vue": "^1.7.9",

View File

@@ -1,6 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import MdiGithub from "~icons/mdi/github"; import MdiGithub from "~icons/mdi/github";
import MdiTwitter from "~icons/mdi/twitter";
import MdiDiscord from "~icons/mdi/discord"; import MdiDiscord from "~icons/mdi/discord";
import MdiFolder from "~icons/mdi/folder"; import MdiFolder from "~icons/mdi/folder";
import MdiAccount from "~icons/mdi/account"; import MdiAccount from "~icons/mdi/account";
@@ -8,6 +7,7 @@
import MdiLogin from "~icons/mdi/login"; import MdiLogin from "~icons/mdi/login";
import MdiArrowRight from "~icons/mdi/arrow-right"; import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiLock from "~icons/mdi/lock"; import MdiLock from "~icons/mdi/lock";
import MdiMastodon from '~icons/mdi/mastodon';
useHead({ useHead({
title: "Homebox | Organize and Tag Your Stuff", title: "Homebox | Organize and Tag Your Stuff",
@@ -77,6 +77,15 @@
async function registerUser() { async function registerUser() {
loading.value = true; loading.value = true;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email.value)) {
toast.error("Invalid email address");
loading.value = false;
return;
}
const { error } = await api.register({ const { error } = await api.register({
name: username.value, name: username.value,
email: email.value, email: email.value,
@@ -149,19 +158,19 @@
<AppLogo class="w-12 -mb-4" /> <AppLogo class="w-12 -mb-4" />
x x
</h2> </h2>
<p class="ml-1 text-lg text-base-content/50">Track, Organize, and Manage your Things.</p> <p class="ml-1 text-lg text-base-content/50">{{ $t("index.tagline") }}</p>
</div> </div>
<div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content"> <div class="flex mt-6 sm:mt-0 gap-4 ml-auto text-neutral-content">
<a class="tooltip" data-tip="Project Github" href="https://github.com/sysadminsmedia/homebox" target="_blank"> <a class="tooltip" :data-tip="$t('global.github')" href="https://github.com/sysadminsmedia/homebox" target="_blank">
<MdiGithub class="h-8 w-8" /> <MdiGithub class="h-8 w-8" />
</a> </a>
<a href="https://twitter.com/haybytes" class="tooltip" data-tip="Follow The Developer" target="_blank"> <a href="https://noc.social/@sysadminsmedia" class="tooltip" :data-tip="$t('global.follow_dev')" target="_blank">
<MdiTwitter class="h-8 w-8" /> <MdiMastodon class="h-8 w-8" />
</a> </a>
<a href="https://discord.gg/aY4DCkpNA9" class="tooltip" data-tip="Join The Discord" target="_blank"> <a href="https://discord.gg/aY4DCkpNA9" class="tooltip" :data-tip="$t('global.join_discord')" target="_blank">
<MdiDiscord class="h-8 w-8" /> <MdiDiscord class="h-8 w-8" />
</a> </a>
<a href="https://homebox.sysadminsmedia.com/en/" class="tooltip" data-tip="Read The Docs" target="_blank"> <a href="https://homebox.sysadminsmedia.com/en/" class="tooltip" :data-tip="$t('global.read_docs')" target="_blank">
<MdiFolder class="h-8 w-8" /> <MdiFolder class="h-8 w-8" />
</a> </a>
</div> </div>
@@ -174,17 +183,17 @@
<div class="card-body"> <div class="card-body">
<h2 class="card-title text-2xl align-center"> <h2 class="card-title text-2xl align-center">
<MdiAccount class="mr-1 w-7 h-7" /> <MdiAccount class="mr-1 w-7 h-7" />
Register {{ $t("index.register") }}
</h2> </h2>
<FormTextField v-model="email" label="Set your email?" /> <FormTextField v-model="email" :label="$t('index.set_email')" />
<FormTextField v-model="username" label="What's your name?" /> <FormTextField v-model="username" :label="$t('index.set_name')" />
<div v-if="!(groupToken == '')" class="pt-4 pb-1 text-center"> <div v-if="!(groupToken == '')" class="pt-4 pb-1 text-center">
<p>You're Joining an Existing Group!</p> <p>{{ $t("index.joining_group") }}</p>
<button type="button" class="text-xs underline" @click="groupToken = ''"> <button type="button" class="text-xs underline" @click="groupToken = ''">
Don't Want To Join a Group? {{ $t("index.dont_join_group") }}
</button> </button>
</div> </div>
<FormPassword v-model="password" label="Set your password" /> <FormPassword v-model="password" :label="$t('index.set_password')" />
<PasswordScore v-model:valid="canRegister" :password="password" /> <PasswordScore v-model:valid="canRegister" :password="password" />
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<button <button
@@ -193,7 +202,7 @@
:class="loading ? 'loading' : ''" :class="loading ? 'loading' : ''"
:disabled="loading || !canRegister" :disabled="loading || !canRegister"
> >
Register {{ $t("index.register") }}
</button> </button>
</div> </div>
</div> </div>
@@ -204,17 +213,17 @@
<div class="card-body"> <div class="card-body">
<h2 class="card-title text-2xl align-center"> <h2 class="card-title text-2xl align-center">
<MdiAccount class="mr-1 w-7 h-7" /> <MdiAccount class="mr-1 w-7 h-7" />
Login {{ $t("index.login") }}
</h2> </h2>
<template v-if="status && status.demo"> <template v-if="status && status.demo">
<p class="text-xs italic text-center">This is a demo instance</p> <p class="text-xs italic text-center">This is a demo instance</p>
<p class="text-xs text-center"><b>Email</b> demo@example.com</p> <p class="text-xs text-center"><b>{{ $t("global.email") }}</b> demo@example.com</p>
<p class="text-xs text-center"><b>Password</b> demo</p> <p class="text-xs text-center"><b>{{ $t("global.password") }}</b> demo</p>
</template> </template>
<FormTextField v-model="email" label="Email" /> <FormTextField v-model="email" :label="$t('global.email')" />
<FormPassword v-model="loginPassword" label="Password" /> <FormPassword v-model="loginPassword" :label="$t('global.password')" />
<div class="max-w-[140px]"> <div class="max-w-[140px]">
<FormCheckbox v-model="remember" label="Remember Me" /> <FormCheckbox v-model="remember" :label="$t('index.remember_me')" />
</div> </div>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
<button <button
@@ -223,7 +232,7 @@
:class="loading ? 'loading' : ''" :class="loading ? 'loading' : ''"
:disabled="loading" :disabled="loading"
> >
Login {{ $t("index.login") }}
</button> </button>
</div> </div>
</div> </div>
@@ -241,18 +250,21 @@
<MdiLogin v-else class="w-5 h-5 swap-off" /> <MdiLogin v-else class="w-5 h-5 swap-off" />
<MdiArrowRight class="w-5 h-5 swap-on" /> <MdiArrowRight class="w-5 h-5 swap-on" />
</template> </template>
{{ registerForm ? "Login" : "Register" }} {{ registerForm ? $t("index.login") : $t("index.register") }}
</BaseButton> </BaseButton>
<p v-else class="text-base-content italic text-sm inline-flex items-center gap-2"> <p v-else class="text-base-content italic text-sm inline-flex items-center gap-2">
<MdiLock class="w-4 h-4 inline-block" /> <MdiLock class="w-4 h-4 inline-block" />
Registration Disabled {{ $t("disabled_registration") }}
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<footer v-if="status" class="mt-auto text-center w-full bottom-0 pb-4"> <footer v-if="status" class="mt-auto text-center w-full bottom-0 pb-4">
<p class="text-center text-sm">Version: {{ status.build.version }} ~ Build: {{ status.build.commit }}</p> <p class="text-center text-sm">
{{ $t("global.version", { version: status.build.version }) }} ~
{{ $t("global.build", { build: status.build.commit }) }}
</p>
</footer> </footer>
</div> </div>
</template> </template>

View File

@@ -338,9 +338,9 @@
<div v-if="locations && labels"> <div v-if="locations && labels">
<div class="flex flex-wrap md:flex-nowrap gap-4 items-end"> <div class="flex flex-wrap md:flex-nowrap gap-4 items-end">
<div class="w-full"> <div class="w-full">
<FormTextField v-model="query" placeholder="Search" /> <FormTextField v-model="query" :placeholder="$t('global.search')" />
<div v-if="byAssetId" class="text-sm pl-2 pt-2"> <div v-if="byAssetId" class="text-sm pl-2 pt-2">
<p>Querying Asset ID Number: {{ parsedAssetId }}</p> <p>{{ $t("items.query_id", { id: parsedAssetId }) }}</p>
</div> </div>
</div> </div>
<BaseButton class="btn-block md:w-auto" @click.prevent="submit"> <BaseButton class="btn-block md:w-auto" @click.prevent="submit">
@@ -348,12 +348,12 @@
<MdiLoading v-if="loading" class="animate-spin" /> <MdiLoading v-if="loading" class="animate-spin" />
<MdiMagnify v-else /> <MdiMagnify v-else />
</template> </template>
Search {{ $t("global.search") }}
</BaseButton> </BaseButton>
</div> </div>
<div class="flex flex-wrap md:flex-nowrap gap-2 w-full py-2"> <div class="flex flex-wrap md:flex-nowrap gap-2 w-full py-2">
<SearchFilter v-model="selectedLocations" label="Locations" :options="locationFlatTree"> <SearchFilter v-model="selectedLocations" :label="$t('global.locations')" :options="locationFlatTree">
<template #display="{ item }"> <template #display="{ item }">
<div> <div>
<div class="flex w-full"> <div class="flex w-full">
@@ -365,60 +365,60 @@
</div> </div>
</template> </template>
</SearchFilter> </SearchFilter>
<SearchFilter v-model="selectedLabels" label="Labels" :options="labels" /> <SearchFilter v-model="selectedLabels" :label="$t('global.labels')" :options="labels" />
<div class="dropdown"> <div class="dropdown">
<label tabindex="0" class="btn btn-xs">Options</label> <label tabindex="0" class="btn btn-xs">{{ $t("items.options") }}</label>
<div <div
tabindex="0" tabindex="0"
class="dropdown-content mt-1 max-h-72 p-4 w-64 overflow-auto shadow bg-base-100 rounded-md -translate-x-24" class="dropdown-content mt-1 max-h-72 p-4 w-64 overflow-auto shadow bg-base-100 rounded-md -translate-x-24"
> >
<label class="label cursor-pointer mr-auto"> <label class="label cursor-pointer mr-auto">
<input v-model="includeArchived" type="checkbox" class="toggle toggle-sm toggle-primary" /> <input v-model="includeArchived" type="checkbox" class="toggle toggle-sm toggle-primary" />
<span class="label-text ml-4"> Include Archived Items </span> <span class="label-text ml-4"> {{ $t("items.include_archive") }} </span>
</label> </label>
<label class="label cursor-pointer mr-auto"> <label class="label cursor-pointer mr-auto">
<input v-model="fieldSelector" type="checkbox" class="toggle toggle-sm toggle-primary" /> <input v-model="fieldSelector" type="checkbox" class="toggle toggle-sm toggle-primary" />
<span class="label-text ml-4"> Field Selector </span> <span class="label-text ml-4"> {{ $t("items.field_selector") }} </span>
</label> </label>
<label class="label cursor-pointer mr-auto"> <label class="label cursor-pointer mr-auto">
<input v-model="negateLabels" type="checkbox" class="toggle toggle-sm toggle-primary" /> <input v-model="negateLabels" type="checkbox" class="toggle toggle-sm toggle-primary" />
<span class="label-text ml-4"> Negate selected labels </span> <span class="label-text ml-4"> {{ $t("items.negate_labels") }} </span>
</label> </label>
<label class="label cursor-pointer mr-auto"> <label class="label cursor-pointer mr-auto">
<select v-model="orderBy" class="select select-bordered select-sm"> <select v-model="orderBy" class="select select-bordered select-sm">
<option value="name" selected>Name</option> <option value="name" selected>{{ $t("global.name") }}</option>
<option value="createdAt">Created At</option> <option value="createdAt">{{ $t("items.created_at") }}</option>
<option value="updatedAt">Updated At</option> <option value="updatedAt">{{ $t("items.updated_at") }}</option>
</select> </select>
<span class="label-text ml-4"> Order By </span> <span class="label-text ml-4"> {{ $t("items.order_by") }} </span>
</label> </label>
<hr class="my-2" /> <hr class="my-2" />
<BaseButton class="btn-block btn-sm" @click="reset"> Reset Search</BaseButton> <BaseButton class="btn-block btn-sm" @click="reset"> {{ $t("items.reset_search") }} </BaseButton>
</div> </div>
</div> </div>
<div class="dropdown ml-auto dropdown-end"> <div class="dropdown ml-auto dropdown-end">
<label tabindex="0" class="btn btn-xs">Tips</label> <label tabindex="0" class="btn btn-xs">{{ $t("items.tips") }}</label>
<div <div
tabindex="0" tabindex="0"
class="dropdown-content mt-1 p-4 w-[325px] text-sm overflow-auto shadow bg-base-100 rounded-md" class="dropdown-content mt-1 p-4 w-[325px] text-sm overflow-auto shadow bg-base-100 rounded-md"
> >
<p class="text-base">Search Tips</p> <p class="text-base">{{ $t("items.tips_sub") }}</p>
<ul class="mt-1 list-disc pl-6"> <ul class="mt-1 list-disc pl-6">
<li> <li>
Location and label filters use the 'OR' operation. If more than one is selected only one will be {{ $t("items.tip_1") }}
required for a match.
</li> </li>
<li>Searches prefixed with '#'' will query for a asset ID (example '#000-001')</li>
<li> <li>
Field filters use the 'OR' operation. If more than one is selected only one will be required for a {{ $t("items.tip_2") }}
match. </li>
<li>
{{ $t("items.tip_3") }}
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
<div v-if="fieldSelector" class="py-4 space-y-2"> <div v-if="fieldSelector" class="py-4 space-y-2">
<p>Custom Fields</p> <p>{{ $t("items.custom_fields") }}</p>
<div v-for="(f, idx) in fieldTuples" :key="idx" class="flex flex-wrap gap-2"> <div v-for="(f, idx) in fieldTuples" :key="idx" class="flex flex-wrap gap-2">
<div class="form-control w-full max-w-xs"> <div class="form-control w-full max-w-xs">
<label class="label"> <label class="label">
@@ -435,7 +435,7 @@
</div> </div>
<div class="form-control w-full max-w-xs"> <div class="form-control w-full max-w-xs">
<label class="label"> <label class="label">
<span class="label-text">Field Value</span> <span class="label-text">{{ $t("items.field_value") }}</span>
</label> </label>
<select v-model="fieldTuples[idx][1]" class="select-bordered select" :items="fieldValuesCache[f[0]]"> <select v-model="fieldTuples[idx][1]" class="select-bordered select" :items="fieldValuesCache[f[0]]">
<option v-for="v in fieldValuesCache[f[0]]" :key="v" :value="v">{{ v }}</option> <option v-for="v in fieldValuesCache[f[0]]" :key="v" :value="v">{{ v }}</option>
@@ -449,38 +449,42 @@
<MdiDelete class="w-5 h-5" /> <MdiDelete class="w-5 h-5" />
</button> </button>
</div> </div>
<BaseButton type="button" class="btn-sm mt-2" @click="() => fieldTuples.push(['', ''])"> Add</BaseButton> <BaseButton type="button" class="btn-sm mt-2" @click="() => fieldTuples.push(['', ''])">
{{ $t("items.add") }}
</BaseButton>
</div> </div>
</div> </div>
<section class="mt-10"> <section class="mt-10">
<BaseSectionHeader ref="itemsTitle"> Items </BaseSectionHeader> <BaseSectionHeader ref="itemsTitle"> {{ $t("global.items") }} </BaseSectionHeader>
<p class="text-base font-medium flex items-center"> <p class="text-base font-medium flex items-center">
{{ total }} Results {{ $t("items.results", { total: total }) }}
<span class="text-base ml-auto"> Page {{ page }} of {{ totalPages }}</span> <span class="text-base ml-auto"> {{ $t("items.pages", { page: page, totalPages: totalPages }) }} </span>
</p> </p>
<div ref="cardgrid" class="grid mt-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4"> <div ref="cardgrid" class="grid mt-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
<ItemCard v-for="item in items" :key="item.id" :item="item" /> <ItemCard v-for="item in items" :key="item.id" :item="item" />
<div class="hidden first:inline text-xl">No Items Found</div> <div class="hidden first:inline text-xl">{{ $t("items.no_results") }}</div>
</div> </div>
<div v-if="items.length > 0 && (hasNext || hasPrev)" class="mt-10 flex gap-2 flex-col items-center"> <div v-if="items.length > 0 && (hasNext || hasPrev)" class="mt-10 flex gap-2 flex-col items-center">
<div class="flex"> <div class="flex">
<div class="btn-group"> <div class="btn-group">
<button :disabled="!hasPrev" class="btn text-no-transform" @click="prev"> <button :disabled="!hasPrev" class="btn text-no-transform" @click="prev">
<MdiChevronLeft class="mr-1 h-6 w-6" name="mdi-chevron-left" /> <MdiChevronLeft class="mr-1 h-6 w-6" name="mdi-chevron-left" />
Prev {{ $t("items.prev_page") }}
</button>
<button v-if="hasPrev" class="btn text-no-transform" @click="page = 1">{{ $t("items.first") }}</button>
<button v-if="hasNext" class="btn text-no-transform" @click="page = totalPages">
{{ $t("items.last") }}
</button> </button>
<button v-if="hasPrev" class="btn text-no-transform" @click="page = 1">First</button>
<button v-if="hasNext" class="btn text-no-transform" @click="page = totalPages">Last</button>
<button :disabled="!hasNext" class="btn text-no-transform" @click="next"> <button :disabled="!hasNext" class="btn text-no-transform" @click="next">
Next {{ $t("items.next_page") }}
<MdiChevronRight class="ml-1 h-6 w-6" name="mdi-chevron-right" /> <MdiChevronRight class="ml-1 h-6 w-6" name="mdi-chevron-right" />
</button> </button>
</div> </div>
</div> </div>
<p class="text-sm font-bold">Page {{ page }} of {{ totalPages }}</p> <p class="text-sm font-bold">{{ $t("items.pages", { page: page, totalPages: totalPages }) }}</p>
</div> </div>
</section> </section>
</BaseContainer> </BaseContainer>

View File

@@ -89,13 +89,6 @@
notify.success("Group updated"); notify.success("Group updated");
} }
const pubApi = usePublicApi();
const { data: status } = useAsyncData(async () => {
const { data } = await pubApi.status();
return data;
});
const { setTheme } = useTheme(); const { setTheme } = useTheme();
const auth = useAuthContext(); const auth = useAuthContext();
@@ -305,11 +298,11 @@
<template> <template>
<div> <div>
<BaseModal v-model="passwordChange.dialog"> <BaseModal v-model="passwordChange.dialog">
<template #title> Change Password </template> <template #title> {{ $t("profile.change_password") }} </template>
<form @submit.prevent="changePassword"> <form @submit.prevent="changePassword">
<FormPassword v-model="passwordChange.current" label="Current Password" placeholder="" /> <FormPassword v-model="passwordChange.current" :label="$t('profile.current_password')" placeholder="" />
<FormPassword v-model="passwordChange.new" label="New Password" placeholder="" /> <FormPassword v-model="passwordChange.new" :label="$t('profile.new_password')" placeholder="" />
<PasswordScore v-model:valid="passwordChange.isValid" :password="passwordChange.new" /> <PasswordScore v-model:valid="passwordChange.isValid" :password="passwordChange.new" />
<div class="flex"> <div class="flex">
@@ -319,26 +312,26 @@
:disabled="!passwordChange.isValid" :disabled="!passwordChange.isValid"
type="submit" type="submit"
> >
Submit {{ $t("global.submit") }}
</BaseButton> </BaseButton>
</div> </div>
</form> </form>
</BaseModal> </BaseModal>
<BaseModal v-model="notifierDialog"> <BaseModal v-model="notifierDialog">
<template #title> {{ notifier ? "Edit" : "Create" }} Notifier </template> <template #title> {{ $t("profile.notifier_modal", {type: (notifier != null)}) }} </template>
<form @submit.prevent="createNotifier"> <form @submit.prevent="createNotifier">
<template v-if="notifier"> <template v-if="notifier">
<FormTextField v-model="notifier.name" label="Name" /> <FormTextField v-model="notifier.name" :label="$t('global.name')" />
<FormTextField v-model="notifier.url" label="URL" /> <FormTextField v-model="notifier.url" :label="$t('profile.url')" />
<div class="max-w-[100px]"> <div class="max-w-[100px]">
<FormCheckbox v-model="notifier.isActive" label="Enabled" /> <FormCheckbox v-model="notifier.isActive" :label="$t('profile.enabled')" />
</div> </div>
</template> </template>
<div class="flex gap-2 justify-between mt-4"> <div class="flex gap-2 justify-between mt-4">
<BaseButton :disabled="!(notifier && notifier.url)" type="button" @click="testNotifier"> Test </BaseButton> <BaseButton :disabled="!(notifier && notifier.url)" type="button" @click="testNotifier"> {{ $t("profile.test") }} </BaseButton>
<BaseButton type="submit"> Submit </BaseButton> <BaseButton type="submit"> {{ $t("global.submit") }} </BaseButton>
</div> </div>
</form> </form>
</BaseModal> </BaseModal>
@@ -348,8 +341,8 @@
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<MdiAccount class="mr-2 -mt-1 text-base-600" /> <MdiAccount class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> User Profile </span> <span class="text-base-600"> {{ $t("profile.user_profile") }} </span>
<template #description> Invite users, and manage your account. </template> <template #description> {{ $t("profile.user_profile_sub") }} </template>
</BaseSectionHeader> </BaseSectionHeader>
</template> </template>
@@ -357,8 +350,8 @@
<div class="p-4"> <div class="p-4">
<div class="flex gap-2"> <div class="flex gap-2">
<BaseButton size="sm" @click="openPassChange"> Change Password </BaseButton> <BaseButton size="sm" @click="openPassChange"> {{ $t("profile.change_password") }} </BaseButton>
<BaseButton size="sm" @click="generateToken"> Generate Invite Link </BaseButton> <BaseButton size="sm" @click="generateToken"> {{ $t("profile.gen_invite") }} </BaseButton>
</div> </div>
<div v-if="token" class="pt-4 flex items-center pl-1"> <div v-if="token" class="pt-4 flex items-center pl-1">
<CopyText class="mr-2 btn-primary btn btn-outline btn-square btn-sm" :text="tokenUrl" /> <CopyText class="mr-2 btn-primary btn btn-outline btn-square btn-sm" :text="tokenUrl" />
@@ -375,8 +368,8 @@
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<MdiMegaphone class="mr-2 -mt-1 text-base-600" /> <MdiMegaphone class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Notifiers </span> <span class="text-base-600"> {{ $t("profile.notifiers") }} </span>
<template #description> Get notifications for up coming maintenance reminders </template> <template #description> {{ $t("profile.notifiers_sub") }} </template>
</BaseSectionHeader> </BaseSectionHeader>
</template> </template>
@@ -399,11 +392,11 @@
</div> </div>
<div class="flex justify-between py-1 flex-wrap text-sm"> <div class="flex justify-between py-1 flex-wrap text-sm">
<p> <p>
<span v-if="n.isActive" class="badge badge-success"> Active </span> <span v-if="n.isActive" class="badge badge-success"> {{ $t("profile.active") }} </span>
<span v-else class="badge badge-error"> Inactive</span> <span v-else class="badge badge-error"> {{ $t("profile.inactive") }} </span>
</p> </p>
<p> <p>
Created {{ $t("global.created") }}
<DateTime format="relative" datetime-type="time" :date="n.createdAt" /> <DateTime format="relative" datetime-type="time" :date="n.createdAt" />
</p> </p>
</div> </div>
@@ -411,7 +404,7 @@
</div> </div>
<div class="p-4"> <div class="p-4">
<BaseButton size="sm" @click="openNotifierDialog"> Create </BaseButton> <BaseButton size="sm" @click="openNotifierDialog"> {{ $t("global.create") }} </BaseButton>
</div> </div>
</BaseCard> </BaseCard>
@@ -419,19 +412,19 @@
<template #title> <template #title>
<BaseSectionHeader class="pb-0"> <BaseSectionHeader class="pb-0">
<MdiAccountMultiple class="mr-2 -mt-1 text-base-600" /> <MdiAccountMultiple class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Group Settings </span> <span class="text-base-600"> {{ $t("profile.group_settings") }} </span>
<template #description> <template #description>
Shared Group Settings. You may need to refresh your browser for some settings to apply. {{ $t("profile.group_settings_sub") }}
</template> </template>
</BaseSectionHeader> </BaseSectionHeader>
</template> </template>
<div v-if="group && currencies && currencies.length > 0" class="p-5 pt-0"> <div v-if="group && currencies && currencies.length > 0" class="p-5 pt-0">
<FormSelect v-model="currency" label="Currency Format" :items="currencies" /> <FormSelect v-model="currency" :label="$t('profile.currency_format')" :items="currencies" />
<p class="m-2 text-sm">Example: {{ currencyExample }}</p> <p class="m-2 text-sm">Example: {{ currencyExample }}</p>
<div class="mt-4"> <div class="mt-4">
<BaseButton size="sm" @click="updateGroup"> Update Group </BaseButton> <BaseButton size="sm" @click="updateGroup"> {{ $t("profile.update_group") }} </BaseButton>
</div> </div>
</div> </div>
</BaseCard> </BaseCard>
@@ -440,10 +433,9 @@
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<MdiFill class="mr-2 text-base-600" /> <MdiFill class="mr-2 text-base-600" />
<span class="text-base-600"> Theme Settings </span> <span class="text-base-600"> {{ $t("profile.theme_settings") }} </span>
<template #description> <template #description>
Theme settings are stored in your browser's local storage. You can change the theme at any time. If you're {{ $t("profile.theme_settings_sub") }}
having trouble setting your theme try refreshing your browser.
</template> </template>
</BaseSectionHeader> </BaseSectionHeader>
</template> </template>
@@ -491,18 +483,15 @@
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<MdiDelete class="mr-2 -mt-1 text-base-600" /> <MdiDelete class="mr-2 -mt-1 text-base-600" />
<span class="text-base-600"> Delete Account</span> <span class="text-base-600"> {{ $t("profile.delete_account") }} </span>
<template #description> Delete your account and all its associated data. </template> <template #description> {{ $t("profile.delete_account_sub") }} </template>
</BaseSectionHeader> </BaseSectionHeader>
</template> </template>
<div class="p-4 px-6 border-t-2 border-gray-300"> <div class="p-4 px-6 border-t-2 border-gray-300">
<BaseButton size="sm" class="btn-error" @click="deleteProfile"> Delete Account </BaseButton> <BaseButton size="sm" class="btn-error" @click="deleteProfile"> {{ $t("profile.delete_account") }} </BaseButton>
</div> </div>
</BaseCard> </BaseCard>
</BaseContainer> </BaseContainer>
<footer v-if="status" class="text-center w-full bottom-0 pb-4">
<p class="text-center text-sm">Version: {{ status.build.version }} ~ Build: {{ status.build.commit }}</p>
</footer>
</div> </div>
</template> </template>

View File

@@ -308,7 +308,7 @@
</p> </p>
<p> <p>
This feature is in early development stages and may change in future releases, if you have feedback please This feature is in early development stages and may change in future releases, if you have feedback please
provide it in the <a href="https://github.com/sysadminsmedia/homebox/discussions/273">GitHub Discussion</a> provide it in the <a href="https://github.com/sysadminsmedia/homebox/discussions/53">GitHub Discussion</a>
</p> </p>
<h2>Tips</h2> <h2>Tips</h2>
<ul> <ul>

View File

@@ -42,8 +42,9 @@
<div class="border-t px-6 pb-3 border-gray-300 divide-gray-300 divide-y"> <div class="border-t px-6 pb-3 border-gray-300 divide-gray-300 divide-y">
<DetailAction @action="modals.import = true"> <DetailAction @action="modals.import = true">
<template #title>Import Inventory</template> <template #title>Import Inventory</template>
Imports the standard CSV format for Homebox. This will <b>not</b> overwrite any existing items in your Imports the standard CSV format for Homebox. Without an <code>HB.import_ref</code> column, this will
inventory. It will only add new items. <b>not</b> overwrite any existing items in your inventory, only add new items. Rows with an
<code>HB.import_ref</code> column are merged into existing items with the same import_ref, if one exists.
</DetailAction> </DetailAction>
<DetailAction @action="getExportCSV()"> <DetailAction @action="getExportCSV()">
<template #title>Export Inventory</template> <template #title>Export Inventory</template>
@@ -104,7 +105,7 @@
middleware: ["auth"], middleware: ["auth"],
}); });
useHead({ useHead({
title: "Homebox | Profile", title: "Homebox | Tools",
}); });
const modals = ref({ const modals = ref({

63
frontend/plugins/i18n.ts Normal file
View File

@@ -0,0 +1,63 @@
import type { CompileError, MessageCompiler, MessageContext } from "vue-i18n";
import { createI18n } from "vue-i18n";
import { IntlMessageFormat } from "intl-messageformat";
export default defineNuxtPlugin(({ vueApp }) => {
function checkDefaultLanguage() {
let matched = null;
const languages = Object.getOwnPropertyNames(messages())
languages.forEach(lang => {
if (lang === navigator.language) {
matched = lang;
}
});
if (!matched) {
languages.forEach(lang => {
const languagePartials = navigator.language.split('-')[0]
if (lang === languagePartials) {
matched = lang;
}
});
}
return matched;
}
const i18n = createI18n({
legacy: false,
globalInjection: true,
locale: checkDefaultLanguage() || "en",
fallbackLocale: "en",
messageCompiler,
messages: messages(),
});
vueApp.use(i18n);
});
export const messageCompiler: MessageCompiler = (message, { locale, key, onError }) => {
if (typeof message === "string") {
/**
* You can tune your message compiler performance more with your cache strategy or also memoization at here
*/
const formatter = new IntlMessageFormat(message, locale);
return (ctx: MessageContext) => {
return formatter.format(ctx.values);
};
} else {
/**
* for AST.
* If you would like to support it,
* You need to transform locale messages such as `json`, `yaml`, etc. with the bundle plugin.
*/
onError && onError(new Error("not support for AST") as CompileError);
return () => key;
}
};
export const messages: Object = () => {
let messages = {};
const modules = import.meta.glob('~//locales/**.json', { eager: true });
for (const path in modules) {
const key = path.slice(9, -5);
messages[key] = modules[path];
}
return messages;
};

12656
frontend/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff