Overview
Comment: | Add quick search to accounts lists for quickly finding accounts |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | accounts_refactor |
Files: | files | file ages | folders |
SHA3-256: |
5b2dfdefd4ce99747f973080ef9f3e87 |
User & Date: | bohwaz on 2022-11-05 16:46:33 |
Other Links: | branch diff | manifest | tags |
Context
2022-11-05
| ||
16:52 | Pre-select asset or liability, to get a sensible default check-in: 91144d5c10 user: bohwaz tags: accounts_refactor | |
16:46 | Add quick search to accounts lists for quickly finding accounts check-in: 5b2dfdefd4 user: bohwaz tags: accounts_refactor | |
05:08 | Fix migration of projects check-in: 86b60c055e user: bohwaz tags: accounts_refactor | |
Changes
Modified src/include/migrations/1.1/32.sql from [43af03b5d1] to [a7eb3b4440].
︙ | ︙ | |||
21 22 23 24 25 26 27 | SET id_project = (SELECT b.id FROM acc_projects AS b INNER JOIN acc_accounts_old c ON c.code = b.code WHERE c.id = a.id_project) WHERE id_project IS NOT NULL; UPDATE acc_transactions_lines AS a SET id_project = (SELECT b.id FROM acc_projects AS b INNER JOIN acc_accounts_old c ON c.code = b.code WHERE c.id = a.id_project) WHERE id_project IS NOT NULL; | | > | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | SET id_project = (SELECT b.id FROM acc_projects AS b INNER JOIN acc_accounts_old c ON c.code = b.code WHERE c.id = a.id_project) WHERE id_project IS NOT NULL; UPDATE acc_transactions_lines AS a SET id_project = (SELECT b.id FROM acc_projects AS b INNER JOIN acc_accounts_old c ON c.code = b.code WHERE c.id = a.id_project) WHERE id_project IS NOT NULL; -- Remove first 99 and 9 from code (added in 1.1.30) UPDATE acc_projects SET code = CASE WHEN SUBSTR(code, 1, 2) = '99' AND LENGTH(code) > 2 THEN SUBSTR(code, 3) ELSE code END; UPDATE acc_projects SET code = CASE WHEN SUBSTR(code, 1, 1) = '9' AND LENGTH(code) > 1 THEN SUBSTR(code, 2) ELSE code END; --UPDATE acc_transactions_lines SET id_project = NULL WHERE id_project NOT IN (SELECT id FROM acc_projects); --UPDATE acc_transactions_lines SET id_project = 424242 WHERE id_project IS NULL; INSERT INTO acc_accounts SELECT *, CASE WHEN type > 0 AND type <= 8 THEN 1 ELSE 0 END FROM acc_accounts_old; -- Delete old analytical accounts |
︙ | ︙ |
Modified src/templates/acc/charts/accounts/all.tpl from [f98b58b8c2] to [cab3c3255e].
1 2 3 4 | {include file="admin/_head.tpl" title=$chart.label current="acc/years"} {include file="acc/charts/accounts/_nav.tpl" current="all"} | > > > > > > > | | | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | {include file="admin/_head.tpl" title=$chart.label current="acc/years"} {include file="acc/charts/accounts/_nav.tpl" current="all"} <form method="post" action="{$self_url}" data-focus="1"> <p class="actions quick-search"> <input type="text" placeholder="Recherche rapide…" title="Filtrer la liste" />{button shape="delete" type="reset" title="Effacer la recherche"} {* We can't use input type="search" because Firefox sucks *} </p> <p class="help"> Les comptes marqués comme « <em>Ajouté</em> » ont été ajoutés au plan comptable officiel par vous-même. </p> {include file="common/dynamic_list_head.tpl"} {foreach from=$list->iterate() item="account"} <tr class="account account-level-{$account.level}"> <td class="num">{$account.code}</td> <th{if !$account.description} colspan=2{/if}>{$account.label}</th> |
︙ | ︙ | |||
36 37 38 39 40 41 42 | {/if} </td> </tr> {/foreach} </tbody> </table> | | | 41 42 43 44 45 46 47 48 49 50 51 52 | {/if} </td> </tr> {/foreach} </tbody> </table> <script type="text/javascript" src="{$admin_url}static/scripts/accounts_list.js"></script> </form> {include file="admin/_foot.tpl"} |
Modified src/templates/acc/charts/accounts/index.tpl from [af532ac7cc] to [5d942236c6].
1 2 3 4 | {include file="admin/_head.tpl" title=$chart.label current="acc/years"} {include file="acc/charts/accounts/_nav.tpl" current="favorites"} | > > > > > > > > | | | < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | {include file="admin/_head.tpl" title=$chart.label current="acc/years"} {include file="acc/charts/accounts/_nav.tpl" current="favorites"} <form method="post" action="all.php?id={$chart.id}"> <p class="actions quick-search"> <input type="text" placeholder="Recherche rapide…" title="Filtrer la liste" />{button shape="delete" type="reset" title="Effacer la recherche"} {* We can't use input type="search" because Firefox sucks *} </p> <p class="help"> Cette liste regroupe les comptes de banque, caisse, attente, tiers, dépense, recette ou bénévolat qui sont soit marqués comme favori, soit ajoutés manuellement, soit déjà utilisés dans un exercice. </p> <table class="list"> {foreach from=$accounts_grouped item="group"} <tbody> <tr> <td colspan="4"><h2 class="ruler">{$group.label}</h2></td> <td class="actions"> |
︙ | ︙ | |||
42 43 44 45 46 47 48 | </td> </tr> {/foreach} </tbody> {/foreach} </table> | | > | 48 49 50 51 52 53 54 55 56 57 58 59 | </td> </tr> {/foreach} </tbody> {/foreach} </table> <script type="text/javascript" src="{$admin_url}static/scripts/accounts_list.js"></script> </form> {include file="admin/_foot.tpl"} |
Modified src/templates/acc/charts/accounts/selector.tpl from [aa02383c7a] to [1be1c0e24c].
1 2 3 4 5 6 7 8 9 10 11 12 | {include file="admin/_head.tpl" title="Sélectionner un compte"} <div class="selector"> {if empty($grouped_accounts) && empty($accounts)} <p class="block alert">Le plan comptable ne comporte aucun compte de ce type.<br /> {linkbutton href="!acc/charts/accounts/new.php?id=%s&type=%s"|args:$chart.id,$targets[0] label="Créer un compte" shape="plus"} </p> {else} <header> | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | {include file="admin/_head.tpl" title="Sélectionner un compte"} <div class="selector"> {if empty($grouped_accounts) && empty($accounts)} <p class="block alert">Le plan comptable ne comporte aucun compte de ce type.<br /> {linkbutton href="!acc/charts/accounts/new.php?id=%s&type=%s"|args:$chart.id,$targets[0] label="Créer un compte" shape="plus"} </p> {else} <header> <h2 class="quick-search"> <input type="text" placeholder="Recherche rapide…" title="Filtrer la liste" />{button shape="delete" type="reset" title="Effacer la recherche"} {* We can't use input type="search" because Firefox sucks *} </h2> {if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_ADMIN)} <?php $page = isset($grouped_accounts) ? '' : 'all.php'; ?> <p class="edit">{linkbutton label="Modifier les comptes" href="!acc/charts/accounts/%s?id=%d&types=%s"|args:$page,$chart.id,$targets_str shape="edit"}</aside></p> {/if} |
︙ | ︙ | |||
32 33 34 35 36 37 38 | {foreach from=$group.accounts item="account"} <tr data-idx="{$index}" class="account"> <td class="bookmark">{if $account.bookmark}{icon shape="star" title="Compte favori"}{/if}</td> <td class="num">{$account.code}</td> <th>{$account.label}</th> <td class="desc">{$account.description}</td> <td class="actions"> | | | | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | {foreach from=$group.accounts item="account"} <tr data-idx="{$index}" class="account"> <td class="bookmark">{if $account.bookmark}{icon shape="star" title="Compte favori"}{/if}</td> <td class="num">{$account.code}</td> <th>{$account.label}</th> <td class="desc">{$account.description}</td> <td class="actions"> {button shape="right" value=$account.id data-label="%s — %s"|args:$account.code,$account.label label="Sélectionner"} </td> </tr> <?php $index++; ?> {/foreach} </tbody> </table> {/foreach} {else} <table class="list"> <tbody> {foreach from=$accounts item="account"} <tr data-idx="{$iteration}" class="account account-level-{$account->level()}"> <td class="bookmark">{if $account.bookmark}{icon shape="star" title="Compte favori"}{/if}</td> <td class="num">{$account.code}</td> <th>{$account.label}</th> <td class="actions"> {button shape="right" value=$account.id data-label="%s — %s"|args:$account.code,$account.label label="Sélectionner"} </td> </tr> {/foreach} </tbody> </table> {/if} |
︙ | ︙ |
Modified src/www/admin/static/scripts/accounts_list.js from [ac8766f7de] to [590fc24309].
|
| | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | $('button[name*=bookmark]').forEach((b) => { b.onclick = () => { b.value = parseInt(b.value) ? 0 : 1; b.setAttribute('data-icon', b.value == 1 ? '☑' : '☐'); fetch(document.forms[0].action, { 'method': 'POST', 'headers': {"Content-Type": "application/x-www-form-urlencoded"}, 'body': b.name + '=' + b.value }); return false; }; }); RegExp.escape = function(string) { return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') }; function normalizeString(str) { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, "") } var q = document.querySelector('.quick-search input[type=text]'); if (q) { var rows = document.querySelectorAll('table tr.account'); rows.forEach((e, k) => { var l = e.querySelector('td.num').innerText + ' ' + e.querySelector('th').innerText; e.setAttribute('data-search-label', normalizeString(l)); }); q.addEventListener('keyup', filterTableList); document.querySelector('.quick-search button[type=reset]').onclick = () => { q.value = ''; q.focus(); return filterTableList(); }; q.focus(); } function filterTableList() { var query = new RegExp(RegExp.escape(normalizeString(q.value)), 'i'); rows.forEach((elm) => { if (elm.getAttribute('data-search-label').match(query)) { g.toggle(elm, true); } else { g.toggle(elm, false); } }); return false; } |
Modified src/www/admin/static/scripts/selector.js from [eeca799734] to [5f77069dce].
1 2 3 4 5 6 7 8 | RegExp.escape = function(string) { return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') }; function normalizeString(str) { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, "") } | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | RegExp.escape = function(string) { return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') }; function normalizeString(str) { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, "") } var buttons = document.querySelectorAll('button[type=button]'); buttons.forEach((e) => { e.onclick = () => { window.parent.g.inputListSelected(e.value, e.getAttribute('data-label')); }; }); |
︙ | ︙ | |||
101 102 103 104 105 106 107 | return false; }); if (buttons[0]) { buttons[0].focus(); } | | > | | > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | < < < | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | return false; }); if (buttons[0]) { buttons[0].focus(); } var q = document.querySelector('.quick-search input[type=text]'); var qr = document.querySelector('.quick-search button[type=reset]'); if (q && qr) { q.addEventListener('keyup', filterTableList); qr.onclick = (e) => { q.value = ''; q.focus(); return filterTableList(e); }; q.focus(); } function filterTableList(e) { var query = new RegExp(RegExp.escape(normalizeString(q.value)), 'i'); rows.forEach((elm) => { if (elm.getAttribute('data-search-label').match(query)) { g.toggle(elm, true); } else { g.toggle(elm, false); } }); if (first = document.querySelector('tbody tr:not(.hidden)')) { if (f = document.querySelector('tr.focused')) { f.classList.remove('focused'); } first.classList.add('focused'); } if (e.key == 'Enter') { if (first = document.querySelector('tbody tr.focused:not(.hidden) button')) { first.click(); } } return false; } var o = document.getElementById('f_filter'); if (o) { o.onchange = () => { let s = new URLSearchParams(window.location.search); s.set("filter", o.value); window.location.search = s.toString(); }; } |
Modified src/www/admin/static/styles/03-forms.css from [6a971c609b] to [aeaac26b8f].
︙ | ︙ | |||
431 432 433 434 435 436 437 438 439 440 441 442 443 444 | dd.help.example { margin-left: 2.5em; font-size: .9em; } form p.actions { float: right; } /** Datepicker widget */ .datepicker-parent { position: relative; } | > | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | dd.help.example { margin-left: 2.5em; font-size: .9em; } form p.actions { float: right; margin: .5em; } /** Datepicker widget */ .datepicker-parent { position: relative; } |
︙ | ︙ | |||
711 712 713 714 715 716 717 718 719 720 721 722 723 724 | float: right; margin: 0; } .selector header h2 input { width: calc(100% - 1em); } .selector select { font-size: .9em; margin: .2em 0; padding: .2em; border-color: var(--gLightBorderColor); cursor: pointer; | > > > > > > > > > > > | 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 | float: right; margin: 0; } .selector header h2 input { width: calc(100% - 1em); } .quick-search button[type=reset] { margin-left: -2.5em; background: none; border: none; color: var(--gBorderColor); } h2.quick-search button[type=reset] { font-size: 1rem; } .selector select { font-size: .9em; margin: .2em 0; padding: .2em; border-color: var(--gLightBorderColor); cursor: pointer; |
︙ | ︙ |