feat: Pay Salary quick action on home dashboard (deep-link to modal)
Admin Quick Actions tile -> /payroll/?action=pay-salary; the payroll page auto-clicks the existing paySalaryBtn then strips the param. Reuses all existing Pay-Salary machinery; param inert server-side. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
56c10ab938
commit
9ab0c68243
@ -209,6 +209,13 @@
|
||||
<i class="fas fa-money-check-alt"></i>
|
||||
<span>Run Payroll</span>
|
||||
</a>
|
||||
{# === PAY SALARY — quick path: opens the Pay-Salary modal on /payroll/ === #}
|
||||
{# Same fa-user-tie icon as the payroll dashboard's Pay Salary button so #}
|
||||
{# users have one mental model for "salary = fa-user-tie". #}
|
||||
<a href="{% url 'payroll_dashboard' %}?action=pay-salary" class="quick-action">
|
||||
<i class="fas fa-user-tie"></i>
|
||||
<span>Pay Salary</span>
|
||||
</a>
|
||||
<a href="{% url 'work_history' %}" class="quick-action">
|
||||
<i class="fas fa-history"></i>
|
||||
<span>View History</span>
|
||||
|
||||
@ -2116,6 +2116,22 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
});
|
||||
}
|
||||
|
||||
// === Quick-action deep-link: /payroll/?action=pay-salary ===
|
||||
// The home dashboard "Pay Salary" Quick Action links here with this
|
||||
// param. Auto-click the existing Pay Salary button (which does the
|
||||
// clean-slate + type=Salary + managers-only scoping + modal open),
|
||||
// then strip the param so a manual refresh or Back doesn't re-pop
|
||||
// the modal. Best-effort — never let a deep-link quirk block the page.
|
||||
try {
|
||||
var _qsAction = new URLSearchParams(window.location.search).get('action');
|
||||
if (_qsAction === 'pay-salary' && paySalaryBtn) {
|
||||
paySalaryBtn.click();
|
||||
var _u = new URL(window.location.href);
|
||||
_u.searchParams.delete('action');
|
||||
window.history.replaceState({}, '', _u.pathname + _u.search + _u.hash);
|
||||
}
|
||||
} catch (e) { /* deep-link is best-effort; never block the page */ }
|
||||
|
||||
// When the modal is opened from the HEADER button (not quick-adjust,
|
||||
// not Pay-Salary), clear any pre-selected workers/project and reset
|
||||
// the type to Bonus.
|
||||
|
||||
@ -3307,6 +3307,37 @@ class WorkerListPayTypeFilterTests(TestCase):
|
||||
)
|
||||
|
||||
|
||||
class PaySalaryQuickActionTests(TestCase):
|
||||
"""Home dashboard 'Pay Salary' Quick Action: an admin sees a tile
|
||||
that deep-links /payroll/?action=pay-salary; the param is inert
|
||||
server-side (no view change). The auto-open click is client-side
|
||||
JS, verified by manual checklist (not asserted here)."""
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.admin = User.objects.create_user(
|
||||
username='psqa_admin', password='pw',
|
||||
is_staff=True, is_superuser=True,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
self.client.force_login(self.admin)
|
||||
|
||||
def test_home_has_pay_salary_quick_action(self):
|
||||
resp = self.client.get('/')
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
# The tile links to the payroll dashboard with the deep-link param.
|
||||
self.assertContains(resp, '?action=pay-salary')
|
||||
# And is labelled "Pay Salary".
|
||||
self.assertContains(resp, 'Pay Salary')
|
||||
|
||||
def test_payroll_dashboard_ignores_action_param(self):
|
||||
# The param is purely a client-side signal; the view must not
|
||||
# care about it — same 200 as a plain /payroll/ load.
|
||||
resp = self.client.get('/payroll/?action=pay-salary')
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
|
||||
class WorkHistoryTeamFilterTests(TestCase):
|
||||
"""The /history/ page accepts ?team=<id> to narrow to logs tagged
|
||||
with that team, ?team=none for logs with no team set, and empty
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user