@layerfi/components 0.1.129-alpha.1 → 0.1.129

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -222,7 +222,7 @@ const getIntlLocale = (locale) => {
222
222
  return isSupportedLocale(locale) ? locale : DEFAULT_LOCALE;
223
223
  };
224
224
  const name = "@layerfi/components";
225
- const version$1 = "0.1.129-alpha.1";
225
+ const version$1 = "0.1.129";
226
226
  const description = "Layer React Components";
227
227
  const main = "dist/cjs/index.cjs";
228
228
  const module$1 = "dist/esm/index.mjs";
@@ -393,15 +393,13 @@ var getCustomHeaders = () => ({
393
393
  "Layer-Locale": _locale,
394
394
  "Layer-React-Version": package_default.version
395
395
  });
396
- const get = (url) => (baseUrl, accessToken, options) => () => {
397
- return fetch(`${baseUrl}${url((options === null || options === void 0 ? void 0 : options.params) || {})}`, {
398
- headers: _objectSpread2({
399
- "Authorization": "Bearer " + (accessToken || ""),
400
- "Content-Type": "application/json"
401
- }, getCustomHeaders()),
402
- method: "GET"
403
- }).then((res) => handleResponse(res)).catch((error$38) => handleException(error$38));
404
- };
396
+ const get = (url) => (baseUrl, accessToken, options) => () => fetch(`${baseUrl}${url((options === null || options === void 0 ? void 0 : options.params) || {})}`, {
397
+ headers: _objectSpread2({
398
+ "Authorization": "Bearer " + (accessToken || ""),
399
+ "Content-Type": "application/json"
400
+ }, getCustomHeaders()),
401
+ method: "GET"
402
+ }).then((res) => handleResponse(res)).catch((error$38) => handleException(error$38));
405
403
  const getText = (url) => (baseUrl, accessToken, options) => () => fetch(`${baseUrl}${url((options === null || options === void 0 ? void 0 : options.params) || {})}`, {
406
404
  headers: _objectSpread2({ Authorization: "Bearer " + (accessToken || "") }, getCustomHeaders()),
407
405
  method: "GET"
@@ -1759,11 +1757,7 @@ var overview_default$1 = {
1759
1757
  chart_type: chart_type$1,
1760
1758
  label: label$35
1761
1759
  };
1762
- const action$30 = {
1763
- "collapse_rows": "Collapse all rows",
1764
- "expand_rows": "Expand all rows",
1765
- "search_reports": "Search reports"
1766
- };
1760
+ const action$30 = { "search_reports": "Search reports" };
1767
1761
  const empty$22 = {
1768
1762
  "no_detail_lines_found": "No detail lines found",
1769
1763
  "no_detail_lines_pnl_item": "There are no detail lines for this profit and loss item",
@@ -1888,20 +1882,12 @@ const error$24 = {
1888
1882
  };
1889
1883
  const label$31 = {
1890
1884
  "additional_actions": "Additional actions",
1891
- "additional_state_taxes_estimate_owed": "Additional State Taxes Estimate (Owed)",
1892
- "adjusted_gross_income": "Adjusted Gross Income",
1893
- "amount_applied_federal_w2": "Amount Applied from Federal W-2 Withholding",
1894
- "amount_applied_state_withholding": "Amount Applied from State Withholding",
1895
1885
  "annual_taxes": "Annual taxes",
1896
1886
  "annual_w2_income": "Annual W-2 income",
1897
- "business_income": "Business Income",
1898
- "business_income_deduction_rate": "Business Income Deduction ({{rate}})",
1899
1887
  "business_income_taxes": "Business Income Taxes",
1900
1888
  "business_income_taxes_projected": "Projected Business Income Taxes",
1901
1889
  "calculated_from_categorized_transactions": "Calculated based on your categorized transactions and tracked mileage",
1902
1890
  "categorization_incomplete": "Categorization incomplete",
1903
- "deductible_expenses": "Deductible Expenses",
1904
- "deductible_mileage_expenses": "Deductible Mileage Expenses",
1905
1891
  "deductions": "Deductions",
1906
1892
  "due": "Due",
1907
1893
  "due_with_date": "Due: {{date}}",
@@ -1910,26 +1896,15 @@ const label$31 = {
1910
1896
  "estimated_taxes": "Estimated taxes",
1911
1897
  "estimates": "Estimates",
1912
1898
  "federal": "Federal",
1913
- "federal_deductions": "Federal Deductions",
1914
1899
  "federal_state_tax_payments": "Federal and state tax payments for the selected tax year",
1915
1900
  "federal_state_tax_payments_projected": "Projected federal and state tax payments for the selected tax year",
1916
- "federal_tax": "Federal Tax",
1917
- "federal_tax_estimate_owed": "Federal Tax Estimate (Owed)",
1918
1901
  "federal_tax_information": "Federal Tax Information",
1919
- "federal_tax_rate": "Federal Tax Rate",
1920
- "federal_taxes": "Federal Taxes",
1921
- "federal_taxes_projected": "Projected Federal Taxes",
1922
1902
  "filing_status": "Filing status",
1923
1903
  "full_year_projection": "Full year projection",
1924
1904
  "head_household": "Head of household",
1925
1905
  "home_office_area_sq": "Home office area (sq ft)",
1926
- "home_office_deduction": "Home Office Deduction",
1927
1906
  "married_filing_jointly": "Married filing jointly",
1928
1907
  "married_filing_separately": "Married filing separately",
1929
- "medicare_surtax_estimate_owed": "Medicare Surtax Estimate (Owed)",
1930
- "medicare_surtax_rate": "Medicare Surtax Rate",
1931
- "medicare_tax_estimate_owed": "Medicare Tax Estimate (Owed)",
1932
- "medicare_tax_rate": "Medicare Tax Rate",
1933
1908
  "overtime_income": "Overtime income",
1934
1909
  "owed_quarter": "Owed This Quarter",
1935
1910
  "paid": "Paid",
@@ -1939,59 +1914,33 @@ const label$31 = {
1939
1914
  "q2": "Q2",
1940
1915
  "q3": "Q3",
1941
1916
  "q4": "Q4",
1942
- "qualified_overtime_deduction": "Qualified Overtime Deduction",
1943
- "qualified_tip_deduction": "Qualified Tip Deduction",
1944
1917
  "qualifying_widow_er": "Qualifying widow(er)",
1945
1918
  "quarter": "Quarter",
1946
1919
  "quarter_taxes": "{{quarterLabel}} taxes",
1947
1920
  "remaining_balance": "Remaining Balance",
1948
1921
  "rolled_over_from_previous_quarter": "Rolled Over From Previous Quarter",
1949
- "self_employment_deduction": "Self-Employment Deduction",
1950
1922
  "single": "Single",
1951
- "social_security_tax_estimate_owed": "Social Security Tax Estimate (Owed)",
1952
- "social_security_tax_rate": "Social Security Tax Rate",
1953
1923
  "state": "State",
1954
- "state_adjusted_gross_income": "State Adjusted Gross Income",
1955
- "state_deductions": "State Deductions",
1956
- "state_income_tax_estimate_owed": "State Income Tax Estimate (Owed)",
1957
- "state_tax": "State Tax",
1958
- "state_tax_rate": "State Tax Rate",
1959
- "state_taxable_income": "State Taxable Income",
1960
- "tax_estimate_view": "Tax estimate view",
1961
- "tax_information": "State Tax Information",
1962
- "tax_name_estimate_owed": "{{taxName}} Estimate (Owed)",
1963
- "tax_name_rate": "{{taxName}} Rate",
1964
1924
  "tax_details": "Tax Details",
1965
1925
  "tax_details_amount": "Amount",
1966
1926
  "tax_details_label": "Label",
1927
+ "tax_estimate_view": "Tax estimate view",
1928
+ "tax_information": "State Tax Information",
1967
1929
  "tax_payments": "Tax Payments",
1968
1930
  "tax_payments_projected": "Projected Tax Payments",
1969
1931
  "tax_profile": "Tax Profile",
1970
1932
  "tax_profile_saved": "Tax profile saved",
1971
1933
  "tax_summary": "Tax Summary",
1972
- "taxable_amount_tax_name": "Taxable Amount for {{taxName}}",
1973
- "taxable_business_income": "Taxable Business Income",
1974
- "taxable_business_income_projected": "Projected Taxable Business Income",
1975
- "taxable_income": "Taxable Income",
1976
1934
  "taxable_income_estimate_to_date_for_year": "Taxable income estimate to date for year {{year}}",
1977
1935
  "taxable_income_estimate_to_date_for_year_projected": "Taxable income projection for year {{year}}",
1978
1936
  "taxable_income_for_year": "Taxable income for {{year}}",
1979
1937
  "taxable_income_for_year_projected": "Projected taxable income for {{year}}",
1980
- "taxable_medicare_income": "Taxable Medicare Income",
1981
- "taxable_medicare_surtax_income": "Taxable Medicare Surtax Income",
1982
- "taxable_social_security_income": "Taxable Social Security Income",
1983
- "taxes_by_state_name": "State Taxes ({{stateName}})",
1984
- "taxes_by_state_name_projected": "Projected State Taxes ({{stateName}})",
1985
- "taxes_due": "Taxes Due",
1986
1938
  "taxes_due_at": "Taxes due on {{date}}",
1987
1939
  "taxes_owed": "Taxes Owed",
1988
1940
  "taxes_owed_projected": "Projected Taxes Owed",
1989
1941
  "taxes_paid": "Taxes Paid",
1990
1942
  "tip_income": "Tip income",
1991
- "total_deductions": "Total Deductions",
1992
- "total_federal_tax_estimate": "Total Federal Tax Estimate",
1993
1943
  "total_paid": "Total Paid",
1994
- "total_state_tax_estimate": "Total State Tax Estimate",
1995
1944
  "uncategorized_transactions_one": "{{count}} uncategorized transaction",
1996
1945
  "uncategorized_transactions_other": "{{count}} uncategorized transactions",
1997
1946
  "uncategorized_transactions_with_year_one": "{{count}} uncategorized transaction ({{year}})",
@@ -1999,7 +1948,6 @@ const label$31 = {
1999
1948
  "use_custom_withholding": "Use custom withholding?",
2000
1949
  "use_simplified_home_office": "Use simplified home office deduction?",
2001
1950
  "use_standard_mileage_deduction": "Use standard mileage deduction?",
2002
- "w2_income": "W-2 Income",
2003
1951
  "withholding_amount": "Withholding amount",
2004
1952
  "year_to_date": "Year to date",
2005
1953
  "your_tax_deadlines": "Your tax deadlines"
@@ -2798,7 +2746,7 @@ const label$19 = {
2798
2746
  "equities": "Capitaux propres",
2799
2747
  "expenses": "Dépenses",
2800
2748
  "gross_profit": "Bénéfice brut",
2801
- "hide_details": "",
2749
+ "hide_details": "Masquer les détails",
2802
2750
  "id": "ID",
2803
2751
  "keep_editing": "Continuer à modifier",
2804
2752
  "liabilities": "Passifs",
@@ -2825,7 +2773,7 @@ const label$19 = {
2825
2773
  "row": "Ligne",
2826
2774
  "savings": "Compte d’épargne",
2827
2775
  "select_all": "Tout sélectionner",
2828
- "show_details": "",
2776
+ "show_details": "Afficher les détails",
2829
2777
  "source": "Source",
2830
2778
  "status": "Statut",
2831
2779
  "tax_estimates": "Estimations fiscales",
@@ -3363,11 +3311,7 @@ var overview_default = {
3363
3311
  chart_type,
3364
3312
  label: label$10
3365
3313
  };
3366
- const action$8 = {
3367
- "collapse_rows": "Réduire toutes les lignes",
3368
- "expand_rows": "Afficher toutes les lignes",
3369
- "search_reports": "Rechercher des rapports"
3370
- };
3314
+ const action$8 = { "search_reports": "Rechercher des rapports" };
3371
3315
  const empty$6 = {
3372
3316
  "no_detail_lines_found": "Aucune ligne de détail trouvée",
3373
3317
  "no_detail_lines_pnl_item": "Il n’y a aucune ligne de détail pour cet élément de l’état des résultats",
@@ -3470,8 +3414,8 @@ const disclaimer = {
3470
3414
  "content": "L’outil d’estimation des impôts et le contenu connexe sont fournis à titre informatif seulement et ne constituent pas des conseils juridiques, comptables ou fiscaux, ni un substitut à l’avis d’un professionnel. Nous ne sommes pas un planificateur financier ni un conseiller fiscal, et les utilisateurs assument l’entière responsabilité de leurs obligations fiscales, de l’exactitude des données et du respect des lois. Tous les calculs sont des estimations et peuvent contenir des erreurs. Ils reposent uniquement sur les renseignements que vous nous fournissez."
3471
3415
  };
3472
3416
  const empty$4 = {
3473
- "no_tax_details": "",
3474
- "no_tax_details_description": "",
3417
+ "no_tax_details": "Aucun détail fiscal",
3418
+ "no_tax_details_description": "Aucun détail fiscal trouvé",
3475
3419
  "no_tax_payments_to_display": "Il n’y a aucun paiement d’impôt à afficher.",
3476
3420
  "tax_payments": "Aucun paiement d’impôt trouvé"
3477
3421
  };
@@ -3479,33 +3423,25 @@ const error$5 = {
3479
3423
  "disclaimer_required": "Vous devez reconnaître l’avis de non-responsabilité pour continuer.",
3480
3424
  "feature_not_enabled": "Les estimations d'impôt ne sont pas activées.",
3481
3425
  "load_tax_deadlines": "Impossible de charger vos échéances fiscales",
3482
- "load_tax_details": "",
3426
+ "load_tax_details": "Impossible de charger vos détails fiscaux",
3483
3427
  "load_tax_estimates": "Nous n’avons pas pu charger vos estimations fiscales",
3484
3428
  "load_tax_estimates_summary": "Nous n’avons pas pu charger votre sommaire fiscal",
3485
3429
  "load_tax_information": "Impossible de charger les renseignements fiscaux",
3486
3430
  "load_tax_payments": "Nous n’avons pas pu charger vos paiements d’impôt",
3487
3431
  "retrieve_tax_profile": "Nous n’avons pas pu récupérer votre profil fiscal. Veuillez vérifier votre connexion et réessayer.",
3488
- "while_loading_tax_details": "",
3432
+ "while_loading_tax_details": "Une erreur s’est produite lors du chargement de vos détails fiscaux. Veuillez vérifier votre connexion et réessayer.",
3489
3433
  "while_loading_tax_estimates": "Une erreur s’est produite lors du chargement de vos estimations d’impôt. Veuillez vérifier votre connexion et réessayer.",
3490
3434
  "while_loading_tax_payments": "Une erreur s’est produite lors du chargement de vos paiements d’impôt. Veuillez vérifier votre connexion et réessayer.",
3491
3435
  "while_loading_tax_summary": "Une erreur s’est produite lors du chargement de votre sommaire fiscal. Veuillez vérifier votre connexion et réessayer."
3492
3436
  };
3493
3437
  const label$6 = {
3494
3438
  "additional_actions": "Actions supplémentaires",
3495
- "additional_state_taxes_estimate_owed": "Estimation des impôts d’État supplémentaires (à payer)",
3496
- "adjusted_gross_income": "Revenu brut ajusté",
3497
- "amount_applied_federal_w2": "Montant appliqué de la retenue fédérale du formulaire W-2",
3498
- "amount_applied_state_withholding": "Montant appliqué de la retenue d'impôt de l'État",
3499
3439
  "annual_taxes": "Impôts annuels",
3500
3440
  "annual_w2_income": "Revenu annuel indiqué sur le formulaire W-2",
3501
- "business_income": "Revenu d’entreprise",
3502
- "business_income_deduction_rate": "Déduction pour revenu d’entreprise ({{rate}})",
3503
3441
  "business_income_taxes": "Impôts sur le revenu d’entreprise",
3504
3442
  "business_income_taxes_projected": "Impôts projetés sur le revenu d’entreprise",
3505
3443
  "calculated_from_categorized_transactions": "Calculé en fonction de vos opérations catégorisées et de votre kilométrage suivi",
3506
3444
  "categorization_incomplete": "Catégorisation incomplète",
3507
- "deductible_expenses": "Dépenses déductibles",
3508
- "deductible_mileage_expenses": "Frais de kilométrage déductibles",
3509
3445
  "deductions": "Déductions",
3510
3446
  "due": "Échéance",
3511
3447
  "due_with_date": "Échéance : {{date}}",
@@ -3514,26 +3450,15 @@ const label$6 = {
3514
3450
  "estimated_taxes": "Impôts estimés",
3515
3451
  "estimates": "Estimations",
3516
3452
  "federal": "Fédéral",
3517
- "federal_deductions": "Déductions fédérales",
3518
3453
  "federal_state_tax_payments": "Paiements d’impôt fédéral et d’État pour l’année d’imposition sélectionnée",
3519
3454
  "federal_state_tax_payments_projected": "Paiements d’impôt fédéral et d’État projetés pour l’année d’imposition sélectionnée",
3520
- "federal_tax": "Impôt fédéral",
3521
- "federal_tax_estimate_owed": "Estimation de l’impôt fédéral (à payer)",
3522
3455
  "federal_tax_information": "Renseignements sur l’impôt fédéral",
3523
- "federal_tax_rate": "Taux d’imposition fédéral",
3524
- "federal_taxes": "Impôts fédéraux",
3525
- "federal_taxes_projected": "Impôts fédéraux projetés",
3526
3456
  "filing_status": "Statut de déclaration",
3527
3457
  "full_year_projection": "Projection annuelle",
3528
3458
  "head_household": "Chef de famille",
3529
3459
  "home_office_area_sq": "Superficie du bureau à domicile (pi²)",
3530
- "home_office_deduction": "Déduction pour bureau à domicile",
3531
3460
  "married_filing_jointly": "Marié(e), déclaration conjointe",
3532
3461
  "married_filing_separately": "Marié(e), déclaration séparée",
3533
- "medicare_surtax_estimate_owed": "Estimation de la surtaxe Medicare (à payer)",
3534
- "medicare_surtax_rate": "Taux de la surtaxe Medicare",
3535
- "medicare_tax_estimate_owed": "Estimation de la taxe Medicare (à payer)",
3536
- "medicare_tax_rate": "Taux de la taxe Medicare",
3537
3462
  "overtime_income": "Revenu d’heures supplémentaires",
3538
3463
  "owed_quarter": "À payer ce trimestre",
3539
3464
  "paid": "Payé",
@@ -3543,59 +3468,33 @@ const label$6 = {
3543
3468
  "q2": "T2",
3544
3469
  "q3": "T3",
3545
3470
  "q4": "T4",
3546
- "qualified_overtime_deduction": "Déduction admissible pour heures supplémentaires",
3547
- "qualified_tip_deduction": "Déduction admissible pour pourboires",
3548
3471
  "qualifying_widow_er": "Veuf(ve) admissible",
3549
3472
  "quarter": "Trimestre",
3550
3473
  "quarter_taxes": "Impôts du {{quarterLabel}}",
3551
3474
  "remaining_balance": "Solde restant",
3552
3475
  "rolled_over_from_previous_quarter": "Reporté du trimestre précédent",
3553
- "self_employment_deduction": "Déduction pour travail autonome",
3554
3476
  "single": "Célibataire",
3555
- "social_security_tax_estimate_owed": "Estimation de la taxe de sécurité sociale (à payer)",
3556
- "social_security_tax_rate": "Taux de la taxe de sécurité sociale",
3557
3477
  "state": "État",
3558
- "state_adjusted_gross_income": "Revenu brut ajusté de l’État",
3559
- "state_deductions": "Déductions d’État",
3560
- "state_income_tax_estimate_owed": "Estimation de l’impôt sur le revenu de l’État (à payer)",
3561
- "state_tax": "Impôt d’État",
3562
- "state_tax_rate": "Taux d’imposition de l’État",
3563
- "state_taxable_income": "Revenu imposable de l’État",
3478
+ "tax_details": "Détails fiscaux",
3479
+ "tax_details_amount": "Montant",
3480
+ "tax_details_label": "Libellé",
3564
3481
  "tax_estimate_view": "Vue des estimations fiscales",
3565
3482
  "tax_information": "Renseignements sur l'impôt d'État",
3566
- "tax_name_estimate_owed": "Estimation de {{taxName}} (à payer)",
3567
- "tax_name_rate": "Taux de {{taxName}}",
3568
- "tax_details": "",
3569
- "tax_details_amount": "",
3570
- "tax_details_label": "",
3571
3483
  "tax_payments": "Paiements d’impôt",
3572
3484
  "tax_payments_projected": "Paiements d’impôt projetés",
3573
3485
  "tax_profile": "Profil fiscal",
3574
3486
  "tax_profile_saved": "Profil fiscal enregistré",
3575
3487
  "tax_summary": "Sommaire fiscal",
3576
- "taxable_amount_tax_name": "Montant imposable pour {{taxName}}",
3577
- "taxable_business_income": "Revenu d’entreprise imposable",
3578
- "taxable_business_income_projected": "Revenu d’entreprise imposable projeté",
3579
- "taxable_income": "Revenu imposable",
3580
3488
  "taxable_income_estimate_to_date_for_year": "Estimation du revenu imposable à ce jour pour l’année {{year}}",
3581
3489
  "taxable_income_estimate_to_date_for_year_projected": "Projection du revenu imposable pour l’année {{year}}",
3582
3490
  "taxable_income_for_year": "Revenu imposable pour {{year}}",
3583
3491
  "taxable_income_for_year_projected": "Revenu imposable projeté pour {{year}}",
3584
- "taxable_medicare_income": "Revenu Medicare imposable",
3585
- "taxable_medicare_surtax_income": "Revenu imposable pour la surtaxe Medicare",
3586
- "taxable_social_security_income": "Revenu imposable de la Sécurité Sociale",
3587
- "taxes_by_state_name": "Impôts d’État ({{stateName}})",
3588
- "taxes_by_state_name_projected": "Impôts d’État projetés ({{stateName}})",
3589
- "taxes_due": "Impôts à payer",
3590
- "taxes_due_at": "",
3492
+ "taxes_due_at": "Taxes à payer le {{date}}",
3591
3493
  "taxes_owed": "Impôts dus",
3592
3494
  "taxes_owed_projected": "Impôts dus projetés",
3593
3495
  "taxes_paid": "Impôts payés",
3594
3496
  "tip_income": "Revenu de pourboires",
3595
- "total_deductions": "",
3596
- "total_federal_tax_estimate": "Estimation totale de l’impôt fédéral",
3597
3497
  "total_paid": "Total payé",
3598
- "total_state_tax_estimate": "Estimation totale de l’impôt d’État",
3599
3498
  "uncategorized_transactions_one": "{{count}} transaction non catégorisée",
3600
3499
  "uncategorized_transactions_other": "{{count}} transactions non catégorisées",
3601
3500
  "uncategorized_transactions_with_year_one": "{{count}} transaction non catégorisée ({{year}})",
@@ -3603,7 +3502,6 @@ const label$6 = {
3603
3502
  "use_custom_withholding": "Utiliser une retenue personnalisée?",
3604
3503
  "use_simplified_home_office": "Utiliser la déduction simplifiée pour bureau à domicile?",
3605
3504
  "use_standard_mileage_deduction": "Utiliser la déduction forfaitaire kilométrique?",
3606
- "w2_income": "Revenu W-2",
3607
3505
  "withholding_amount": "Montant de la retenue",
3608
3506
  "year_to_date": "Cumul annuel",
3609
3507
  "your_tax_deadlines": "Vos échéances fiscales"
@@ -14809,6 +14707,7 @@ let ReportControl = /* @__PURE__ */ function(ReportControl$1) {
14809
14707
  ReportControl$1["Date"] = "date";
14810
14708
  ReportControl$1["DateRange"] = "date_range";
14811
14709
  ReportControl$1["GroupBy"] = "group_by";
14710
+ ReportControl$1["Year"] = "year";
14812
14711
  ReportControl$1["Unknown"] = "unknown";
14813
14712
  return ReportControl$1;
14814
14713
  }({});
@@ -20612,6 +20511,29 @@ const CategorizationRulesMobileList = ({ data, isLoading, isError, paginationPro
20612
20511
  })
20613
20512
  });
20614
20513
  };
20514
+ function useHorizontalOverflow(elementRef, options = { dependencies: [] }) {
20515
+ const { dependencies: dependencies$1 = [] } = options;
20516
+ const [hasHorizontalOverflow, setHasHorizontalOverflow] = (0, react.useState)(false);
20517
+ const updateHorizontalOverflow = (0, react.useCallback)(() => {
20518
+ const element = elementRef.current;
20519
+ if (!element) return;
20520
+ setHasHorizontalOverflow(Math.ceil(element.scrollWidth) > Math.ceil(element.clientWidth));
20521
+ }, [elementRef, ...dependencies$1]);
20522
+ (0, __react_hook_resize_observer.default)(elementRef, updateHorizontalOverflow);
20523
+ (0, react.useEffect)(() => {
20524
+ var _elementRef$current;
20525
+ const element = (_elementRef$current = elementRef.current) === null || _elementRef$current === void 0 ? void 0 : _elementRef$current.firstElementChild;
20526
+ if (!element) return;
20527
+ const observer = new ResizeObserver(() => updateHorizontalOverflow());
20528
+ observer.observe(element);
20529
+ return () => observer.disconnect();
20530
+ }, [elementRef, updateHorizontalOverflow]);
20531
+ (0, react.useEffect)(() => {
20532
+ const id = requestAnimationFrame(() => updateHorizontalOverflow());
20533
+ return () => cancelAnimationFrame(id);
20534
+ }, [updateHorizontalOverflow]);
20535
+ return hasHorizontalOverflow;
20536
+ }
20615
20537
  var WIDTH_CHANGE_THRESHOLD_PX = .5;
20616
20538
  var getLeafHeaderCells = (header) => {
20617
20539
  const leafRow = header === null || header === void 0 ? void 0 : header.lastElementChild;
@@ -20657,9 +20579,43 @@ const useColumnPinningStyles = (headerGroups) => {
20657
20579
  pinningStyles: (0, react.useMemo)(() => computePinningStyles(headerGroups, headerWidths), [headerGroups, headerWidths])
20658
20580
  };
20659
20581
  };
20582
+ const DEFAULT_SKELETON_COLUMNS = 3;
20583
+ const DataTableHeaderSkeleton = ({ nonAria, numColumns = 3 }) => {
20584
+ const resolvedNumColumns = numColumns > 0 ? numColumns : 3;
20585
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
20586
+ nonAria,
20587
+ children: Array.from({ length: resolvedNumColumns }).map((_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Column, {
20588
+ nonAria,
20589
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonLoader, {
20590
+ width: index === 0 ? "60%" : "40%",
20591
+ height: "12px"
20592
+ })
20593
+ }, `loading-header-${index}`))
20594
+ });
20595
+ };
20596
+ const DataTableSkeleton = ({ numColumns, nonAria }) => {
20597
+ const resolvedNumColumns = numColumns > 0 ? numColumns : 3;
20598
+ const loadingColumns = (0, react.useMemo)(() => Array.from({ length: resolvedNumColumns }, (_, index) => ({ index })), [resolvedNumColumns]);
20599
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: Array.from({ length: 6 }).map((_, rowIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
20600
+ nonAria,
20601
+ children: loadingColumns.map((column) => {
20602
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cell$3, {
20603
+ className: "Layer__skeleton-loader__row",
20604
+ nonAria,
20605
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonLoader, {
20606
+ width: `${100 - (column.index === 0 && rowIndex >= 3 ? (rowIndex - 2) * 10 : 0)}%`,
20607
+ height: "20px"
20608
+ })
20609
+ }, `loading-${rowIndex}-${column.index}`);
20610
+ })
20611
+ }, `loading-${rowIndex}`)) });
20612
+ };
20660
20613
  const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, dependencies: dependencies$1, data, headerGroups, numColumns, withClickableRow }) => {
20661
- const nonAria = headerGroups.length > 1;
20614
+ const scrollContainerRef = (0, react.useRef)(null);
20615
+ const nonAria = headerGroups.length > 1 || numColumns === 0;
20662
20616
  const { EmptyState: EmptyState$8, ErrorState: ErrorState$9 } = slots;
20617
+ const hasHorizontalOverflow = useHorizontalOverflow(scrollContainerRef, { dependencies: [data, numColumns] });
20618
+ const showLoadingFallbackHeaders = isLoading && numColumns === 0;
20663
20619
  const { headerRef, pinningStyles } = useColumnPinningStyles(headerGroups);
20664
20620
  const isEmptyTable = (data === null || data === void 0 ? void 0 : data.length) === 0;
20665
20621
  const renderTableBody = (0, react.useMemo)(() => {
@@ -20673,15 +20629,9 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
20673
20629
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorState$9, {})
20674
20630
  })
20675
20631
  });
20676
- if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
20677
- className: "Layer__DataTable__EmptyState__Row",
20678
- nonAria,
20679
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Cell$3, {
20680
- className: "Layer__DataTable__EmptyState__Cell",
20681
- colSpan: numColumns,
20682
- nonAria,
20683
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Loader, {})
20684
- })
20632
+ if (isLoading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableSkeleton, {
20633
+ numColumns,
20634
+ nonAria
20685
20635
  });
20686
20636
  if (isEmptyTable) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
20687
20637
  className: "Layer__DataTable__EmptyState__Row",
@@ -20728,7 +20678,8 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
20728
20678
  pinningStyles
20729
20679
  ]);
20730
20680
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
20731
- className: "Layer__UI__Table-ScrollContainer",
20681
+ ref: scrollContainerRef,
20682
+ className: (0, classnames.default)("Layer__UI__Table-ScrollContainer", hasHorizontalOverflow && "Layer__UI__Table-ScrollContainer--has-horizontal-overflow"),
20732
20683
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Table$1, {
20733
20684
  "aria-label": ariaLabel,
20734
20685
  className: `Layer__UI__Table__${componentName}`,
@@ -20736,7 +20687,10 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
20736
20687
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableHeader, {
20737
20688
  ref: headerRef,
20738
20689
  nonAria,
20739
- children: headerGroups.map((headerGroup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
20690
+ children: showLoadingFallbackHeaders ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTableHeaderSkeleton, {
20691
+ nonAria,
20692
+ numColumns: 3
20693
+ }) : headerGroups.map((headerGroup) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Row, {
20740
20694
  nonAria,
20741
20695
  children: headerGroup.headers.map((header) => {
20742
20696
  var _header$column$column, _header$column$column2;
@@ -20757,7 +20711,7 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
20757
20711
  nonAria,
20758
20712
  children: renderTableBody
20759
20713
  })]
20760
- })
20714
+ }, `${componentName}-cols-${numColumns}`)
20761
20715
  });
20762
20716
  };
20763
20717
  function PaginatedTable({ data, isLoading, isError, columnConfig, componentName, ariaLabel, paginationProps, slots }) {
@@ -28650,13 +28604,6 @@ const LEDGER_ACCOUNT_TYPES_CONFIG = [
28650
28604
  _objectSpread2({ value: "REVENUE" }, translationKey("common:label.revenue", "Revenue")),
28651
28605
  _objectSpread2({ value: "EXPENSE" }, translationKey("common:label.expenses", "Expenses"))
28652
28606
  ];
28653
- const DEFAULT_ACCOUNT_TYPE_DIRECTION = {
28654
- ASSET: Direction.DEBIT,
28655
- LIABILITY: Direction.CREDIT,
28656
- EQUITY: Direction.CREDIT,
28657
- REVENUE: Direction.CREDIT,
28658
- EXPENSE: Direction.DEBIT
28659
- };
28660
28607
  const NORMALITY_CONFIG = [_objectSpread2({ value: Direction.DEBIT }, translationKey("common:label.debit", "Debit")), _objectSpread2({ value: Direction.CREDIT }, translationKey("common:label.credit", "Credit"))];
28661
28608
  const ASSET_LEDGER_ACCOUNT_SUBTYPES_CONFIG = [
28662
28609
  _objectSpread2({ value: "BANK_ACCOUNTS" }, translationKey("chartOfAccounts:label.bank_accounts", "Bank Accounts")),
@@ -29216,134 +29163,6 @@ const ChartOfAccountsContext = (0, react.createContext)({
29216
29163
  changeFormData: () => {},
29217
29164
  submitForm: () => {}
29218
29165
  });
29219
- var _excluded$22 = ["size"];
29220
- var Plus$8 = (_ref) => {
29221
- let { size = 14 } = _ref;
29222
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", _objectSpread2(_objectSpread2({
29223
- xmlns: "http://www.w3.org/2000/svg",
29224
- viewBox: "0 0 14 14",
29225
- fill: "none"
29226
- }, _objectWithoutProperties(_ref, _excluded$22)), {}, {
29227
- width: size,
29228
- height: size,
29229
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29230
- d: "M7 2.91602V11.0827",
29231
- stroke: "currentColor",
29232
- strokeLinecap: "round",
29233
- strokeLinejoin: "round"
29234
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29235
- d: "M2.91669 7H11.0834",
29236
- stroke: "currentColor",
29237
- strokeLinecap: "round",
29238
- strokeLinejoin: "round"
29239
- })]
29240
- }));
29241
- };
29242
- var Plus_default = Plus$8;
29243
- var Collapse = (_ref) => {
29244
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", _objectSpread2(_objectSpread2({
29245
- xmlns: "http://www.w3.org/2000/svg",
29246
- width: "14",
29247
- height: "22",
29248
- viewBox: "0 0 14 22",
29249
- fill: "none"
29250
- }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29251
- d: "M3.5 5.25L7 8.75L10.5 5.25",
29252
- stroke: "currentColor",
29253
- strokeLinecap: "round",
29254
- strokeLinejoin: "round"
29255
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29256
- d: "M3.5 16.75L7 13.25L10.5 16.75",
29257
- stroke: "currentColor",
29258
- strokeLinecap: "round",
29259
- strokeLinejoin: "round"
29260
- })] }));
29261
- };
29262
- var Collapse_default = Collapse;
29263
- var Expand = (_ref) => {
29264
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", _objectSpread2(_objectSpread2({
29265
- xmlns: "http://www.w3.org/2000/svg",
29266
- width: "14",
29267
- height: "22",
29268
- viewBox: "0 0 14 22",
29269
- fill: "none"
29270
- }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29271
- d: "M10.5 8.75L7 5.25L3.5 8.75",
29272
- stroke: "currentColor",
29273
- strokeLinecap: "round",
29274
- strokeLinejoin: "round"
29275
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29276
- d: "M3.5 13.25L7 16.75L10.5 13.25",
29277
- stroke: "currentColor",
29278
- strokeLinecap: "round",
29279
- strokeLinejoin: "round"
29280
- })] }));
29281
- };
29282
- var Expand_default = Expand;
29283
- const ExpandCollapseButton = ({ onClick, expanded, className, iconOnly, variant }) => {
29284
- const { t } = (0, react_i18next.useTranslation)();
29285
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
29286
- onClick: () => onClick(!expanded),
29287
- variant: variant ? variant : ButtonVariant.secondary,
29288
- className: (0, classnames.default)(iconOnly ? "Layer__expand-collapse-all-rows-btn--sm" : "Layer__expand-collapse-all-rows-btn", className),
29289
- rightIcon: !iconOnly ? null : expanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapse_default, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Expand_default, {}),
29290
- iconAsPrimary: iconOnly,
29291
- iconOnly,
29292
- children: iconOnly ? null : !expanded ? t("reports:action.expand_rows", "Expand all rows") : t("reports:action.collapse_rows", "Collapse all rows")
29293
- }) });
29294
- };
29295
- var getLedgerAccountBalancesCSV = get(({ businessId }) => `/v1/businesses/${businessId}/ledger/balances/exports/csv`);
29296
- function buildKey$51({ access_token: accessToken, apiUrl, businessId, startCutoff, endCutoff }) {
29297
- if (accessToken && apiUrl) return {
29298
- accessToken,
29299
- apiUrl,
29300
- businessId,
29301
- startCutoff,
29302
- endCutoff,
29303
- tags: [
29304
- "#account-balances",
29305
- "#exports",
29306
- "#csv"
29307
- ]
29308
- };
29309
- }
29310
- function useAccountBalancesDownload({ startCutoff, endCutoff, onSuccess }) {
29311
- const withLocale = useLocalizedKey();
29312
- const { data: auth } = useAuth();
29313
- const { businessId } = useLayerContext();
29314
- return (0, swr_mutation.default)(() => withLocale(buildKey$51(_objectSpread2(_objectSpread2({}, auth), {}, {
29315
- businessId,
29316
- startCutoff,
29317
- endCutoff
29318
- }))), ({ accessToken, apiUrl, businessId: businessId$1, startCutoff: startCutoff$1, endCutoff: endCutoff$1 }) => getLedgerAccountBalancesCSV(apiUrl, accessToken, { params: {
29319
- businessId: businessId$1,
29320
- startCutoff: startCutoff$1 === null || startCutoff$1 === void 0 ? void 0 : startCutoff$1.toISOString(),
29321
- endCutoff: endCutoff$1 === null || endCutoff$1 === void 0 ? void 0 : endCutoff$1.toISOString()
29322
- } })().then(({ data }) => {
29323
- if (onSuccess) return onSuccess(data);
29324
- }), {
29325
- revalidate: false,
29326
- throwOnError: false
29327
- });
29328
- }
29329
- function AccountBalancesDownloadButton({ startCutoff, endCutoff, iconOnly }) {
29330
- const { t } = (0, react_i18next.useTranslation)();
29331
- const { invisibleDownloadRef, triggerInvisibleDownload } = useInvisibleDownload();
29332
- const { trigger, isMutating, error: error$38 } = useAccountBalancesDownload({
29333
- startCutoff,
29334
- endCutoff,
29335
- onSuccess: ({ presignedUrl }) => triggerInvisibleDownload({ url: presignedUrl })
29336
- });
29337
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DownloadButton, {
29338
- iconOnly,
29339
- onClick: () => {
29340
- trigger();
29341
- },
29342
- isDownloading: isMutating,
29343
- requestFailed: Boolean(error$38),
29344
- text: t("common:action.download_csv", "Download CSV")
29345
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InvisibleDownload_default, { ref: invisibleDownloadRef })] });
29346
- }
29347
29166
  const useParentOptions = (data) => (0, react.useMemo)(() => flattenAccounts$1((data === null || data === void 0 ? void 0 : data.accounts) || []).sort((a, b) => (a === null || a === void 0 ? void 0 : a.name) && (b === null || b === void 0 ? void 0 : b.name) ? a.name.localeCompare(b.name) : 0).map((x) => {
29348
29167
  return {
29349
29168
  label: x.name,
@@ -29534,23 +29353,20 @@ const ChartOfAccountsForm = ({ stringOverrides }) => {
29534
29353
  ]
29535
29354
  });
29536
29355
  };
29537
- const ChartOfAccountsSidebar = ({ parentRef: _parentRef, stringOverrides }) => {
29538
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsForm, { stringOverrides });
29539
- };
29540
29356
  let LedgerAccountNodeType = /* @__PURE__ */ function(LedgerAccountNodeType$1) {
29541
29357
  LedgerAccountNodeType$1["Leaf"] = "Leaf";
29542
29358
  LedgerAccountNodeType$1["Root"] = "Root";
29543
29359
  LedgerAccountNodeType$1["Parent"] = "Parent";
29544
29360
  return LedgerAccountNodeType$1;
29545
29361
  }({});
29546
- var _excluded$21 = ["size"];
29362
+ var _excluded$22 = ["size"];
29547
29363
  var Edit2 = (_ref) => {
29548
29364
  let { size = 18 } = _ref;
29549
29365
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", _objectSpread2(_objectSpread2({
29550
29366
  xmlns: "http://www.w3.org/2000/svg",
29551
29367
  viewBox: "0 0 18 18",
29552
29368
  fill: "none"
29553
- }, _objectWithoutProperties(_ref, _excluded$21)), {}, {
29369
+ }, _objectWithoutProperties(_ref, _excluded$22)), {}, {
29554
29370
  width: size,
29555
29371
  height: size,
29556
29372
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
@@ -29585,6 +29401,20 @@ const filterAccounts = (accounts, query, formatCurrencyFromCents$1) => {
29585
29401
  return [];
29586
29402
  });
29587
29403
  };
29404
+ const getRowId$2 = (row) => row.accountId;
29405
+ const getInitialExpandedState = (accounts) => {
29406
+ const expandedState = {};
29407
+ if (!accounts) return expandedState;
29408
+ const collectExpanded = (nestedAccounts, depth) => {
29409
+ for (const account of nestedAccounts) {
29410
+ if (!(account.subAccounts.length > 0)) continue;
29411
+ if (depth === 0 || account.isMatching) expandedState[getRowId$2(account)] = true;
29412
+ collectExpanded(account.subAccounts, depth + 1);
29413
+ }
29414
+ };
29415
+ collectExpanded(accounts, 0);
29416
+ return expandedState;
29417
+ };
29588
29418
  var skippedChars = ["$", ","];
29589
29419
  const getMatchedTextIndices = ({ text, query, isMatching }) => {
29590
29420
  if (!query || !isMatching) return null;
@@ -29610,6 +29440,122 @@ const getMatchedTextIndices = ({ text, query, isMatching }) => {
29610
29440
  endIdx: matchEndIdx
29611
29441
  };
29612
29442
  };
29443
+ var defaultContextValue = {
29444
+ expanded: {},
29445
+ setExpanded: () => {}
29446
+ };
29447
+ const ExpandableDataTableContext = (0, react.createContext)(defaultContextValue);
29448
+ function ExpandableDataTableProvider({ children }) {
29449
+ const [expanded, setExpanded] = (0, react.useState)({});
29450
+ const value = (0, react.useMemo)(() => ({
29451
+ expanded,
29452
+ setExpanded
29453
+ }), [expanded]);
29454
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandableDataTableContext.Provider, {
29455
+ value,
29456
+ children
29457
+ });
29458
+ }
29459
+ var baseClassName = "Layer__ExpandButton";
29460
+ const ExpandButton = ({ isExpanded }) => {
29461
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownFill_default, {
29462
+ className: (0, classnames.default)(baseClassName, `${baseClassName}--${isExpanded ? "expanded" : "collapsed"}`),
29463
+ size: 16,
29464
+ "aria-label": isExpanded ? "Collapse row" : "Expand row"
29465
+ });
29466
+ };
29467
+ var INDENT_SIZE_XS = 10;
29468
+ var INDENT_SIZE_SM = 20;
29469
+ var INDENT_SIZE_MD = 40;
29470
+ var CHEVRON_OFFSET_PX = 4;
29471
+ var getRowIndentStyle = ({ depth, canExpand, indentSizePx }) => ({
29472
+ paddingInlineStart: depth * indentSizePx + (canExpand ? 0 : CHEVRON_OFFSET_PX),
29473
+ overflow: "hidden"
29474
+ });
29475
+ var EMPTY_ARRAY$2 = [];
29476
+ function ExpandableDataTable({ data, isLoading, isError, columnConfig, componentName, ariaLabel, slots, getSubRows: getSubRows$4, getRowId: getRowId$3, indentSize = "sm" }) {
29477
+ const { expanded, setExpanded } = (0, react.useContext)(ExpandableDataTableContext);
29478
+ const wrappedColumnConfig = (0, react.useMemo)(() => {
29479
+ const indentSizePx = indentSize === "xs" ? INDENT_SIZE_XS : indentSize === "md" ? INDENT_SIZE_MD : INDENT_SIZE_SM;
29480
+ const [first, ...rest] = columnConfig;
29481
+ if (!first || !isLeafColumn(first)) return columnConfig;
29482
+ const cellRenderer = first.cell;
29483
+ return [_objectSpread2(_objectSpread2({}, first), {}, { cell: (row) => {
29484
+ const canExpand = row.getCanExpand();
29485
+ const rowIndentStyle = getRowIndentStyle({
29486
+ canExpand,
29487
+ depth: row.depth,
29488
+ indentSizePx
29489
+ });
29490
+ if (!canExpand) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
29491
+ style: rowIndentStyle,
29492
+ children: cellRenderer(row)
29493
+ });
29494
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
29495
+ style: rowIndentStyle,
29496
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
29497
+ align: "center",
29498
+ gap: "xs",
29499
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandButton, { isExpanded: row.getIsExpanded() }), cellRenderer(row)]
29500
+ })
29501
+ });
29502
+ } }), ...rest];
29503
+ }, [columnConfig, indentSize]);
29504
+ const columnDefs = getColumnDefs(wrappedColumnConfig);
29505
+ const columnPinning = (0, react.useMemo)(() => getColumnPinning(wrappedColumnConfig), [wrappedColumnConfig]);
29506
+ const table$1 = (0, __tanstack_react_table.useReactTable)({
29507
+ data: data !== null && data !== void 0 ? data : EMPTY_ARRAY$2,
29508
+ columns: columnDefs,
29509
+ getSubRows: getSubRows$4,
29510
+ getCoreRowModel: (0, __tanstack_react_table.getCoreRowModel)(),
29511
+ getExpandedRowModel: (0, __tanstack_react_table.getExpandedRowModel)(),
29512
+ state: {
29513
+ expanded,
29514
+ columnPinning
29515
+ },
29516
+ onExpandedChange: setExpanded,
29517
+ autoResetPageIndex: false,
29518
+ getRowId: getRowId$3
29519
+ });
29520
+ const { rows } = table$1.getExpandedRowModel();
29521
+ const dependencies$1 = (0, react.useMemo)(() => [expanded], [expanded]);
29522
+ const headerGroups = table$1.getHeaderGroups();
29523
+ const numColumns = table$1.getVisibleLeafColumns().length;
29524
+ const isRowClickable = (0, react.useCallback)((row) => {
29525
+ return row.getCanExpand();
29526
+ }, []);
29527
+ const onRowClick = (0, react.useCallback)((row) => {
29528
+ row.toggleExpanded();
29529
+ }, []);
29530
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTable, {
29531
+ ariaLabel,
29532
+ numColumns,
29533
+ data: rows,
29534
+ isLoading,
29535
+ isError,
29536
+ componentName,
29537
+ slots,
29538
+ dependencies: dependencies$1,
29539
+ headerGroups,
29540
+ withClickableRow: (0, react.useMemo)(() => ({
29541
+ onRowClick,
29542
+ isRowClickable
29543
+ }), [onRowClick, isRowClickable])
29544
+ });
29545
+ }
29546
+ var ChartOfAccountsColumn = /* @__PURE__ */ function(ChartOfAccountsColumn$1) {
29547
+ ChartOfAccountsColumn$1["AccountNumber"] = "AccountNumber";
29548
+ ChartOfAccountsColumn$1["Name"] = "Name";
29549
+ ChartOfAccountsColumn$1["Type"] = "Type";
29550
+ ChartOfAccountsColumn$1["Subtype"] = "Subtype";
29551
+ ChartOfAccountsColumn$1["Balance"] = "Balance";
29552
+ ChartOfAccountsColumn$1["Actions"] = "Actions";
29553
+ return ChartOfAccountsColumn$1;
29554
+ }(ChartOfAccountsColumn || {});
29555
+ var COMPONENT_NAME$8 = "chart-of-accounts";
29556
+ var getSubRows$3 = (row) => {
29557
+ return row.subAccounts.length > 0 ? asMutable(row.subAccounts) : void 0;
29558
+ };
29613
29559
  var highlightMatch = ({ text, query, isMatching }) => {
29614
29560
  const matchedTextIndices = getMatchedTextIndices({
29615
29561
  text,
@@ -29633,41 +29579,36 @@ var highlightMatch = ({ text, query, isMatching }) => {
29633
29579
  ]
29634
29580
  });
29635
29581
  };
29636
- const ChartOfAccountsTable = ({ view, stringOverrides, data, searchQuery, expandAll, templateAccountsEditable = true }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsTableContent, {
29637
- view,
29638
- data,
29639
- searchQuery,
29640
- stringOverrides,
29641
- expandAll,
29642
- templateAccountsEditable
29643
- }) });
29644
- const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expandAll, templateAccountsEditable }) => {
29582
+ var ChartOfAccountsEmptyState = () => {
29583
+ const { t } = (0, react_i18next.useTranslation)();
29584
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataState, {
29585
+ status: DataStateStatus.info,
29586
+ title: t("chartOfAccounts:empty.accounts", "No accounts found"),
29587
+ description: t("chartOfAccounts:empty.accounts_match_filters", "No accounts match the current filters. Click \"Add Account\" to create a new one."),
29588
+ spacing: true
29589
+ });
29590
+ };
29591
+ var ChartOfAccountsErrorState = () => {
29592
+ const { t } = (0, react_i18next.useTranslation)();
29593
+ const { refetch, isValidating, isLoading } = (0, react.useContext)(ChartOfAccountsContext);
29594
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataState, {
29595
+ status: DataStateStatus.failed,
29596
+ title: t("common:error.something_went_wrong", "Something went wrong"),
29597
+ description: t("common:error.couldnt_load_data", "We couldn’t load your data."),
29598
+ onRefresh: () => void refetch(),
29599
+ isLoading: isValidating || isLoading,
29600
+ spacing: true
29601
+ });
29602
+ };
29603
+ const ChartOfAccountsTable = ({ stringOverrides, searchQuery, templateAccountsEditable = true }) => {
29645
29604
  const { t } = (0, react_i18next.useTranslation)();
29646
29605
  const { formatCurrencyFromCents: formatCurrencyFromCents$1 } = useIntlFormatter();
29647
29606
  const { setSelectedAccount } = (0, react.useContext)(LedgerAccountsContext);
29648
- const { editAccount, deleteAccount, isError } = (0, react.useContext)(ChartOfAccountsContext);
29649
- const [toggledKeys, setToggledKeys] = (0, react.useState)({});
29607
+ const { setExpanded } = (0, react.useContext)(ExpandableDataTableContext);
29608
+ const { data, isLoading, isError, editAccount, deleteAccount } = (0, react.useContext)(ChartOfAccountsContext);
29650
29609
  const [accountToDelete, setAccountToDelete] = (0, react.useState)(null);
29651
29610
  const { accountingConfiguration } = useLayerContext();
29652
29611
  const enableAccountNumbers = !!(accountingConfiguration === null || accountingConfiguration === void 0 ? void 0 : accountingConfiguration.enableAccountNumbers);
29653
- const allRowKeys = (0, react.useMemo)(() => {
29654
- const keys$1 = [];
29655
- const collect = (accounts) => {
29656
- for (const account of accounts) {
29657
- const key = `coa-row-${account.accountId}`;
29658
- if (account.subAccounts.length > 0) {
29659
- keys$1.push(key);
29660
- collect(account.subAccounts);
29661
- }
29662
- }
29663
- };
29664
- collect(data.accounts);
29665
- return keys$1;
29666
- }, [data.accounts]);
29667
- (0, react.useEffect)(() => {
29668
- if (expandAll === void 0) return;
29669
- setToggledKeys(Object.fromEntries(allRowKeys.map((key) => [key, expandAll === "expanded"])));
29670
- }, [allRowKeys, expandAll]);
29671
29612
  const onConfirmDelete = function() {
29672
29613
  var _ref = _asyncToGenerator(function* () {
29673
29614
  if (!accountToDelete) return;
@@ -29677,109 +29618,106 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
29677
29618
  return _ref.apply(this, arguments);
29678
29619
  };
29679
29620
  }();
29680
- const getDeleteButtonTooltip = (account) => {
29621
+ const getDeleteButtonTooltip = (0, react.useCallback)((account) => {
29681
29622
  if (account.isDeletable) return;
29682
29623
  if (account.subAccounts.length > 0) return t("chartOfAccounts:validation.delete_account_has_children", "This account cannot be deleted because it has child accounts");
29683
29624
  if (account.balance !== 0) return t("chartOfAccounts:validation.delete_account_has_ledger_entries", "This account cannot be deleted because it has ledger entries");
29684
29625
  return t("chartOfAccounts:validation.delete_account_is_required", "This account cannot be deleted because it is a required account");
29685
- };
29686
- (0, react.useEffect)(() => {
29687
- setToggledKeys({});
29688
- }, [searchQuery]);
29626
+ }, [t]);
29689
29627
  const filteredAccounts = (0, react.useMemo)(() => {
29628
+ if (!data) return void 0;
29690
29629
  if (!searchQuery) return data.accounts;
29691
29630
  return filterAccounts(asMutable(data.accounts), searchQuery.toLowerCase(), formatCurrencyFromCents$1);
29692
29631
  }, [
29693
- data.accounts,
29632
+ data,
29694
29633
  formatCurrencyFromCents$1,
29695
29634
  searchQuery
29696
29635
  ]);
29697
- const renderChartOfAccountsDesktopRow = ({ account, index, depth, searchQuery: searchQuery$1 }) => {
29698
- var _account$accountType, _account$accountSubty;
29699
- const rowKey = `coa-row-${account.accountId}`;
29700
- const hasSubAccounts = !!account.subAccounts && account.subAccounts.length > 0;
29701
- const nodeType = depth === 0 ? LedgerAccountNodeType.Root : hasSubAccounts ? LedgerAccountNodeType.Parent : LedgerAccountNodeType.Leaf;
29702
- const manuallyToggled = toggledKeys[rowKey];
29703
- const isExpanded = !hasSubAccounts || manuallyToggled === true || manuallyToggled !== false && (account.isMatching || depth === 0);
29704
- const isNonEditable = !templateAccountsEditable && !!account.stableName;
29705
- const isDeleteDisabled = !account.isDeletable;
29706
- const onClickRow = (e) => {
29707
- e.stopPropagation();
29708
- if (!hasSubAccounts) return;
29709
- setToggledKeys((prev) => _objectSpread2(_objectSpread2({}, prev), {}, { [rowKey]: !isExpanded }));
29710
- };
29711
- const onClickAccountName = (e) => {
29712
- e.stopPropagation();
29713
- setSelectedAccount(_objectSpread2(_objectSpread2({}, account), {}, { nodeType }));
29714
- };
29715
- const onClickEdit = (e) => {
29716
- e.preventDefault();
29717
- e.stopPropagation();
29718
- editAccount(account.accountId);
29719
- };
29720
- const onClickView = (e) => {
29721
- e.preventDefault();
29722
- e.stopPropagation();
29723
- setSelectedAccount(_objectSpread2(_objectSpread2({}, account), {}, { nodeType }));
29724
- };
29725
- const onClickDelete = (e) => {
29726
- e.preventDefault();
29727
- e.stopPropagation();
29728
- setAccountToDelete(account);
29636
+ (0, react.useLayoutEffect)(() => {
29637
+ setExpanded(getInitialExpandedState(filteredAccounts));
29638
+ }, [filteredAccounts, setExpanded]);
29639
+ const getNodeType = (row) => {
29640
+ if (row.depth === 0) return LedgerAccountNodeType.Root;
29641
+ return row.getCanExpand() ? LedgerAccountNodeType.Parent : LedgerAccountNodeType.Leaf;
29642
+ };
29643
+ const onClickView = (0, react.useCallback)((row, e) => {
29644
+ e.preventDefault();
29645
+ e.stopPropagation();
29646
+ setSelectedAccount(_objectSpread2(_objectSpread2({}, row.original), {}, { nodeType: getNodeType(row) }));
29647
+ }, [setSelectedAccount]);
29648
+ const onClickEdit = (0, react.useCallback)((account, e) => {
29649
+ e.preventDefault();
29650
+ e.stopPropagation();
29651
+ editAccount(account.accountId);
29652
+ }, [editAccount]);
29653
+ const onClickDelete = (account, e) => {
29654
+ e.preventDefault();
29655
+ e.stopPropagation();
29656
+ setAccountToDelete(account);
29657
+ };
29658
+ const renderHighlightedValue = (0, react.useCallback)((row, text) => {
29659
+ return highlightMatch({
29660
+ text,
29661
+ query: searchQuery,
29662
+ isMatching: row.original.isMatching
29663
+ });
29664
+ }, [searchQuery]);
29665
+ const renderHighlightedNonRootValue = (0, react.useCallback)((row, text) => {
29666
+ if (row.depth === 0) return null;
29667
+ return renderHighlightedValue(row, text);
29668
+ }, [renderHighlightedValue]);
29669
+ const slots = (0, react.useMemo)(() => ({
29670
+ EmptyState: ChartOfAccountsEmptyState,
29671
+ ErrorState: ChartOfAccountsErrorState
29672
+ }), []);
29673
+ const columnConfig = (0, react.useMemo)(() => {
29674
+ const accountNumberColumn = {
29675
+ id: ChartOfAccountsColumn.AccountNumber,
29676
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.numberColumnHeader) || t("generalLedger:label.account_number", "Account Number"),
29677
+ cell: (row) => renderHighlightedValue(row, row.original.accountNumber || "")
29729
29678
  };
29730
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TableRow, {
29731
- rowKey: rowKey + "-" + index,
29732
- expandable: hasSubAccounts,
29733
- isExpanded,
29734
- onClick: onClickRow,
29735
- depth,
29736
- variant: depth === 0 ? "expandable" : "default",
29737
- children: [
29738
- enableAccountNumbers && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29739
- withExpandIcon: hasSubAccounts,
29740
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HStack, _objectSpread2(_objectSpread2({}, !hasSubAccounts && { pis: "lg" }), {}, {
29741
- overflow: "hidden",
29742
- children: enableAccountNumbers && highlightMatch({
29743
- text: account.accountNumber || "",
29744
- query: searchQuery$1,
29745
- isMatching: account.isMatching
29746
- })
29747
- }))
29748
- }),
29749
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29750
- withExpandIcon: hasSubAccounts && !enableAccountNumbers,
29751
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HStack, _objectSpread2(_objectSpread2({}, !hasSubAccounts && !enableAccountNumbers ? { pis: "lg" } : {}), {}, {
29752
- overflow: "hidden",
29753
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
29754
- variant: "text",
29755
- ellipsis: true,
29756
- onClick: onClickAccountName,
29757
- children: highlightMatch({
29758
- text: account.name,
29759
- query: searchQuery$1,
29760
- isMatching: account.isMatching
29761
- })
29762
- })
29763
- }))
29679
+ const columns = [
29680
+ {
29681
+ id: ChartOfAccountsColumn.Name,
29682
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.nameColumnHeader) || t("generalLedger:label.account_name_title_case", "Account Name"),
29683
+ cell: (row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
29684
+ variant: "text",
29685
+ ellipsis: true,
29686
+ onClick: (e) => onClickView(row, e),
29687
+ children: renderHighlightedValue(row, row.original.name)
29764
29688
  }),
29765
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, { children: depth != 0 && highlightMatch({
29766
- text: ((_account$accountType = account.accountType) === null || _account$accountType === void 0 ? void 0 : _account$accountType.displayName) || "",
29767
- query: searchQuery$1,
29768
- isMatching: account.isMatching
29769
- }) }),
29770
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, { children: depth != 0 && highlightMatch({
29771
- text: ((_account$accountSubty = account.accountSubtype) === null || _account$accountSubty === void 0 ? void 0 : _account$accountSubty.displayName) || "",
29772
- query: searchQuery$1,
29773
- isMatching: account.isMatching
29774
- }) }),
29775
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, { children: highlightMatch({
29776
- text: formatCurrencyFromCents$1(account.balance),
29777
- query: searchQuery$1,
29778
- isMatching: account.isMatching
29779
- }) }),
29780
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29781
- align: TableCellAlign.RIGHT,
29782
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
29689
+ isRowHeader: true
29690
+ },
29691
+ {
29692
+ id: ChartOfAccountsColumn.Type,
29693
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.typeColumnHeader) || t("common:label.type", "Type"),
29694
+ cell: (row) => {
29695
+ var _row$original$account;
29696
+ return renderHighlightedNonRootValue(row, ((_row$original$account = row.original.accountType) === null || _row$original$account === void 0 ? void 0 : _row$original$account.displayName) || "");
29697
+ }
29698
+ },
29699
+ {
29700
+ id: ChartOfAccountsColumn.Subtype,
29701
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.subtypeColumnHeader) || t("chartOfAccounts:label.sub_type", "Sub-Type"),
29702
+ cell: (row) => {
29703
+ var _row$original$account2;
29704
+ return renderHighlightedNonRootValue(row, ((_row$original$account2 = row.original.accountSubtype) === null || _row$original$account2 === void 0 ? void 0 : _row$original$account2.displayName) || "");
29705
+ }
29706
+ },
29707
+ {
29708
+ id: ChartOfAccountsColumn.Balance,
29709
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.balanceColumnHeader) || t("common:label.balance", "Balance"),
29710
+ cell: (row) => renderHighlightedValue(row, formatCurrencyFromCents$1(row.original.balance))
29711
+ },
29712
+ {
29713
+ id: ChartOfAccountsColumn.Actions,
29714
+ header: null,
29715
+ alignment: Alignment.Right,
29716
+ cell: (row) => {
29717
+ const account = row.original;
29718
+ const isNonEditable = !templateAccountsEditable && !!account.stableName;
29719
+ const isDeleteDisabled = !account.isDeletable;
29720
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
29783
29721
  className: "Layer__coa__actions",
29784
29722
  gap: "xs",
29785
29723
  children: [
@@ -29787,7 +29725,7 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
29787
29725
  variant: ButtonVariant.secondary,
29788
29726
  rightIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.List, { size: 14 }),
29789
29727
  iconOnly: true,
29790
- onClick: onClickView,
29728
+ onClick: (e) => onClickView(row, e),
29791
29729
  children: t("common:action.view_label", "View")
29792
29730
  }),
29793
29731
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
@@ -29795,7 +29733,7 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
29795
29733
  rightIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Edit2_default, { size: 14 }),
29796
29734
  iconOnly: true,
29797
29735
  disabled: isNonEditable,
29798
- onClick: onClickEdit,
29736
+ onClick: (e) => onClickEdit(account, e),
29799
29737
  tooltip: isNonEditable ? t("chartOfAccounts:validation.account_not_modifiable", "This account cannot be modified") : void 0,
29800
29738
  children: t("common:action.edit_label", "Edit")
29801
29739
  }),
@@ -29803,77 +29741,40 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
29803
29741
  variant: ButtonVariant.secondary,
29804
29742
  rightIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Trash2, { size: 14 }),
29805
29743
  iconOnly: true,
29806
- onClick: onClickDelete,
29744
+ onClick: (e) => onClickDelete(account, e),
29807
29745
  disabled: isDeleteDisabled,
29808
29746
  tooltip: getDeleteButtonTooltip(account),
29809
29747
  children: t("common:action.delete_label", "Delete")
29810
29748
  })
29811
29749
  ]
29812
- })
29813
- })
29814
- ]
29815
- }), hasSubAccounts && isExpanded && account.subAccounts.map((subItem, subIdx) => {
29816
- return renderChartOfAccountsDesktopRow({
29817
- account: subItem,
29818
- index: subIdx,
29819
- depth: depth + 1,
29820
- searchQuery: searchQuery$1
29821
- });
29822
- })] }, rowKey + "-" + index);
29823
- };
29824
- if (filteredAccounts.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
29825
- className: "Layer__table-state-container",
29826
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataState, {
29827
- status: DataStateStatus.info,
29828
- title: t("chartOfAccounts:empty.accounts", "No accounts found"),
29829
- description: t("chartOfAccounts:empty.accounts_match_filters", "No accounts match the current filters. Click \"Add Account\" to create a new one.")
29830
- })
29831
- });
29832
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Table, {
29833
- componentName: "chart-of-accounts",
29834
- children: [
29835
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("colgroup", { children: [
29836
- enableAccountNumbers && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("col", { className: "Layer__chart-of-accounts--accountnumber" }),
29837
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("col", { className: "Layer__chart-of-accounts--name" }),
29838
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("col", { className: "Layer__chart-of-accounts--type" }),
29839
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("col", { className: "Layer__chart-of-accounts--subtype" }),
29840
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("col", { className: "Layer__chart-of-accounts--balance" }),
29841
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("col", { className: "Layer__chart-of-accounts--actions" })
29842
- ] }),
29843
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableHead, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(TableRow, {
29844
- isHeadRow: true,
29845
- rowKey: "charts-of-accounts-head-row",
29846
- children: [
29847
- enableAccountNumbers && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29848
- isHeaderCell: true,
29849
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.numberColumnHeader) || t("generalLedger:label.account_number", "Account Number")
29850
- }),
29851
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29852
- isHeaderCell: true,
29853
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.nameColumnHeader) || t("generalLedger:label.account_name_title_case", "Account Name")
29854
- }),
29855
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29856
- isHeaderCell: true,
29857
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.typeColumnHeader) || t("common:label.type", "Type")
29858
- }),
29859
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29860
- isHeaderCell: true,
29861
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.subtypeColumnHeader) || t("chartOfAccounts:label.sub_type", "Sub-Type")
29862
- }),
29863
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, {
29864
- isHeaderCell: true,
29865
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.balanceColumnHeader) || t("common:label.balance", "Balance")
29866
- }),
29867
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableCell, { isHeaderCell: true })
29868
- ]
29869
- }) }),
29870
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TableBody, { children: !isError && filteredAccounts.map((account, index) => renderChartOfAccountsDesktopRow({
29871
- account,
29872
- index,
29873
- depth: 0,
29874
- searchQuery
29875
- })) })
29876
- ]
29750
+ });
29751
+ }
29752
+ }
29753
+ ];
29754
+ if (enableAccountNumbers) columns.unshift(accountNumberColumn);
29755
+ return columns;
29756
+ }, [
29757
+ enableAccountNumbers,
29758
+ formatCurrencyFromCents$1,
29759
+ getDeleteButtonTooltip,
29760
+ onClickEdit,
29761
+ onClickView,
29762
+ renderHighlightedNonRootValue,
29763
+ renderHighlightedValue,
29764
+ stringOverrides,
29765
+ t,
29766
+ templateAccountsEditable
29767
+ ]);
29768
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandableDataTable, {
29769
+ componentName: COMPONENT_NAME$8,
29770
+ ariaLabel: t("chartOfAccounts:label.chart_of_accounts", "Chart of Accounts"),
29771
+ columnConfig,
29772
+ data: filteredAccounts ? asMutable(filteredAccounts) : void 0,
29773
+ isLoading,
29774
+ isError,
29775
+ slots,
29776
+ getSubRows: getSubRows$3,
29777
+ getRowId: getRowId$2
29877
29778
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BaseConfirmationModal, {
29878
29779
  isOpen: accountToDelete !== null,
29879
29780
  onOpenChange: (isOpen) => {
@@ -29886,88 +29787,201 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
29886
29787
  cancelLabel: t("common:action.cancel_label", "Cancel")
29887
29788
  })] });
29888
29789
  };
29889
- var COMPONENT_NAME$8 = "chart-of-accounts";
29890
- const ChartOfAccountsTableWithPanel = ({ view, containerRef, asWidget = false, withDateControl = false, withExpandAllButton = false, showAddAccountButton = true, stringOverrides, templateAccountsEditable }) => {
29790
+ var _excluded$21 = ["size"];
29791
+ var Plus$8 = (_ref) => {
29792
+ let { size = 14 } = _ref;
29793
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", _objectSpread2(_objectSpread2({
29794
+ xmlns: "http://www.w3.org/2000/svg",
29795
+ viewBox: "0 0 14 14",
29796
+ fill: "none"
29797
+ }, _objectWithoutProperties(_ref, _excluded$21)), {}, {
29798
+ width: size,
29799
+ height: size,
29800
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29801
+ d: "M7 2.91602V11.0827",
29802
+ stroke: "currentColor",
29803
+ strokeLinecap: "round",
29804
+ strokeLinejoin: "round"
29805
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29806
+ d: "M2.91669 7H11.0834",
29807
+ stroke: "currentColor",
29808
+ strokeLinecap: "round",
29809
+ strokeLinejoin: "round"
29810
+ })]
29811
+ }));
29812
+ };
29813
+ var Plus_default = Plus$8;
29814
+ var getLedgerAccountBalancesCSV = get(({ businessId }) => `/v1/businesses/${businessId}/ledger/balances/exports/csv`);
29815
+ function buildKey$51({ access_token: accessToken, apiUrl, businessId, startCutoff, endCutoff }) {
29816
+ if (accessToken && apiUrl) return {
29817
+ accessToken,
29818
+ apiUrl,
29819
+ businessId,
29820
+ startCutoff,
29821
+ endCutoff,
29822
+ tags: [
29823
+ "#account-balances",
29824
+ "#exports",
29825
+ "#csv"
29826
+ ]
29827
+ };
29828
+ }
29829
+ function useAccountBalancesDownload({ startCutoff, endCutoff, onSuccess }) {
29830
+ const withLocale = useLocalizedKey();
29831
+ const { data: auth } = useAuth();
29832
+ const { businessId } = useLayerContext();
29833
+ return (0, swr_mutation.default)(() => withLocale(buildKey$51(_objectSpread2(_objectSpread2({}, auth), {}, {
29834
+ businessId,
29835
+ startCutoff,
29836
+ endCutoff
29837
+ }))), ({ accessToken, apiUrl, businessId: businessId$1, startCutoff: startCutoff$1, endCutoff: endCutoff$1 }) => getLedgerAccountBalancesCSV(apiUrl, accessToken, { params: {
29838
+ businessId: businessId$1,
29839
+ startCutoff: startCutoff$1 === null || startCutoff$1 === void 0 ? void 0 : startCutoff$1.toISOString(),
29840
+ endCutoff: endCutoff$1 === null || endCutoff$1 === void 0 ? void 0 : endCutoff$1.toISOString()
29841
+ } })().then(({ data }) => {
29842
+ if (onSuccess) return onSuccess(data);
29843
+ }), {
29844
+ revalidate: false,
29845
+ throwOnError: false
29846
+ });
29847
+ }
29848
+ function AccountBalancesDownloadButton({ startCutoff, endCutoff, iconOnly }) {
29849
+ const { t } = (0, react_i18next.useTranslation)();
29850
+ const { invisibleDownloadRef, triggerInvisibleDownload } = useInvisibleDownload();
29851
+ const { trigger, isMutating, error: error$38 } = useAccountBalancesDownload({
29852
+ startCutoff,
29853
+ endCutoff,
29854
+ onSuccess: ({ presignedUrl }) => triggerInvisibleDownload({ url: presignedUrl })
29855
+ });
29856
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(DownloadButton, {
29857
+ iconOnly,
29858
+ onClick: () => {
29859
+ trigger();
29860
+ },
29861
+ isDownloading: isMutating,
29862
+ requestFailed: Boolean(error$38),
29863
+ text: t("common:action.download_csv", "Download CSV")
29864
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InvisibleDownload_default, { ref: invisibleDownloadRef })] });
29865
+ }
29866
+ var Collapse = (_ref) => {
29867
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", _objectSpread2(_objectSpread2({
29868
+ xmlns: "http://www.w3.org/2000/svg",
29869
+ width: "14",
29870
+ height: "22",
29871
+ viewBox: "0 0 14 22",
29872
+ fill: "none"
29873
+ }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29874
+ d: "M3.5 5.25L7 8.75L10.5 5.25",
29875
+ stroke: "currentColor",
29876
+ strokeLinecap: "round",
29877
+ strokeLinejoin: "round"
29878
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29879
+ d: "M3.5 16.75L7 13.25L10.5 16.75",
29880
+ stroke: "currentColor",
29881
+ strokeLinecap: "round",
29882
+ strokeLinejoin: "round"
29883
+ })] }));
29884
+ };
29885
+ var Collapse_default = Collapse;
29886
+ var Expand = (_ref) => {
29887
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", _objectSpread2(_objectSpread2({
29888
+ xmlns: "http://www.w3.org/2000/svg",
29889
+ width: "14",
29890
+ height: "22",
29891
+ viewBox: "0 0 14 22",
29892
+ fill: "none"
29893
+ }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29894
+ d: "M10.5 8.75L7 5.25L3.5 8.75",
29895
+ stroke: "currentColor",
29896
+ strokeLinecap: "round",
29897
+ strokeLinejoin: "round"
29898
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
29899
+ d: "M3.5 13.25L7 16.75L10.5 13.25",
29900
+ stroke: "currentColor",
29901
+ strokeLinecap: "round",
29902
+ strokeLinejoin: "round"
29903
+ })] }));
29904
+ };
29905
+ var Expand_default = Expand;
29906
+ const ExpandableDataTableToggleButton = () => {
29907
+ const { t } = (0, react_i18next.useTranslation)();
29908
+ const { expanded, setExpanded } = (0, react.useContext)(ExpandableDataTableContext);
29909
+ const { isDesktop } = useSizeClass();
29910
+ const shouldCollapse = expanded === true;
29911
+ const onClickExpandOrCollapse = (0, react.useCallback)(() => {
29912
+ if (shouldCollapse) setExpanded({});
29913
+ else setExpanded(true);
29914
+ }, [setExpanded, shouldCollapse]);
29915
+ const buttonText = shouldCollapse ? t("common:action.collapse_all", "Collapse All") : t("common:action.expand_all", "Expand All");
29916
+ const Icon = shouldCollapse ? Collapse_default : Expand_default;
29917
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
29918
+ icon: !isDesktop,
29919
+ variant: "outlined",
29920
+ onClick: onClickExpandOrCollapse,
29921
+ "aria-label": !isDesktop ? buttonText : void 0,
29922
+ children: !isDesktop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {}) : buttonText
29923
+ });
29924
+ };
29925
+ const ChartOfAccountsTableHeader = ({ asWidget, withDateControl, withExpandAllButton, showAddAccountButton, inputValue, onSearchChange, stringOverrides }) => {
29891
29926
  const { t } = (0, react_i18next.useTranslation)();
29892
- const { data, isLoading, addAccount, isError, isValidating, refetch, form } = (0, react.useContext)(ChartOfAccountsContext);
29893
- const [expandAll, setExpandAll] = (0, react.useState)();
29927
+ const { addAccount } = (0, react.useContext)(ChartOfAccountsContext);
29928
+ const { isDesktop } = useSizeClass();
29929
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header$1, {
29930
+ asHeader: true,
29931
+ rounded: true,
29932
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCol, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Heading$1, {
29933
+ size: asWidget ? HeadingSize.view : HeadingSize.primary,
29934
+ children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.headerText) || t("chartOfAccounts:label.chart_of_accounts", "Chart of Accounts")
29935
+ }) }) })
29936
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header$1, {
29937
+ sticky: true,
29938
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HeaderRow, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCol, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Heading$1, {
29939
+ size: HeadingSize.secondary,
29940
+ children: withDateControl || withExpandAllButton ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
29941
+ align: "center",
29942
+ gap: "xs",
29943
+ children: [withDateControl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalMonthPicker, {}), withExpandAllButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandableDataTableToggleButton, {})]
29944
+ }) : null
29945
+ }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HeaderCol, {
29946
+ className: "Layer__chart-of-accounts__actions",
29947
+ children: [
29948
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchField, {
29949
+ label: t("chartOfAccounts:label.search_accounts", "Search accounts"),
29950
+ value: inputValue,
29951
+ onChange: onSearchChange
29952
+ }),
29953
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountBalancesDownloadButton, { iconOnly: !isDesktop }),
29954
+ showAddAccountButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
29955
+ onClick: () => addAccount(),
29956
+ iconOnly: !isDesktop,
29957
+ leftIcon: !isDesktop && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Plus_default, { size: 14 }),
29958
+ children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.addAccountButtonText) || t("chartOfAccounts:action.add_account", "Add Account")
29959
+ })
29960
+ ]
29961
+ })] })
29962
+ })] });
29963
+ };
29964
+ const ChartOfAccountsTableWithPanel = ({ containerRef, asWidget = false, withDateControl = false, withExpandAllButton = false, showAddAccountButton = true, stringOverrides, templateAccountsEditable }) => {
29965
+ const { form } = (0, react.useContext)(ChartOfAccountsContext);
29894
29966
  const { inputValue, searchQuery, handleInputChange } = useDebouncedSearchInput({ initialInputState: "" });
29895
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Panel, {
29896
- sidebar: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsSidebar, {
29897
- parentRef: containerRef,
29898
- stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.chartOfAccountsForm
29899
- }),
29900
- sidebarIsOpen: Boolean(form),
29967
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandableDataTableProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Panel, {
29968
+ sidebar: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsForm, { stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.chartOfAccountsForm }),
29969
+ sidebarIsOpen: !!form,
29901
29970
  parentRef: containerRef,
29902
- children: [
29903
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header$1, {
29904
- className: `Layer__${COMPONENT_NAME$8}__header`,
29905
- asHeader: true,
29906
- rounded: true,
29907
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderRow, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCol, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Heading$1, {
29908
- className: `Layer__${COMPONENT_NAME$8}__title`,
29909
- size: asWidget ? HeadingSize.view : HeadingSize.primary,
29910
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.headerText) || t("chartOfAccounts:label.chart_of_accounts", "Chart of Accounts")
29911
- }) }) })
29912
- }),
29913
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Header$1, {
29914
- className: `Layer__${COMPONENT_NAME$8}__header`,
29915
- sticky: true,
29916
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HeaderRow, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeaderCol, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Heading$1, {
29917
- size: HeadingSize.secondary,
29918
- className: `Layer__${COMPONENT_NAME$8}__subtitle`,
29919
- children: withDateControl || withExpandAllButton ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
29920
- align: "center",
29921
- gap: "xs",
29922
- children: [withDateControl && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalMonthPicker, {}), withExpandAllButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandCollapseButton, {
29923
- iconOnly: view === "mobile",
29924
- onClick: () => setExpandAll(!expandAll || expandAll === "collapsed" ? "expanded" : "collapsed"),
29925
- expanded: !(!expandAll || expandAll === "collapsed"),
29926
- variant: ButtonVariant.secondary
29927
- })]
29928
- }) : null
29929
- }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HeaderCol, {
29930
- className: "Layer__chart-of-accounts__actions",
29931
- children: [
29932
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchField, {
29933
- label: t("chartOfAccounts:label.search_accounts", "Search accounts"),
29934
- value: inputValue,
29935
- onChange: handleInputChange
29936
- }),
29937
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountBalancesDownloadButton, { iconOnly: ["mobile", "tablet"].includes(view) }),
29938
- showAddAccountButton && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button$1, {
29939
- onClick: () => addAccount(),
29940
- iconOnly: ["mobile", "tablet"].includes(view),
29941
- leftIcon: ["mobile", "tablet"].includes(view) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Plus_default, { size: 14 }),
29942
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.addAccountButtonText) || t("chartOfAccounts:action.add_account", "Add Account")
29943
- })
29944
- ]
29945
- })] })
29946
- }),
29947
- data && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsTable, {
29948
- view,
29949
- data,
29950
- searchQuery,
29951
- stringOverrides,
29952
- expandAll,
29953
- templateAccountsEditable
29954
- }),
29955
- isError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
29956
- className: "Layer__table-state-container",
29957
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataState, {
29958
- status: DataStateStatus.failed,
29959
- title: t("common:error.something_went_wrong", "Something went wrong"),
29960
- description: t("common:error.couldnt_load_data", "We couldn’t load your data."),
29961
- onRefresh: () => void refetch(),
29962
- isLoading: isValidating || isLoading
29963
- })
29964
- }) : null,
29965
- (!data || isLoading) && !isError ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
29966
- className: `Layer__${COMPONENT_NAME$8}__loader-container`,
29967
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Loader, {})
29968
- }) : null
29969
- ]
29970
- });
29971
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsTableHeader, {
29972
+ asWidget,
29973
+ withDateControl,
29974
+ withExpandAllButton,
29975
+ showAddAccountButton,
29976
+ inputValue,
29977
+ onSearchChange: handleInputChange,
29978
+ stringOverrides
29979
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChartOfAccountsTable, {
29980
+ searchQuery,
29981
+ stringOverrides,
29982
+ templateAccountsEditable
29983
+ })]
29984
+ }) });
29971
29985
  };
29972
29986
  const LedgerAccountRow = ({ row, index, view, nodeType }) => {
29973
29987
  var _ledgerEntrySource$di3, _row$account$name3, _row$account3;
@@ -30326,7 +30340,6 @@ var ChartOfAccountsContent = ({ asWidget, withDateControl, withExpandAllButton,
30326
30340
  asWidget,
30327
30341
  withDateControl,
30328
30342
  withExpandAllButton,
30329
- view,
30330
30343
  containerRef,
30331
30344
  showAddAccountButton,
30332
30345
  stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.chartOfAccountsTable,
@@ -31055,10 +31068,10 @@ const JournalEntryLineItem = ({ form, index, displayIndex, isReadOnly, onDeleteL
31055
31068
  })
31056
31069
  });
31057
31070
  };
31058
- var EMPTY_ARRAY$2 = [];
31071
+ var EMPTY_ARRAY$1 = [];
31059
31072
  const JournalEntryLineItemsTable = ({ form, isReadOnly, title, direction, showTags = false }) => {
31060
31073
  const { t } = (0, react_i18next.useTranslation)();
31061
- const lineItems = (0, __tanstack_react_form.useStore)(form.store, (state$16) => state$16.values.lineItems || EMPTY_ARRAY$2);
31074
+ const lineItems = (0, __tanstack_react_form.useStore)(form.store, (state$16) => state$16.values.lineItems || EMPTY_ARRAY$1);
31062
31075
  const filteredIndices = (0, react.useMemo)(() => {
31063
31076
  const indices = [];
31064
31077
  lineItems.forEach((item, index) => {
@@ -39439,18 +39452,20 @@ function useUnifiedReportParams() {
39439
39452
  const dateSelectionMode = useUnifiedReportDateSelectionMode();
39440
39453
  const { date: effectiveDate } = useGlobalDate({ dateSelectionMode });
39441
39454
  const { startDate, endDate } = useGlobalDateRange({ dateSelectionMode });
39455
+ const { startDate: yearStartDate } = useGlobalDateRange({ dateSelectionMode: "year" });
39442
39456
  return (0, react.useMemo)(() => {
39443
39457
  if (!report) return null;
39444
- return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({ route: report.reportRoute }, report.baseQueryParameters), hasControl(report, ReportControl.Date) && { effectiveDate }), hasControl(report, ReportControl.DateRange) && {
39458
+ return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({ route: report.reportRoute }, report.baseQueryParameters), hasControl(report, ReportControl.Date) && { effectiveDate }), hasControl(report, ReportControl.DateRange) && {
39445
39459
  startDate,
39446
39460
  endDate
39447
- }), hasControl(report, ReportControl.GroupBy) && groupBy != null && { groupBy });
39461
+ }), hasControl(report, ReportControl.GroupBy) && groupBy != null && { groupBy }), hasControl(report, ReportControl.Year) && { year: (0, date_fns.getYear)(yearStartDate) });
39448
39462
  }, [
39449
39463
  effectiveDate,
39450
39464
  endDate,
39451
39465
  groupBy,
39452
39466
  report,
39453
- startDate
39467
+ startDate,
39468
+ yearStartDate
39454
39469
  ]);
39455
39470
  }
39456
39471
  var findDefaultReport = (groups) => {
@@ -39506,22 +39521,6 @@ function UnifiedReportStoreProvider({ children, dateSelectionMode = "full" }) {
39506
39521
  children
39507
39522
  });
39508
39523
  }
39509
- var defaultContextValue = {
39510
- expanded: {},
39511
- setExpanded: () => {}
39512
- };
39513
- const ExpandableDataTableContext = (0, react.createContext)(defaultContextValue);
39514
- function ExpandableDataTableProvider({ children }) {
39515
- const [expanded, setExpanded] = (0, react.useState)({});
39516
- const value = (0, react.useMemo)(() => ({
39517
- expanded,
39518
- setExpanded
39519
- }), [expanded]);
39520
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandableDataTableContext.Provider, {
39521
- value,
39522
- children
39523
- });
39524
- }
39525
39524
  var _excluded$8 = ["children", "className"], _excluded2$3 = ["children"], _excluded3 = ["children"];
39526
39525
  var TREE_CLASS_NAME = "Layer__UI__Tree";
39527
39526
  var TREE_ITEM_CLASS_NAME = "Layer__UI__TreeItem";
@@ -39594,11 +39593,7 @@ var renderTreeGroup = ({ group, groupConfig: groupConfig$1, onToggle, renderItem
39594
39593
  var renderTreeLeaf = ({ leaf, leafConfig }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TreeItem, {
39595
39594
  id: leafConfig.getId(leaf),
39596
39595
  textValue: leafConfig.getTextValue(leaf),
39597
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TreeItemContent, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
39598
- align: "center",
39599
- justify: "space-between",
39600
- children: [leafConfig.renderLabel(leaf), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Check_default, { className: "Layer__TreeNavigation__Check" })]
39601
- }) })
39596
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TreeItemContent, { children: leafConfig.renderLabel(leaf) })
39602
39597
  });
39603
39598
  function TreeNavigation({ items, selectedItem, isGroup: isGroup$1, groupConfig: groupConfig$1, leafConfig, ariaLabel }) {
39604
39599
  const { t } = (0, react_i18next.useTranslation)();
@@ -39733,25 +39728,6 @@ function ReportsNavigation() {
39733
39728
  }
39734
39729
  });
39735
39730
  }
39736
- const ExpandableDataTableToggleButton = () => {
39737
- const { t } = (0, react_i18next.useTranslation)();
39738
- const { expanded, setExpanded } = (0, react.useContext)(ExpandableDataTableContext);
39739
- const { isDesktop } = useSizeClass();
39740
- const shouldCollapse = expanded === true;
39741
- const onClickExpandOrCollapse = (0, react.useCallback)(() => {
39742
- if (shouldCollapse) setExpanded({});
39743
- else setExpanded(true);
39744
- }, [setExpanded, shouldCollapse]);
39745
- const buttonText = shouldCollapse ? t("common:action.collapse_all", "Collapse All") : t("common:action.expand_all", "Expand All");
39746
- const Icon = shouldCollapse ? Collapse_default : Expand_default;
39747
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
39748
- icon: !isDesktop,
39749
- variant: "outlined",
39750
- onClick: onClickExpandOrCollapse,
39751
- "aria-label": !isDesktop ? buttonText : void 0,
39752
- children: !isDesktop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {}) : buttonText
39753
- });
39754
- };
39755
39731
  var ReportComboBoxOption = class extends BaseComboBoxOption {
39756
39732
  constructor(report) {
39757
39733
  super(report);
@@ -39917,90 +39893,6 @@ function useUnifiedReport() {
39917
39893
  return getUnifiedReport(apiUrl$1, accessToken, { params: _objectSpread2({ businessId: businessId$1 }, restParams) })().then(({ data }) => effect.Schema.decodeUnknownPromise(UnifiedReportSchema)(data));
39918
39894
  }));
39919
39895
  }
39920
- var baseClassName = "Layer__ExpandButton";
39921
- const ExpandButton = ({ isExpanded }) => {
39922
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChevronDownFill_default, {
39923
- className: (0, classnames.default)(baseClassName, `${baseClassName}--${isExpanded ? "expanded" : "collapsed"}`),
39924
- size: 16,
39925
- "aria-label": isExpanded ? "Collapse row" : "Expand row"
39926
- });
39927
- };
39928
- var INDENT_SIZE_XS = 10;
39929
- var INDENT_SIZE_SM = 20;
39930
- var INDENT_SIZE_MD = 40;
39931
- var CHEVRON_OFFSET_PX = 4;
39932
- var getRowIndentStyle = ({ depth, canExpand, indentSizePx }) => ({ paddingInlineStart: depth * indentSizePx + (canExpand ? 0 : CHEVRON_OFFSET_PX) });
39933
- var EMPTY_ARRAY$1 = [];
39934
- function ExpandableDataTable({ data, isLoading, isError, columnConfig, componentName, ariaLabel, slots, getSubRows: getSubRows$3, getRowId: getRowId$2, indentSize = "sm" }) {
39935
- const { expanded, setExpanded } = (0, react.useContext)(ExpandableDataTableContext);
39936
- const wrappedColumnConfig = (0, react.useMemo)(() => {
39937
- const indentSizePx = indentSize === "xs" ? INDENT_SIZE_XS : indentSize === "md" ? INDENT_SIZE_MD : INDENT_SIZE_SM;
39938
- const [first, ...rest] = columnConfig;
39939
- if (!first || !isLeafColumn(first)) return columnConfig;
39940
- const cellRenderer = first.cell;
39941
- return [_objectSpread2(_objectSpread2({}, first), {}, { cell: (row) => {
39942
- const canExpand = row.getCanExpand();
39943
- const rowIndentStyle = getRowIndentStyle({
39944
- canExpand,
39945
- depth: row.depth,
39946
- indentSizePx
39947
- });
39948
- if (!canExpand) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39949
- style: rowIndentStyle,
39950
- children: cellRenderer(row)
39951
- });
39952
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
39953
- style: rowIndentStyle,
39954
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
39955
- align: "center",
39956
- gap: "xs",
39957
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpandButton, { isExpanded: row.getIsExpanded() }), cellRenderer(row)]
39958
- })
39959
- });
39960
- } }), ...rest];
39961
- }, [columnConfig, indentSize]);
39962
- const columnDefs = getColumnDefs(wrappedColumnConfig);
39963
- const columnPinning = (0, react.useMemo)(() => getColumnPinning(wrappedColumnConfig), [wrappedColumnConfig]);
39964
- const table$1 = (0, __tanstack_react_table.useReactTable)({
39965
- data: data !== null && data !== void 0 ? data : EMPTY_ARRAY$1,
39966
- columns: columnDefs,
39967
- getSubRows: getSubRows$3,
39968
- getCoreRowModel: (0, __tanstack_react_table.getCoreRowModel)(),
39969
- getExpandedRowModel: (0, __tanstack_react_table.getExpandedRowModel)(),
39970
- state: {
39971
- expanded,
39972
- columnPinning
39973
- },
39974
- onExpandedChange: setExpanded,
39975
- autoResetPageIndex: false,
39976
- getRowId: getRowId$2
39977
- });
39978
- const { rows } = table$1.getExpandedRowModel();
39979
- const dependencies$1 = (0, react.useMemo)(() => [expanded], [expanded]);
39980
- const headerGroups = table$1.getHeaderGroups();
39981
- const numColumns = table$1.getVisibleLeafColumns().length;
39982
- const isRowClickable = (0, react.useCallback)((row) => {
39983
- return row.getCanExpand();
39984
- }, []);
39985
- const onRowClick = (0, react.useCallback)((row) => {
39986
- row.toggleExpanded();
39987
- }, []);
39988
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataTable, {
39989
- ariaLabel,
39990
- numColumns,
39991
- data: rows,
39992
- isLoading,
39993
- isError,
39994
- componentName,
39995
- slots,
39996
- dependencies: dependencies$1,
39997
- headerGroups,
39998
- withClickableRow: (0, react.useMemo)(() => ({
39999
- onRowClick,
40000
- isRowClickable
40001
- }), [onRowClick, isRowClickable])
40002
- });
40003
- }
40004
39896
  var _excluded$5 = [
40005
39897
  "durationMinutes",
40006
39898
  "className",
@@ -40134,8 +40026,8 @@ const UnifiedReportTable = () => {
40134
40026
  const UnifiedReportEmptyState = (0, react.useCallback)(() => {
40135
40027
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DataState, {
40136
40028
  status: DataStateStatus.allDone,
40137
- title: t("reports:empty.no_rows_found", "No rows found"),
40138
- description: t("reports:empty.report_has_no_rows", "This report has no rows."),
40029
+ title: t("reports:empty.no_rows_found", "No line items found"),
40030
+ description: t("reports:empty.report_has_no_rows", "This report has no line items."),
40139
40031
  spacing: true
40140
40032
  });
40141
40033
  }, [t]);
@@ -40163,6 +40055,63 @@ const UnifiedReportTable = () => {
40163
40055
  getRowId: (row) => row.rowKey
40164
40056
  });
40165
40057
  };
40058
+ const YearPicker = ({ label: label$50, year, onChange, minDate = null, maxDate = null, isDisabled = false }) => {
40059
+ var _minDate$year, _maxDate$year;
40060
+ const { t } = (0, react_i18next.useTranslation)();
40061
+ const { formatDate: formatDate$1 } = useIntlFormatter();
40062
+ const coercedLabel = label$50 !== null && label$50 !== void 0 ? label$50 : t("date:label.year", "Year");
40063
+ const minYear = (_minDate$year = minDate === null || minDate === void 0 ? void 0 : minDate.year) !== null && _minDate$year !== void 0 ? _minDate$year : null;
40064
+ const maxYear = (_maxDate$year = maxDate === null || maxDate === void 0 ? void 0 : maxDate.year) !== null && _maxDate$year !== void 0 ? _maxDate$year : null;
40065
+ const yearOptions = (0, react.useMemo)(() => {
40066
+ const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
40067
+ const effectiveMinYear = minYear !== null && minYear !== void 0 ? minYear : currentYear - 10;
40068
+ const effectiveMaxYear = maxYear !== null && maxYear !== void 0 ? maxYear : currentYear;
40069
+ const count = effectiveMaxYear - effectiveMinYear + 1;
40070
+ if (count <= 0) return [];
40071
+ return Array.from({ length: count }, (_, i) => {
40072
+ const optionYear = effectiveMaxYear - i;
40073
+ return {
40074
+ label: formatDate$1(new Date(optionYear, 0, 1), DateFormat.Year),
40075
+ value: String(optionYear)
40076
+ };
40077
+ });
40078
+ }, [
40079
+ formatDate$1,
40080
+ minYear,
40081
+ maxYear
40082
+ ]);
40083
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ComboBox, {
40084
+ selectedValue: (0, react.useMemo)(() => {
40085
+ var _yearOptions$find;
40086
+ return (_yearOptions$find = yearOptions.find((opt) => opt.value === String(year))) !== null && _yearOptions$find !== void 0 ? _yearOptions$find : yearOptions[0];
40087
+ }, [yearOptions, year]),
40088
+ onSelectedValueChange: (0, react.useCallback)((option) => {
40089
+ if (option) onChange(Number(option.value));
40090
+ }, [onChange]),
40091
+ options: yearOptions,
40092
+ isSearchable: false,
40093
+ isClearable: false,
40094
+ isDisabled,
40095
+ "aria-label": coercedLabel,
40096
+ className: "Layer__YearPicker"
40097
+ });
40098
+ };
40099
+ const GlobalYearPicker = () => {
40100
+ const { minDate, maxDate } = useGlobalDatePickerBounds();
40101
+ const { setYear } = useGlobalDateRangeActions();
40102
+ const { startDate } = useGlobalDateRange({ dateSelectionMode: "year" });
40103
+ const selectedYear = (0, date_fns.getYear)(startDate);
40104
+ const minDateZdt = (0, react.useMemo)(() => minDate ? convertDateToZonedDateTime(minDate) : null, [minDate]);
40105
+ const maxDateZdt = (0, react.useMemo)(() => convertDateToZonedDateTime(maxDate), [maxDate]);
40106
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(YearPicker, {
40107
+ year: selectedYear,
40108
+ onChange: (0, react.useCallback)((year) => {
40109
+ setYear({ startDate: new Date(year, 0, 1) });
40110
+ }, [setYear]),
40111
+ minDate: minDateZdt,
40112
+ maxDate: maxDateZdt
40113
+ });
40114
+ };
40166
40115
  var SMALL_BREAKPOINT$1 = 560;
40167
40116
  var MEDIUM_BREAKPOINT$1 = 760;
40168
40117
  var getVariantForWidth = (width) => {
@@ -40194,39 +40143,43 @@ const UnifiedReportControls = () => {
40194
40143
  });
40195
40144
  const variant = getVariantForWidth(size);
40196
40145
  const hasGroupBy = dateSelectionMode === "full" && hasControl(baseReport, ReportControl.GroupBy);
40146
+ const hasYear = hasControl(baseReport, ReportControl.Year);
40197
40147
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Stack, {
40198
40148
  ref: containerRef,
40199
40149
  direction: variant === "large" ? "row" : "column",
40200
40150
  pb: "md",
40201
40151
  pi: "lg",
40202
40152
  gap: "xs",
40203
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportDateSelection, { isCompact: variant === "small" }), hasGroupBy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
40153
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportDateSelection, { isCompact: variant === "small" }), (hasYear || hasGroupBy) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
40204
40154
  className: "Layer__UnifiedReport__AdditionalControls",
40205
40155
  "data-variant": variant,
40206
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DateGroupByComboBox, {
40156
+ children: [hasYear && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalYearPicker, {}), hasGroupBy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DateGroupByComboBox, {
40207
40157
  value: groupBy,
40208
40158
  onValueChange: setGroupBy
40209
- })
40159
+ })]
40210
40160
  })]
40211
40161
  });
40212
40162
  };
40213
40163
  const UnifiedReportBaseHeader = () => {
40214
40164
  const { baseReport } = useBaseUnifiedReport();
40215
40165
  const { isDesktop } = useSizeClass();
40216
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, { children: [isDesktop && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
40217
- pi: "lg",
40218
- pbs: "lg",
40219
- align: "center",
40220
- justify: "space-between",
40221
- children: [baseReport ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
40222
- size: "lg",
40223
- weight: "bold",
40224
- children: baseReport.displayName
40225
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonLoader, {
40226
- width: "192px",
40227
- height: "24px"
40228
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportHeaderButtons, {})]
40229
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportControls, {})] });
40166
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, {
40167
+ className: "Layer__UnifiedReport__BaseHeader",
40168
+ children: [isDesktop && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
40169
+ pi: "lg",
40170
+ pbs: "lg",
40171
+ align: "center",
40172
+ justify: "space-between",
40173
+ children: [baseReport ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Span, {
40174
+ size: "lg",
40175
+ weight: "bold",
40176
+ children: baseReport.displayName
40177
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SkeletonLoader, {
40178
+ width: "192px",
40179
+ height: "24px"
40180
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportHeaderButtons, {})]
40181
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportControls, {})]
40182
+ });
40230
40183
  };
40231
40184
  var _excluded$4 = [
40232
40185
  "children",
@@ -40347,14 +40300,17 @@ var UnifiedReportContent = () => {
40347
40300
  title: t("reports:label.reports", "Reports"),
40348
40301
  viewClassName: "Layer__UnifiedReport",
40349
40302
  header,
40350
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, { children: [isDesktop && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VStack, {
40351
- className: "Layer__UnifiedReport__Sidebar",
40352
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReportsNavigation, {})
40353
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, {
40354
- fluid: true,
40355
- className: "Layer__UnifiedReport__Content",
40356
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportTableHeader, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportTable, {})]
40357
- })] })
40303
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(HStack, {
40304
+ className: "Layer__UnifiedReport__Body",
40305
+ children: [isDesktop && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VStack, {
40306
+ className: "Layer__UnifiedReport__Sidebar",
40307
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReportsNavigation, {})
40308
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(VStack, {
40309
+ fluid: true,
40310
+ className: "Layer__UnifiedReport__Content",
40311
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportTableHeader, {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UnifiedReportTable, {})]
40312
+ })]
40313
+ })
40358
40314
  });
40359
40315
  };
40360
40316
  const UnifiedReport = ({ dateSelectionMode }) => {
@@ -41055,63 +41011,6 @@ const GeneralLedgerView = ({ title, showTitle = true, showTags = true, showCusto
41055
41011
  })
41056
41012
  });
41057
41013
  };
41058
- const YearPicker = ({ label: label$50, year, onChange, minDate = null, maxDate = null, isDisabled = false }) => {
41059
- var _minDate$year, _maxDate$year;
41060
- const { t } = (0, react_i18next.useTranslation)();
41061
- const { formatDate: formatDate$1 } = useIntlFormatter();
41062
- const coercedLabel = label$50 !== null && label$50 !== void 0 ? label$50 : t("date:label.year", "Year");
41063
- const minYear = (_minDate$year = minDate === null || minDate === void 0 ? void 0 : minDate.year) !== null && _minDate$year !== void 0 ? _minDate$year : null;
41064
- const maxYear = (_maxDate$year = maxDate === null || maxDate === void 0 ? void 0 : maxDate.year) !== null && _maxDate$year !== void 0 ? _maxDate$year : null;
41065
- const yearOptions = (0, react.useMemo)(() => {
41066
- const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
41067
- const effectiveMinYear = minYear !== null && minYear !== void 0 ? minYear : currentYear - 10;
41068
- const effectiveMaxYear = maxYear !== null && maxYear !== void 0 ? maxYear : currentYear;
41069
- const count = effectiveMaxYear - effectiveMinYear + 1;
41070
- if (count <= 0) return [];
41071
- return Array.from({ length: count }, (_, i) => {
41072
- const optionYear = effectiveMaxYear - i;
41073
- return {
41074
- label: formatDate$1(new Date(optionYear, 0, 1), DateFormat.Year),
41075
- value: String(optionYear)
41076
- };
41077
- });
41078
- }, [
41079
- formatDate$1,
41080
- minYear,
41081
- maxYear
41082
- ]);
41083
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ComboBox, {
41084
- selectedValue: (0, react.useMemo)(() => {
41085
- var _yearOptions$find;
41086
- return (_yearOptions$find = yearOptions.find((opt) => opt.value === String(year))) !== null && _yearOptions$find !== void 0 ? _yearOptions$find : yearOptions[0];
41087
- }, [yearOptions, year]),
41088
- onSelectedValueChange: (0, react.useCallback)((option) => {
41089
- if (option) onChange(Number(option.value));
41090
- }, [onChange]),
41091
- options: yearOptions,
41092
- isSearchable: false,
41093
- isClearable: false,
41094
- isDisabled,
41095
- "aria-label": coercedLabel,
41096
- className: "Layer__YearPicker"
41097
- });
41098
- };
41099
- const GlobalYearPicker = () => {
41100
- const { minDate, maxDate } = useGlobalDatePickerBounds();
41101
- const { setYear } = useGlobalDateRangeActions();
41102
- const { startDate } = useGlobalDateRange({ dateSelectionMode: "year" });
41103
- const selectedYear = (0, date_fns.getYear)(startDate);
41104
- const minDateZdt = (0, react.useMemo)(() => minDate ? convertDateToZonedDateTime(minDate) : null, [minDate]);
41105
- const maxDateZdt = (0, react.useMemo)(() => convertDateToZonedDateTime(maxDate), [maxDate]);
41106
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(YearPicker, {
41107
- year: selectedYear,
41108
- onChange: (0, react.useCallback)((year) => {
41109
- setYear({ startDate: new Date(year, 0, 1) });
41110
- }, [setYear]),
41111
- minDate: minDateZdt,
41112
- maxDate: maxDateZdt
41113
- });
41114
- };
41115
41014
  var MileageDeductionChartTooltipContent = ({ active, payload }) => {
41116
41015
  const { t } = (0, react_i18next.useTranslation)();
41117
41016
  const { formatNumber: formatNumber$1 } = useIntlFormatter();