From 86ccbbe83074fdb2649318836f951000656915eb Mon Sep 17 00:00:00 2001 From: jordi fita mas Date: Fri, 28 Apr 2023 00:06:48 +0200 Subject: [PATCH] Add keyboard controls for product search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are almost the same as for the multiselect, except that it “clicks” the option to “select” it, as this will trigger the replacement of the
with the whole product. --- po/ca.po | 277 ++++++++++++++-------------- po/es.po | 277 ++++++++++++++-------------- web/static/numerus.js | 136 ++++++++++++-- web/template/products/search.gohtml | 3 + 4 files changed, 409 insertions(+), 284 deletions(-) diff --git a/po/ca.po b/po/ca.po index 1a0daf2..c87bd2a 100644 --- a/po/ca.po +++ b/po/ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: numerus\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2023-04-18 20:59+0200\n" +"POT-Creation-Date: 2023-04-28 00:05+0200\n" "PO-Revision-Date: 2023-01-18 17:08+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Catalan \n" @@ -47,53 +47,53 @@ msgctxt "title" msgid "New Invoice" msgstr "Nova factura" -#: web/template/invoices/products.gohtml:49 -#: web/template/products/index.gohtml:25 +#: web/template/invoices/products.gohtml:48 +#: web/template/products/index.gohtml:38 msgctxt "product" msgid "All" msgstr "Tots" -#: web/template/invoices/products.gohtml:50 -#: web/template/products/index.gohtml:26 +#: web/template/invoices/products.gohtml:49 +#: web/template/products/index.gohtml:39 msgctxt "title" msgid "Name" msgstr "Nom" -#: web/template/invoices/products.gohtml:51 -#: web/template/invoices/view.gohtml:62 web/template/products/index.gohtml:28 +#: web/template/invoices/products.gohtml:50 +#: web/template/invoices/view.gohtml:62 web/template/products/index.gohtml:41 msgctxt "title" msgid "Price" msgstr "Preu" -#: web/template/invoices/products.gohtml:65 -#: web/template/products/index.gohtml:48 +#: web/template/invoices/products.gohtml:64 +#: web/template/products/index.gohtml:61 msgid "No products added yet." msgstr "No hi ha cap producte." -#: web/template/invoices/products.gohtml:73 web/template/invoices/new.gohtml:67 -#: web/template/invoices/edit.gohtml:68 +#: web/template/invoices/products.gohtml:72 web/template/invoices/new.gohtml:62 +#: web/template/invoices/edit.gohtml:62 msgctxt "action" msgid "Add products" msgstr "Afegeix productes" -#: web/template/invoices/new.gohtml:48 web/template/invoices/view.gohtml:67 -#: web/template/invoices/edit.gohtml:49 +#: web/template/invoices/new.gohtml:39 web/template/invoices/view.gohtml:67 +#: web/template/invoices/edit.gohtml:39 msgctxt "title" msgid "Subtotal" msgstr "Subtotal" -#: web/template/invoices/new.gohtml:58 web/template/invoices/view.gohtml:71 -#: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:59 +#: web/template/invoices/new.gohtml:49 web/template/invoices/view.gohtml:71 +#: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:49 msgctxt "title" msgid "Total" msgstr "Total" -#: web/template/invoices/new.gohtml:70 web/template/invoices/edit.gohtml:71 +#: web/template/invoices/new.gohtml:66 web/template/invoices/edit.gohtml:66 msgctxt "action" msgid "Update" msgstr "Actualitza" -#: web/template/invoices/new.gohtml:72 web/template/invoices/index.gohtml:21 +#: web/template/invoices/new.gohtml:68 web/template/invoices/index.gohtml:20 msgctxt "action" msgid "New invoice" msgstr "Nova factura" @@ -103,73 +103,73 @@ msgctxt "action" msgid "Download invoices" msgstr "Descarrega factures" -#: web/template/invoices/index.gohtml:41 +#: web/template/invoices/index.gohtml:40 web/template/products/index.gohtml:32 msgctxt "action" msgid "Filter" msgstr "Filtra" -#: web/template/invoices/index.gohtml:47 +#: web/template/invoices/index.gohtml:46 msgctxt "invoice" msgid "All" msgstr "Totes" -#: web/template/invoices/index.gohtml:48 web/template/invoices/view.gohtml:34 +#: web/template/invoices/index.gohtml:47 web/template/invoices/view.gohtml:34 msgctxt "title" msgid "Date" msgstr "Data" -#: web/template/invoices/index.gohtml:49 +#: web/template/invoices/index.gohtml:48 msgctxt "title" msgid "Invoice Num." msgstr "Núm. factura" -#: web/template/invoices/index.gohtml:50 web/template/contacts/index.gohtml:26 +#: web/template/invoices/index.gohtml:49 web/template/contacts/index.gohtml:25 msgctxt "title" msgid "Customer" msgstr "Client" -#: web/template/invoices/index.gohtml:51 +#: web/template/invoices/index.gohtml:50 msgctxt "title" msgid "Status" msgstr "Estat" -#: web/template/invoices/index.gohtml:52 web/template/contacts/index.gohtml:29 -#: web/template/products/index.gohtml:27 +#: web/template/invoices/index.gohtml:51 web/template/contacts/index.gohtml:28 +#: web/template/products/index.gohtml:40 msgctxt "title" msgid "Tags" msgstr "Etiquetes" -#: web/template/invoices/index.gohtml:53 +#: web/template/invoices/index.gohtml:52 msgctxt "title" msgid "Amount" msgstr "Import" -#: web/template/invoices/index.gohtml:54 +#: web/template/invoices/index.gohtml:53 msgctxt "title" msgid "Download" msgstr "Descàrrega" -#: web/template/invoices/index.gohtml:55 +#: web/template/invoices/index.gohtml:54 msgctxt "title" msgid "Actions" msgstr "Accions" -#: web/template/invoices/index.gohtml:62 +#: web/template/invoices/index.gohtml:61 msgctxt "action" msgid "Select invoice %v" msgstr "Selecciona factura %v" -#: web/template/invoices/index.gohtml:117 web/template/invoices/view.gohtml:19 +#: web/template/invoices/index.gohtml:116 web/template/invoices/view.gohtml:19 msgctxt "action" msgid "Edit" msgstr "Edita" -#: web/template/invoices/index.gohtml:125 web/template/invoices/view.gohtml:16 +#: web/template/invoices/index.gohtml:124 web/template/invoices/view.gohtml:16 msgctxt "action" msgid "Duplicate" msgstr "Duplica" -#: web/template/invoices/index.gohtml:135 +#: web/template/invoices/index.gohtml:134 msgid "No invoices added yet." msgstr "No hi ha cap factura." @@ -208,7 +208,7 @@ msgctxt "title" msgid "Edit Invoice “%s”" msgstr "Edició de la factura «%s»" -#: web/template/invoices/edit.gohtml:73 +#: web/template/invoices/edit.gohtml:68 msgctxt "action" msgid "Edit invoice" msgstr "Edita factura" @@ -265,27 +265,27 @@ msgctxt "title" msgid "Contacts" msgstr "Contactes" -#: web/template/contacts/new.gohtml:36 web/template/contacts/index.gohtml:15 +#: web/template/contacts/new.gohtml:36 web/template/contacts/index.gohtml:14 msgctxt "action" msgid "New contact" msgstr "Nou contacte" -#: web/template/contacts/index.gohtml:25 +#: web/template/contacts/index.gohtml:24 msgctxt "contact" msgid "All" msgstr "Tots" -#: web/template/contacts/index.gohtml:27 +#: web/template/contacts/index.gohtml:26 msgctxt "title" msgid "Email" msgstr "Correu-e" -#: web/template/contacts/index.gohtml:28 +#: web/template/contacts/index.gohtml:27 msgctxt "title" msgid "Phone" msgstr "Telèfon" -#: web/template/contacts/index.gohtml:50 +#: web/template/contacts/index.gohtml:49 msgid "No contacts added yet." msgstr "No hi ha cap contacte." @@ -415,22 +415,26 @@ msgctxt "title" msgid "Products" msgstr "Productes" -#: web/template/products/new.gohtml:32 web/template/products/index.gohtml:15 +#: web/template/products/new.gohtml:30 web/template/products/index.gohtml:14 msgctxt "action" msgid "New product" msgstr "Nou producte" +#: web/template/products/search.gohtml:12 +msgid "No products found." +msgstr "No s’ha trobat cap producte." + #: web/template/products/edit.gohtml:3 web/template/products/edit.gohtml:20 msgctxt "title" msgid "Edit Product “%s”" msgstr "Edició del producte «%s»" -#: web/template/products/edit.gohtml:36 +#: web/template/products/edit.gohtml:34 msgctxt "action" msgid "Update product" msgstr "Actualitza producte" -#: pkg/login.go:36 pkg/profile.go:40 pkg/contacts.go:211 +#: pkg/login.go:36 pkg/profile.go:40 pkg/contacts.go:199 msgctxt "input" msgid "Email" msgstr "Correu-e" @@ -440,11 +444,11 @@ msgctxt "input" msgid "Password" msgstr "Contrasenya" -#: pkg/login.go:69 pkg/profile.go:89 pkg/contacts.go:308 +#: pkg/login.go:69 pkg/profile.go:89 pkg/contacts.go:296 msgid "Email can not be empty." msgstr "No podeu deixar el correu-e en blanc." -#: pkg/login.go:70 pkg/profile.go:90 pkg/contacts.go:309 +#: pkg/login.go:70 pkg/profile.go:90 pkg/contacts.go:297 msgid "This value is not a valid email. It should be like name@domain.com." msgstr "Aquest valor no és un correu-e vàlid. Hauria de ser similar a nom@domini.cat." @@ -456,49 +460,72 @@ msgstr "No podeu deixar la contrasenya en blanc." msgid "Invalid user or password." msgstr "Nom d’usuari o contrasenya incorrectes." -#: pkg/products.go:204 pkg/invoices.go:732 +#: pkg/products.go:161 pkg/products.go:260 pkg/invoices.go:771 msgctxt "input" msgid "Name" msgstr "Nom" -#: pkg/products.go:210 pkg/invoices.go:737 -msgctxt "input" -msgid "Description" -msgstr "Descripció" - -#: pkg/products.go:215 pkg/invoices.go:741 -msgctxt "input" -msgid "Price" -msgstr "Preu" - -#: pkg/products.go:225 pkg/invoices.go:767 -msgctxt "input" -msgid "Taxes" -msgstr "Imposts" - -#: pkg/products.go:231 pkg/invoices.go:187 pkg/invoices.go:582 -#: pkg/invoices.go:964 pkg/contacts.go:268 +#: pkg/products.go:166 pkg/products.go:287 pkg/invoices.go:187 +#: pkg/invoices.go:597 pkg/invoices.go:1031 pkg/contacts.go:256 msgctxt "input" msgid "Tags" msgstr "Etiquetes" -#: pkg/products.go:250 pkg/profile.go:92 pkg/invoices.go:806 +#: pkg/products.go:170 pkg/invoices.go:191 +msgctxt "input" +msgid "Tags Condition" +msgstr "Condició de les etiquetes" + +#: pkg/products.go:174 pkg/invoices.go:195 +msgctxt "tag condition" +msgid "All" +msgstr "Totes" + +#: pkg/products.go:175 pkg/invoices.go:196 +msgid "Invoices must have all the specified labels." +msgstr "Les factures han de tenir totes les etiquetes." + +#: pkg/products.go:179 pkg/invoices.go:200 +msgctxt "tag condition" +msgid "Any" +msgstr "Qualsevol" + +#: pkg/products.go:180 pkg/invoices.go:201 +msgid "Invoices must have at least one of the specified labels." +msgstr "Les factures han de tenir com a mínim una de les etiquetes." + +#: pkg/products.go:266 pkg/invoices.go:785 +msgctxt "input" +msgid "Description" +msgstr "Descripció" + +#: pkg/products.go:271 pkg/invoices.go:789 +msgctxt "input" +msgid "Price" +msgstr "Preu" + +#: pkg/products.go:281 pkg/invoices.go:815 +msgctxt "input" +msgid "Taxes" +msgstr "Imposts" + +#: pkg/products.go:306 pkg/profile.go:92 pkg/invoices.go:856 msgid "Name can not be empty." msgstr "No podeu deixar el nom en blanc." -#: pkg/products.go:251 pkg/invoices.go:807 +#: pkg/products.go:307 pkg/invoices.go:857 msgid "Price can not be empty." msgstr "No podeu deixar el preu en blanc." -#: pkg/products.go:252 pkg/invoices.go:808 +#: pkg/products.go:308 pkg/invoices.go:858 msgid "Price must be a number greater than zero." msgstr "El preu ha de ser un número major a zero." -#: pkg/products.go:254 pkg/invoices.go:816 +#: pkg/products.go:310 pkg/invoices.go:866 msgid "Selected tax is not valid." msgstr "Heu seleccionat un impost que no és vàlid." -#: pkg/products.go:255 pkg/invoices.go:817 +#: pkg/products.go:311 pkg/invoices.go:867 msgid "You can only select a tax of each class." msgstr "Només podeu seleccionar un impost de cada classe." @@ -606,7 +633,7 @@ msgstr "La confirmació no és igual a la contrasenya." msgid "Selected language is not valid." msgstr "Heu seleccionat un idioma que no és vàlid." -#: pkg/invoices.go:160 pkg/invoices.go:565 +#: pkg/invoices.go:160 pkg/invoices.go:580 msgctxt "input" msgid "Customer" msgstr "Client" @@ -615,7 +642,7 @@ msgstr "Client" msgid "All customers" msgstr "Tots els clients" -#: pkg/invoices.go:166 pkg/invoices.go:559 +#: pkg/invoices.go:166 pkg/invoices.go:574 msgctxt "input" msgid "Invoice Status" msgstr "Estat de la factura" @@ -639,213 +666,193 @@ msgctxt "input" msgid "To Date" msgstr "Fins la data" -#: pkg/invoices.go:191 -msgctxt "input" -msgid "Tags Condition" -msgstr "Condició de les etiquetes" - -#: pkg/invoices.go:195 -msgctxt "tag condition" -msgid "All" -msgstr "Totes" - -#: pkg/invoices.go:196 -msgid "Invoices must have all the specified labels." -msgstr "Les factures han de tenir totes les etiquetes." - -#: pkg/invoices.go:200 -msgctxt "tag condition" -msgid "Any" -msgstr "Qualsevol" - -#: pkg/invoices.go:201 -msgid "Invoices must have at least one of the specified labels." -msgstr "Les factures han de tenir com a mínim una de les etiquetes." - -#: pkg/invoices.go:405 +#: pkg/invoices.go:423 msgid "Select a customer to bill." msgstr "Escolliu un client a facturar." -#: pkg/invoices.go:504 +#: pkg/invoices.go:524 msgid "invoices.zip" msgstr "factures.zip" -#: pkg/invoices.go:510 pkg/invoices.go:950 +#: pkg/invoices.go:530 pkg/invoices.go:1017 msgid "Invalid action" msgstr "Acció invàlida." -#: pkg/invoices.go:571 +#: pkg/invoices.go:586 msgctxt "input" msgid "Invoice Date" msgstr "Data de factura" -#: pkg/invoices.go:577 +#: pkg/invoices.go:592 msgctxt "input" msgid "Notes" msgstr "Notes" -#: pkg/invoices.go:587 +#: pkg/invoices.go:602 msgctxt "input" msgid "Payment Method" msgstr "Mètode de pagament" -#: pkg/invoices.go:624 +#: pkg/invoices.go:638 msgid "Selected invoice status is not valid." msgstr "Heu seleccionat un estat de factura que no és vàlid." -#: pkg/invoices.go:625 +#: pkg/invoices.go:639 msgid "Selected customer is not valid." msgstr "Heu seleccionat un client que no és vàlid." -#: pkg/invoices.go:626 +#: pkg/invoices.go:640 msgid "Invoice date can not be empty." msgstr "No podeu deixar la data de la factura en blanc." -#: pkg/invoices.go:627 +#: pkg/invoices.go:641 msgid "Invoice date must be a valid date." msgstr "La data de facturació ha de ser vàlida." -#: pkg/invoices.go:629 +#: pkg/invoices.go:643 msgid "Selected payment method is not valid." msgstr "Heu seleccionat un mètode de pagament que no és vàlid." -#: pkg/invoices.go:722 pkg/invoices.go:727 +#: pkg/invoices.go:761 pkg/invoices.go:766 msgctxt "input" msgid "Id" msgstr "Identificador" -#: pkg/invoices.go:750 +#: pkg/invoices.go:798 msgctxt "input" msgid "Quantity" msgstr "Quantitat" -#: pkg/invoices.go:758 +#: pkg/invoices.go:806 msgctxt "input" msgid "Discount (%)" msgstr "Descompte (%)" -#: pkg/invoices.go:805 -msgid "Product ID can not be empty." -msgstr "No podeu deixar l’identificador del producte en blanc." +#: pkg/invoices.go:854 +msgid "Product ID must be a number greater than zero." +msgstr "L’ID del producte ha de ser un número major a zero." -#: pkg/invoices.go:810 +#: pkg/invoices.go:860 msgid "Quantity can not be empty." msgstr "No podeu deixar la quantitat en blanc." -#: pkg/invoices.go:811 +#: pkg/invoices.go:861 msgid "Quantity must be a number greater than zero." msgstr "La quantitat ha de ser un número major a zero." -#: pkg/invoices.go:813 +#: pkg/invoices.go:863 msgid "Discount can not be empty." msgstr "No podeu deixar el descompte en blanc." -#: pkg/invoices.go:814 +#: pkg/invoices.go:864 msgid "Discount must be a percentage between 0 and 100." msgstr "El descompte ha de ser un percentatge entre 0 i 100." -#: pkg/contacts.go:181 +#: pkg/contacts.go:169 msgctxt "input" msgid "Business name" msgstr "Nom i cognoms" -#: pkg/contacts.go:191 +#: pkg/contacts.go:179 msgctxt "input" msgid "VAT number" msgstr "DNI / NIF" -#: pkg/contacts.go:197 +#: pkg/contacts.go:185 msgctxt "input" msgid "Trade name" msgstr "Nom comercial" -#: pkg/contacts.go:202 +#: pkg/contacts.go:190 msgctxt "input" msgid "Phone" msgstr "Telèfon" -#: pkg/contacts.go:220 +#: pkg/contacts.go:208 msgctxt "input" msgid "Web" msgstr "Web" -#: pkg/contacts.go:228 +#: pkg/contacts.go:216 msgctxt "input" msgid "Address" msgstr "Adreça" -#: pkg/contacts.go:237 +#: pkg/contacts.go:225 msgctxt "input" msgid "City" msgstr "Població" -#: pkg/contacts.go:243 +#: pkg/contacts.go:231 msgctxt "input" msgid "Province" msgstr "Província" -#: pkg/contacts.go:249 +#: pkg/contacts.go:237 msgctxt "input" msgid "Postal code" msgstr "Codi postal" -#: pkg/contacts.go:258 +#: pkg/contacts.go:246 msgctxt "input" msgid "Country" msgstr "País" -#: pkg/contacts.go:296 +#: pkg/contacts.go:284 msgid "Selected country is not valid." msgstr "Heu seleccionat un país que no és vàlid." -#: pkg/contacts.go:300 +#: pkg/contacts.go:288 msgid "Business name can not be empty." msgstr "No podeu deixar el nom i els cognoms en blanc." -#: pkg/contacts.go:301 +#: pkg/contacts.go:289 msgid "Business name must have at least two letters." msgstr "Nom i cognoms han de tenir com a mínim dues lletres." -#: pkg/contacts.go:302 +#: pkg/contacts.go:290 msgid "VAT number can not be empty." msgstr "No podeu deixar el DNI o NIF en blanc." -#: pkg/contacts.go:303 +#: pkg/contacts.go:291 msgid "This value is not a valid VAT number." msgstr "Aquest valor no és un DNI o NIF vàlid." -#: pkg/contacts.go:305 +#: pkg/contacts.go:293 msgid "Phone can not be empty." msgstr "No podeu deixar el telèfon en blanc." -#: pkg/contacts.go:306 +#: pkg/contacts.go:294 msgid "This value is not a valid phone number." msgstr "Aquest valor no és un telèfon vàlid." -#: pkg/contacts.go:312 +#: pkg/contacts.go:300 msgid "This value is not a valid web address. It should be like https://domain.com/." msgstr "Aquest valor no és una adreça web vàlida. Hauria de ser similar a https://domini.cat/." -#: pkg/contacts.go:314 +#: pkg/contacts.go:302 msgid "Address can not be empty." msgstr "No podeu deixar l’adreça en blanc." -#: pkg/contacts.go:315 +#: pkg/contacts.go:303 msgid "City can not be empty." msgstr "No podeu deixar la població en blanc." -#: pkg/contacts.go:316 +#: pkg/contacts.go:304 msgid "Province can not be empty." msgstr "No podeu deixar la província en blanc." -#: pkg/contacts.go:317 +#: pkg/contacts.go:305 msgid "Postal code can not be empty." msgstr "No podeu deixar el codi postal en blanc." -#: pkg/contacts.go:318 +#: pkg/contacts.go:306 msgid "This value is not a valid postal code." msgstr "Aquest valor no és un codi postal vàlid." +#~ msgid "Product ID can not be empty." +#~ msgstr "No podeu deixar l’identificador del producte en blanc." + #~ msgctxt "input" #~ msgid "Number" #~ msgstr "Número" diff --git a/po/es.po b/po/es.po index a0ee258..18f4d35 100644 --- a/po/es.po +++ b/po/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: numerus\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n" -"POT-Creation-Date: 2023-04-18 20:59+0200\n" +"POT-Creation-Date: 2023-04-28 00:05+0200\n" "PO-Revision-Date: 2023-01-18 17:45+0100\n" "Last-Translator: jordi fita mas \n" "Language-Team: Spanish \n" @@ -47,53 +47,53 @@ msgctxt "title" msgid "New Invoice" msgstr "Nueva factura" -#: web/template/invoices/products.gohtml:49 -#: web/template/products/index.gohtml:25 +#: web/template/invoices/products.gohtml:48 +#: web/template/products/index.gohtml:38 msgctxt "product" msgid "All" msgstr "Todos" -#: web/template/invoices/products.gohtml:50 -#: web/template/products/index.gohtml:26 +#: web/template/invoices/products.gohtml:49 +#: web/template/products/index.gohtml:39 msgctxt "title" msgid "Name" msgstr "Nombre" -#: web/template/invoices/products.gohtml:51 -#: web/template/invoices/view.gohtml:62 web/template/products/index.gohtml:28 +#: web/template/invoices/products.gohtml:50 +#: web/template/invoices/view.gohtml:62 web/template/products/index.gohtml:41 msgctxt "title" msgid "Price" msgstr "Precio" -#: web/template/invoices/products.gohtml:65 -#: web/template/products/index.gohtml:48 +#: web/template/invoices/products.gohtml:64 +#: web/template/products/index.gohtml:61 msgid "No products added yet." msgstr "No hay productos." -#: web/template/invoices/products.gohtml:73 web/template/invoices/new.gohtml:67 -#: web/template/invoices/edit.gohtml:68 +#: web/template/invoices/products.gohtml:72 web/template/invoices/new.gohtml:62 +#: web/template/invoices/edit.gohtml:62 msgctxt "action" msgid "Add products" msgstr "Añadir productos" -#: web/template/invoices/new.gohtml:48 web/template/invoices/view.gohtml:67 -#: web/template/invoices/edit.gohtml:49 +#: web/template/invoices/new.gohtml:39 web/template/invoices/view.gohtml:67 +#: web/template/invoices/edit.gohtml:39 msgctxt "title" msgid "Subtotal" msgstr "Subtotal" -#: web/template/invoices/new.gohtml:58 web/template/invoices/view.gohtml:71 -#: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:59 +#: web/template/invoices/new.gohtml:49 web/template/invoices/view.gohtml:71 +#: web/template/invoices/view.gohtml:111 web/template/invoices/edit.gohtml:49 msgctxt "title" msgid "Total" msgstr "Total" -#: web/template/invoices/new.gohtml:70 web/template/invoices/edit.gohtml:71 +#: web/template/invoices/new.gohtml:66 web/template/invoices/edit.gohtml:66 msgctxt "action" msgid "Update" msgstr "Actualizar" -#: web/template/invoices/new.gohtml:72 web/template/invoices/index.gohtml:21 +#: web/template/invoices/new.gohtml:68 web/template/invoices/index.gohtml:20 msgctxt "action" msgid "New invoice" msgstr "Nueva factura" @@ -103,73 +103,73 @@ msgctxt "action" msgid "Download invoices" msgstr "Descargar facturas" -#: web/template/invoices/index.gohtml:41 +#: web/template/invoices/index.gohtml:40 web/template/products/index.gohtml:32 msgctxt "action" msgid "Filter" msgstr "Filtrar" -#: web/template/invoices/index.gohtml:47 +#: web/template/invoices/index.gohtml:46 msgctxt "invoice" msgid "All" msgstr "Todas" -#: web/template/invoices/index.gohtml:48 web/template/invoices/view.gohtml:34 +#: web/template/invoices/index.gohtml:47 web/template/invoices/view.gohtml:34 msgctxt "title" msgid "Date" msgstr "Fecha" -#: web/template/invoices/index.gohtml:49 +#: web/template/invoices/index.gohtml:48 msgctxt "title" msgid "Invoice Num." msgstr "Nº factura" -#: web/template/invoices/index.gohtml:50 web/template/contacts/index.gohtml:26 +#: web/template/invoices/index.gohtml:49 web/template/contacts/index.gohtml:25 msgctxt "title" msgid "Customer" msgstr "Cliente" -#: web/template/invoices/index.gohtml:51 +#: web/template/invoices/index.gohtml:50 msgctxt "title" msgid "Status" msgstr "Estado" -#: web/template/invoices/index.gohtml:52 web/template/contacts/index.gohtml:29 -#: web/template/products/index.gohtml:27 +#: web/template/invoices/index.gohtml:51 web/template/contacts/index.gohtml:28 +#: web/template/products/index.gohtml:40 msgctxt "title" msgid "Tags" msgstr "Etiquetes" -#: web/template/invoices/index.gohtml:53 +#: web/template/invoices/index.gohtml:52 msgctxt "title" msgid "Amount" msgstr "Importe" -#: web/template/invoices/index.gohtml:54 +#: web/template/invoices/index.gohtml:53 msgctxt "title" msgid "Download" msgstr "Descargar" -#: web/template/invoices/index.gohtml:55 +#: web/template/invoices/index.gohtml:54 msgctxt "title" msgid "Actions" msgstr "Acciones" -#: web/template/invoices/index.gohtml:62 +#: web/template/invoices/index.gohtml:61 msgctxt "action" msgid "Select invoice %v" msgstr "Seleccionar factura %v" -#: web/template/invoices/index.gohtml:117 web/template/invoices/view.gohtml:19 +#: web/template/invoices/index.gohtml:116 web/template/invoices/view.gohtml:19 msgctxt "action" msgid "Edit" msgstr "Editar" -#: web/template/invoices/index.gohtml:125 web/template/invoices/view.gohtml:16 +#: web/template/invoices/index.gohtml:124 web/template/invoices/view.gohtml:16 msgctxt "action" msgid "Duplicate" msgstr "Duplicar" -#: web/template/invoices/index.gohtml:135 +#: web/template/invoices/index.gohtml:134 msgid "No invoices added yet." msgstr "No hay facturas." @@ -208,7 +208,7 @@ msgctxt "title" msgid "Edit Invoice “%s”" msgstr "Edición del la factura «%s»" -#: web/template/invoices/edit.gohtml:73 +#: web/template/invoices/edit.gohtml:68 msgctxt "action" msgid "Edit invoice" msgstr "Editar factura" @@ -265,27 +265,27 @@ msgctxt "title" msgid "Contacts" msgstr "Contactos" -#: web/template/contacts/new.gohtml:36 web/template/contacts/index.gohtml:15 +#: web/template/contacts/new.gohtml:36 web/template/contacts/index.gohtml:14 msgctxt "action" msgid "New contact" msgstr "Nuevo contacto" -#: web/template/contacts/index.gohtml:25 +#: web/template/contacts/index.gohtml:24 msgctxt "contact" msgid "All" msgstr "Todos" -#: web/template/contacts/index.gohtml:27 +#: web/template/contacts/index.gohtml:26 msgctxt "title" msgid "Email" msgstr "Correo-e" -#: web/template/contacts/index.gohtml:28 +#: web/template/contacts/index.gohtml:27 msgctxt "title" msgid "Phone" msgstr "Teléfono" -#: web/template/contacts/index.gohtml:50 +#: web/template/contacts/index.gohtml:49 msgid "No contacts added yet." msgstr "No hay contactos." @@ -415,22 +415,26 @@ msgctxt "title" msgid "Products" msgstr "Productos" -#: web/template/products/new.gohtml:32 web/template/products/index.gohtml:15 +#: web/template/products/new.gohtml:30 web/template/products/index.gohtml:14 msgctxt "action" msgid "New product" msgstr "Nuevo producto" +#: web/template/products/search.gohtml:12 +msgid "No products found." +msgstr "No se ha encontrado ningún producto." + #: web/template/products/edit.gohtml:3 web/template/products/edit.gohtml:20 msgctxt "title" msgid "Edit Product “%s”" msgstr "Edición del producto «%s»" -#: web/template/products/edit.gohtml:36 +#: web/template/products/edit.gohtml:34 msgctxt "action" msgid "Update product" msgstr "Actualizar producto" -#: pkg/login.go:36 pkg/profile.go:40 pkg/contacts.go:211 +#: pkg/login.go:36 pkg/profile.go:40 pkg/contacts.go:199 msgctxt "input" msgid "Email" msgstr "Correo-e" @@ -440,11 +444,11 @@ msgctxt "input" msgid "Password" msgstr "Contraseña" -#: pkg/login.go:69 pkg/profile.go:89 pkg/contacts.go:308 +#: pkg/login.go:69 pkg/profile.go:89 pkg/contacts.go:296 msgid "Email can not be empty." msgstr "No podéis dejar el correo-e en blanco." -#: pkg/login.go:70 pkg/profile.go:90 pkg/contacts.go:309 +#: pkg/login.go:70 pkg/profile.go:90 pkg/contacts.go:297 msgid "This value is not a valid email. It should be like name@domain.com." msgstr "Este valor no es un correo-e válido. Tiene que ser parecido a nombre@dominio.es." @@ -456,49 +460,72 @@ msgstr "No podéis dejar la contraseña en blanco." msgid "Invalid user or password." msgstr "Nombre de usuario o contraseña inválido." -#: pkg/products.go:204 pkg/invoices.go:732 +#: pkg/products.go:161 pkg/products.go:260 pkg/invoices.go:771 msgctxt "input" msgid "Name" msgstr "Nombre" -#: pkg/products.go:210 pkg/invoices.go:737 -msgctxt "input" -msgid "Description" -msgstr "Descripción" - -#: pkg/products.go:215 pkg/invoices.go:741 -msgctxt "input" -msgid "Price" -msgstr "Precio" - -#: pkg/products.go:225 pkg/invoices.go:767 -msgctxt "input" -msgid "Taxes" -msgstr "Impuestos" - -#: pkg/products.go:231 pkg/invoices.go:187 pkg/invoices.go:582 -#: pkg/invoices.go:964 pkg/contacts.go:268 +#: pkg/products.go:166 pkg/products.go:287 pkg/invoices.go:187 +#: pkg/invoices.go:597 pkg/invoices.go:1031 pkg/contacts.go:256 msgctxt "input" msgid "Tags" msgstr "Etiquetes" -#: pkg/products.go:250 pkg/profile.go:92 pkg/invoices.go:806 +#: pkg/products.go:170 pkg/invoices.go:191 +msgctxt "input" +msgid "Tags Condition" +msgstr "Condición de las etiquetas" + +#: pkg/products.go:174 pkg/invoices.go:195 +msgctxt "tag condition" +msgid "All" +msgstr "Todas" + +#: pkg/products.go:175 pkg/invoices.go:196 +msgid "Invoices must have all the specified labels." +msgstr "Las facturas deben tener todas las etiquetas." + +#: pkg/products.go:179 pkg/invoices.go:200 +msgctxt "tag condition" +msgid "Any" +msgstr "Cualquiera" + +#: pkg/products.go:180 pkg/invoices.go:201 +msgid "Invoices must have at least one of the specified labels." +msgstr "Las facturas debent tener como mínimo una de las etiquetas." + +#: pkg/products.go:266 pkg/invoices.go:785 +msgctxt "input" +msgid "Description" +msgstr "Descripción" + +#: pkg/products.go:271 pkg/invoices.go:789 +msgctxt "input" +msgid "Price" +msgstr "Precio" + +#: pkg/products.go:281 pkg/invoices.go:815 +msgctxt "input" +msgid "Taxes" +msgstr "Impuestos" + +#: pkg/products.go:306 pkg/profile.go:92 pkg/invoices.go:856 msgid "Name can not be empty." msgstr "No podéis dejar el nombre en blanco." -#: pkg/products.go:251 pkg/invoices.go:807 +#: pkg/products.go:307 pkg/invoices.go:857 msgid "Price can not be empty." msgstr "No podéis dejar el precio en blanco." -#: pkg/products.go:252 pkg/invoices.go:808 +#: pkg/products.go:308 pkg/invoices.go:858 msgid "Price must be a number greater than zero." msgstr "El precio tiene que ser un número mayor a cero." -#: pkg/products.go:254 pkg/invoices.go:816 +#: pkg/products.go:310 pkg/invoices.go:866 msgid "Selected tax is not valid." msgstr "Habéis escogido un impuesto que no es válido." -#: pkg/products.go:255 pkg/invoices.go:817 +#: pkg/products.go:311 pkg/invoices.go:867 msgid "You can only select a tax of each class." msgstr "Solo podéis escoger un impuesto de cada clase." @@ -606,7 +633,7 @@ msgstr "La confirmación no corresponde con la contraseña." msgid "Selected language is not valid." msgstr "Habéis escogido un idioma que no es válido." -#: pkg/invoices.go:160 pkg/invoices.go:565 +#: pkg/invoices.go:160 pkg/invoices.go:580 msgctxt "input" msgid "Customer" msgstr "Cliente" @@ -615,7 +642,7 @@ msgstr "Cliente" msgid "All customers" msgstr "Todos los clientes" -#: pkg/invoices.go:166 pkg/invoices.go:559 +#: pkg/invoices.go:166 pkg/invoices.go:574 msgctxt "input" msgid "Invoice Status" msgstr "Estado de la factura" @@ -639,213 +666,193 @@ msgctxt "input" msgid "To Date" msgstr "Hasta la fecha" -#: pkg/invoices.go:191 -msgctxt "input" -msgid "Tags Condition" -msgstr "Condición de las etiquetas" - -#: pkg/invoices.go:195 -msgctxt "tag condition" -msgid "All" -msgstr "Todas" - -#: pkg/invoices.go:196 -msgid "Invoices must have all the specified labels." -msgstr "Las facturas deben tener todas las etiquetas." - -#: pkg/invoices.go:200 -msgctxt "tag condition" -msgid "Any" -msgstr "Cualquiera" - -#: pkg/invoices.go:201 -msgid "Invoices must have at least one of the specified labels." -msgstr "Las facturas debent tener como mínimo una de las etiquetas." - -#: pkg/invoices.go:405 +#: pkg/invoices.go:423 msgid "Select a customer to bill." msgstr "Escoged un cliente a facturar." -#: pkg/invoices.go:504 +#: pkg/invoices.go:524 msgid "invoices.zip" msgstr "facturas.zip" -#: pkg/invoices.go:510 pkg/invoices.go:950 +#: pkg/invoices.go:530 pkg/invoices.go:1017 msgid "Invalid action" msgstr "Acción inválida." -#: pkg/invoices.go:571 +#: pkg/invoices.go:586 msgctxt "input" msgid "Invoice Date" msgstr "Fecha de factura" -#: pkg/invoices.go:577 +#: pkg/invoices.go:592 msgctxt "input" msgid "Notes" msgstr "Notas" -#: pkg/invoices.go:587 +#: pkg/invoices.go:602 msgctxt "input" msgid "Payment Method" msgstr "Método de pago" -#: pkg/invoices.go:624 +#: pkg/invoices.go:638 msgid "Selected invoice status is not valid." msgstr "Habéis escogido un estado de factura que no es válido." -#: pkg/invoices.go:625 +#: pkg/invoices.go:639 msgid "Selected customer is not valid." msgstr "Habéis escogido un cliente que no es válido." -#: pkg/invoices.go:626 +#: pkg/invoices.go:640 msgid "Invoice date can not be empty." msgstr "No podéis dejar la fecha de la factura en blanco." -#: pkg/invoices.go:627 +#: pkg/invoices.go:641 msgid "Invoice date must be a valid date." msgstr "La fecha de factura debe ser válida." -#: pkg/invoices.go:629 +#: pkg/invoices.go:643 msgid "Selected payment method is not valid." msgstr "Habéis escogido un método de pago que no es válido." -#: pkg/invoices.go:722 pkg/invoices.go:727 +#: pkg/invoices.go:761 pkg/invoices.go:766 msgctxt "input" msgid "Id" msgstr "Identificador" -#: pkg/invoices.go:750 +#: pkg/invoices.go:798 msgctxt "input" msgid "Quantity" msgstr "Cantidad" -#: pkg/invoices.go:758 +#: pkg/invoices.go:806 msgctxt "input" msgid "Discount (%)" msgstr "Descuento (%)" -#: pkg/invoices.go:805 -msgid "Product ID can not be empty." -msgstr "No podéis dejar el identificador de producto en blanco." +#: pkg/invoices.go:854 +msgid "Product ID must be a number greater than zero." +msgstr "El ID de producto tiene que ser un número mayor a cero." -#: pkg/invoices.go:810 +#: pkg/invoices.go:860 msgid "Quantity can not be empty." msgstr "No podéis dejar la cantidad en blanco." -#: pkg/invoices.go:811 +#: pkg/invoices.go:861 msgid "Quantity must be a number greater than zero." msgstr "La cantidad tiene que ser un número mayor a cero." -#: pkg/invoices.go:813 +#: pkg/invoices.go:863 msgid "Discount can not be empty." msgstr "No podéis dejar el descuento en blanco." -#: pkg/invoices.go:814 +#: pkg/invoices.go:864 msgid "Discount must be a percentage between 0 and 100." msgstr "El descuento tiene que ser un porcentaje entre 0 y 100." -#: pkg/contacts.go:181 +#: pkg/contacts.go:169 msgctxt "input" msgid "Business name" msgstr "Nombre y apellidos" -#: pkg/contacts.go:191 +#: pkg/contacts.go:179 msgctxt "input" msgid "VAT number" msgstr "DNI / NIF" -#: pkg/contacts.go:197 +#: pkg/contacts.go:185 msgctxt "input" msgid "Trade name" msgstr "Nombre comercial" -#: pkg/contacts.go:202 +#: pkg/contacts.go:190 msgctxt "input" msgid "Phone" msgstr "Teléfono" -#: pkg/contacts.go:220 +#: pkg/contacts.go:208 msgctxt "input" msgid "Web" msgstr "Web" -#: pkg/contacts.go:228 +#: pkg/contacts.go:216 msgctxt "input" msgid "Address" msgstr "Dirección" -#: pkg/contacts.go:237 +#: pkg/contacts.go:225 msgctxt "input" msgid "City" msgstr "Población" -#: pkg/contacts.go:243 +#: pkg/contacts.go:231 msgctxt "input" msgid "Province" msgstr "Provincia" -#: pkg/contacts.go:249 +#: pkg/contacts.go:237 msgctxt "input" msgid "Postal code" msgstr "Código postal" -#: pkg/contacts.go:258 +#: pkg/contacts.go:246 msgctxt "input" msgid "Country" msgstr "País" -#: pkg/contacts.go:296 +#: pkg/contacts.go:284 msgid "Selected country is not valid." msgstr "Habéis escogido un país que no es válido." -#: pkg/contacts.go:300 +#: pkg/contacts.go:288 msgid "Business name can not be empty." msgstr "No podéis dejar el nombre y los apellidos en blanco." -#: pkg/contacts.go:301 +#: pkg/contacts.go:289 msgid "Business name must have at least two letters." msgstr "El nombre y los apellidos deben contener como mínimo dos letras." -#: pkg/contacts.go:302 +#: pkg/contacts.go:290 msgid "VAT number can not be empty." msgstr "No podéis dejar el DNI o NIF en blanco." -#: pkg/contacts.go:303 +#: pkg/contacts.go:291 msgid "This value is not a valid VAT number." msgstr "Este valor no es un DNI o NIF válido." -#: pkg/contacts.go:305 +#: pkg/contacts.go:293 msgid "Phone can not be empty." msgstr "No podéis dejar el teléfono en blanco." -#: pkg/contacts.go:306 +#: pkg/contacts.go:294 msgid "This value is not a valid phone number." msgstr "Este valor no es un teléfono válido." -#: pkg/contacts.go:312 +#: pkg/contacts.go:300 msgid "This value is not a valid web address. It should be like https://domain.com/." msgstr "Este valor no es una dirección web válida. Tiene que ser parecida a https://dominio.es/." -#: pkg/contacts.go:314 +#: pkg/contacts.go:302 msgid "Address can not be empty." msgstr "No podéis dejar la dirección en blanco." -#: pkg/contacts.go:315 +#: pkg/contacts.go:303 msgid "City can not be empty." msgstr "No podéis dejar la población en blanco." -#: pkg/contacts.go:316 +#: pkg/contacts.go:304 msgid "Province can not be empty." msgstr "No podéis dejar la provincia en blanco." -#: pkg/contacts.go:317 +#: pkg/contacts.go:305 msgid "Postal code can not be empty." msgstr "No podéis dejar el código postal en blanco." -#: pkg/contacts.go:318 +#: pkg/contacts.go:306 msgid "This value is not a valid postal code." msgstr "Este valor no es un código postal válido válido." +#~ msgid "Product ID can not be empty." +#~ msgstr "No podéis dejar el identificador de producto en blanco." + #~ msgctxt "input" #~ msgid "Number" #~ msgstr "Número" diff --git a/web/static/numerus.js b/web/static/numerus.js index 761d13f..be79afa 100644 --- a/web/static/numerus.js +++ b/web/static/numerus.js @@ -532,20 +532,132 @@ class ProductSearch extends HTMLDivElement { this.init(); } } + if (this.initialized) { + this.onSearchKeydownHandler = (e) => { + switch (e.code) { + case "Enter": + e.preventDefault(); + this.selectHighlighted(); + break; + case "ArrowDown": + if (e.altKey) { + this.open(); + } else { + e.preventDefault(); + this.highlightNext(); + } + break; + case "ArrowUp": + if (e.altKey) { + this.close(); + } else { + e.preventDefault(); + this.highlightPrev(); + } + break; + case "Escape": + this.close(); + break; + } + }; + this.input.addEventListener('keydown', this.onSearchKeydownHandler); + this.onFocusOutHandler = (e) => { + if (this.contains(e.target)) return; + if (!e.target.isConnected) return; + this.close(); + } + window.addEventListener('focusin', this.onFocusOutHandler); + document.addEventListener('click', this.onFocusOutHandler); + } + } + + disconnectedCallback() { + if (this.initialized) { + document.removeEventListener('click', this.onFocusOutHandler); + window.removeEventListener('focusin', this.onFocusOutHandler); + this.onFocusOutHandler = null; + this.input.removeEventListener('keydown', this.onSearchKeydownHandler); + this.onSearchKeydownHandler = null; + } } init() { this.initialized = true; - const list = document.createElement('ul'); - list.classList.add('options') - list.setAttribute('role', 'listbox') - this.append(list); - + this.input.setAttribute('spellcheck', 'false'); + this.input.setAttribute('autocomplete', 'false'); + this.input.setAttribute('role', 'combobox'); + + this.options = document.createElement('ul'); + this.append(this.options); + this.options.classList.add('options') + this.options.setAttribute('role', 'listbox') + this.options.dataset.hxOn = "htmx:afterSettle: this.parentNode.settled()"; + const indicator = document.createElement('img'); + this.append(indicator); indicator.classList.add('htmx-indicator'); indicator.src = '/static/bars.svg'; - this.append(indicator); + + this.close(); + } + + settled() { + this.open(); + } + + open() { + this.options.removeAttribute('style'); + this.input.setAttribute('aria-expanded', 'true'); + const products = this.options.querySelectorAll('li[id]'); + if (products.length > 0) { + this.highlight(this.currentHighlighted(), products.item(0)); + } + } + + close() { + this.input.removeAttribute('aria-activedescendant'); + this.input.setAttribute('aria-expanded', 'false'); + this.options.style.display = 'none'; + } + + highlightNext() { + const current = this.currentHighlighted(); + if (!current) { + return; + } + this.highlight(current, current.nextElementSibling); + } + + highlightPrev() { + const current = this.currentHighlighted(); + if (!current) { + return; + } + this.highlight(current, current.previousElementSibling); + } + + highlight(current, upcoming) { + if (!upcoming) { + return; + } + if (current) { + current.classList.remove('highlight'); + } + this.input.setAttribute('aria-activedescendant', upcoming.id); + this.highlighted = upcoming.dataset.index; + upcoming.classList.add('highlight'); + } + + selectHighlighted() { + const highlighted = this.currentHighlighted(); + if (highlighted) { + highlighted.click(); + } + } + + currentHighlighted() { + return document.getElementById(this.input.getAttribute('aria-activedescendant')); } } @@ -602,12 +714,10 @@ htmx.on(document, 'alpine:init', () => { htmx.on('htmx:error', (error) => { this.showError(error.detail.errorInfo.error); }); - }, - showError(message) { + }, showError(message) { this.toasts.push(message); this.popUp(); - }, - popUp() { + }, popUp() { if (this.toasts.length === 0) { return; } @@ -622,8 +732,7 @@ htmx.on(document, 'alpine:init', () => { this.toast = this.toasts[0]; this.show = true; this.timeoutId = setTimeout(this.dismiss.bind(this), 4000); - }, - dismiss() { + }, dismiss() { if (!this.show) { // already dismissed return; @@ -631,8 +740,7 @@ htmx.on(document, 'alpine:init', () => { this.show = false; clearTimeout(this.timeoutId); this.timeoutId = setTimeout(this.remove.bind(this), 350); - }, - remove() { + }, remove() { clearTimeout(this.timeoutId); this.toasts.splice(0, 1); this.toast = ""; diff --git a/web/template/products/search.gohtml b/web/template/products/search.gohtml index 4d3d1b1..dbf4108 100644 --- a/web/template/products/search.gohtml +++ b/web/template/products/search.gohtml @@ -2,10 +2,13 @@ {{- /*gotype: []dev.tandem.ws/tandem/numerus/pkg.ProductEntry*/ -}} {{- range $product := . }}
  • {{ .Name }}
  • + {{ else }} +
  • {{( gettext "No products found." )}}
  • {{- end }} {{- end }}