@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.
@@ -194,7 +194,7 @@ const getIntlLocale = (locale) => {
194
194
  return isSupportedLocale(locale) ? locale : DEFAULT_LOCALE;
195
195
  };
196
196
  const name = "@layerfi/components";
197
- const version = "0.1.129-alpha.1";
197
+ const version = "0.1.129";
198
198
  const description = "Layer React Components";
199
199
  const main = "dist/cjs/index.cjs";
200
200
  const module = "dist/esm/index.mjs";
@@ -365,15 +365,13 @@ var getCustomHeaders = () => ({
365
365
  "Layer-Locale": _locale,
366
366
  "Layer-React-Version": package_default.version
367
367
  });
368
- const get = (url) => (baseUrl, accessToken, options) => () => {
369
- return fetch(`${baseUrl}${url((options === null || options === void 0 ? void 0 : options.params) || {})}`, {
370
- headers: _objectSpread2({
371
- "Authorization": "Bearer " + (accessToken || ""),
372
- "Content-Type": "application/json"
373
- }, getCustomHeaders()),
374
- method: "GET"
375
- }).then((res) => handleResponse(res)).catch((error$38) => handleException(error$38));
376
- };
368
+ const get = (url) => (baseUrl, accessToken, options) => () => fetch(`${baseUrl}${url((options === null || options === void 0 ? void 0 : options.params) || {})}`, {
369
+ headers: _objectSpread2({
370
+ "Authorization": "Bearer " + (accessToken || ""),
371
+ "Content-Type": "application/json"
372
+ }, getCustomHeaders()),
373
+ method: "GET"
374
+ }).then((res) => handleResponse(res)).catch((error$38) => handleException(error$38));
377
375
  const getText = (url) => (baseUrl, accessToken, options) => () => fetch(`${baseUrl}${url((options === null || options === void 0 ? void 0 : options.params) || {})}`, {
378
376
  headers: _objectSpread2({ Authorization: "Bearer " + (accessToken || "") }, getCustomHeaders()),
379
377
  method: "GET"
@@ -1663,11 +1661,7 @@ var overview_default$1 = {
1663
1661
  }
1664
1662
  };
1665
1663
  var reports_default$1 = {
1666
- action: {
1667
- "collapse_rows": "Collapse all rows",
1668
- "expand_rows": "Expand all rows",
1669
- "search_reports": "Search reports"
1670
- },
1664
+ action: { "search_reports": "Search reports" },
1671
1665
  empty: {
1672
1666
  "no_detail_lines_found": "No detail lines found",
1673
1667
  "no_detail_lines_pnl_item": "There are no detail lines for this profit and loss item",
@@ -1780,20 +1774,12 @@ var taxEstimates_default$1 = {
1780
1774
  },
1781
1775
  label: {
1782
1776
  "additional_actions": "Additional actions",
1783
- "additional_state_taxes_estimate_owed": "Additional State Taxes Estimate (Owed)",
1784
- "adjusted_gross_income": "Adjusted Gross Income",
1785
- "amount_applied_federal_w2": "Amount Applied from Federal W-2 Withholding",
1786
- "amount_applied_state_withholding": "Amount Applied from State Withholding",
1787
1777
  "annual_taxes": "Annual taxes",
1788
1778
  "annual_w2_income": "Annual W-2 income",
1789
- "business_income": "Business Income",
1790
- "business_income_deduction_rate": "Business Income Deduction ({{rate}})",
1791
1779
  "business_income_taxes": "Business Income Taxes",
1792
1780
  "business_income_taxes_projected": "Projected Business Income Taxes",
1793
1781
  "calculated_from_categorized_transactions": "Calculated based on your categorized transactions and tracked mileage",
1794
1782
  "categorization_incomplete": "Categorization incomplete",
1795
- "deductible_expenses": "Deductible Expenses",
1796
- "deductible_mileage_expenses": "Deductible Mileage Expenses",
1797
1783
  "deductions": "Deductions",
1798
1784
  "due": "Due",
1799
1785
  "due_with_date": "Due: {{date}}",
@@ -1802,26 +1788,15 @@ var taxEstimates_default$1 = {
1802
1788
  "estimated_taxes": "Estimated taxes",
1803
1789
  "estimates": "Estimates",
1804
1790
  "federal": "Federal",
1805
- "federal_deductions": "Federal Deductions",
1806
1791
  "federal_state_tax_payments": "Federal and state tax payments for the selected tax year",
1807
1792
  "federal_state_tax_payments_projected": "Projected federal and state tax payments for the selected tax year",
1808
- "federal_tax": "Federal Tax",
1809
- "federal_tax_estimate_owed": "Federal Tax Estimate (Owed)",
1810
1793
  "federal_tax_information": "Federal Tax Information",
1811
- "federal_tax_rate": "Federal Tax Rate",
1812
- "federal_taxes": "Federal Taxes",
1813
- "federal_taxes_projected": "Projected Federal Taxes",
1814
1794
  "filing_status": "Filing status",
1815
1795
  "full_year_projection": "Full year projection",
1816
1796
  "head_household": "Head of household",
1817
1797
  "home_office_area_sq": "Home office area (sq ft)",
1818
- "home_office_deduction": "Home Office Deduction",
1819
1798
  "married_filing_jointly": "Married filing jointly",
1820
1799
  "married_filing_separately": "Married filing separately",
1821
- "medicare_surtax_estimate_owed": "Medicare Surtax Estimate (Owed)",
1822
- "medicare_surtax_rate": "Medicare Surtax Rate",
1823
- "medicare_tax_estimate_owed": "Medicare Tax Estimate (Owed)",
1824
- "medicare_tax_rate": "Medicare Tax Rate",
1825
1800
  "overtime_income": "Overtime income",
1826
1801
  "owed_quarter": "Owed This Quarter",
1827
1802
  "paid": "Paid",
@@ -1831,59 +1806,33 @@ var taxEstimates_default$1 = {
1831
1806
  "q2": "Q2",
1832
1807
  "q3": "Q3",
1833
1808
  "q4": "Q4",
1834
- "qualified_overtime_deduction": "Qualified Overtime Deduction",
1835
- "qualified_tip_deduction": "Qualified Tip Deduction",
1836
1809
  "qualifying_widow_er": "Qualifying widow(er)",
1837
1810
  "quarter": "Quarter",
1838
1811
  "quarter_taxes": "{{quarterLabel}} taxes",
1839
1812
  "remaining_balance": "Remaining Balance",
1840
1813
  "rolled_over_from_previous_quarter": "Rolled Over From Previous Quarter",
1841
- "self_employment_deduction": "Self-Employment Deduction",
1842
1814
  "single": "Single",
1843
- "social_security_tax_estimate_owed": "Social Security Tax Estimate (Owed)",
1844
- "social_security_tax_rate": "Social Security Tax Rate",
1845
1815
  "state": "State",
1846
- "state_adjusted_gross_income": "State Adjusted Gross Income",
1847
- "state_deductions": "State Deductions",
1848
- "state_income_tax_estimate_owed": "State Income Tax Estimate (Owed)",
1849
- "state_tax": "State Tax",
1850
- "state_tax_rate": "State Tax Rate",
1851
- "state_taxable_income": "State Taxable Income",
1852
- "tax_estimate_view": "Tax estimate view",
1853
- "tax_information": "State Tax Information",
1854
- "tax_name_estimate_owed": "{{taxName}} Estimate (Owed)",
1855
- "tax_name_rate": "{{taxName}} Rate",
1856
1816
  "tax_details": "Tax Details",
1857
1817
  "tax_details_amount": "Amount",
1858
1818
  "tax_details_label": "Label",
1819
+ "tax_estimate_view": "Tax estimate view",
1820
+ "tax_information": "State Tax Information",
1859
1821
  "tax_payments": "Tax Payments",
1860
1822
  "tax_payments_projected": "Projected Tax Payments",
1861
1823
  "tax_profile": "Tax Profile",
1862
1824
  "tax_profile_saved": "Tax profile saved",
1863
1825
  "tax_summary": "Tax Summary",
1864
- "taxable_amount_tax_name": "Taxable Amount for {{taxName}}",
1865
- "taxable_business_income": "Taxable Business Income",
1866
- "taxable_business_income_projected": "Projected Taxable Business Income",
1867
- "taxable_income": "Taxable Income",
1868
1826
  "taxable_income_estimate_to_date_for_year": "Taxable income estimate to date for year {{year}}",
1869
1827
  "taxable_income_estimate_to_date_for_year_projected": "Taxable income projection for year {{year}}",
1870
1828
  "taxable_income_for_year": "Taxable income for {{year}}",
1871
1829
  "taxable_income_for_year_projected": "Projected taxable income for {{year}}",
1872
- "taxable_medicare_income": "Taxable Medicare Income",
1873
- "taxable_medicare_surtax_income": "Taxable Medicare Surtax Income",
1874
- "taxable_social_security_income": "Taxable Social Security Income",
1875
- "taxes_by_state_name": "State Taxes ({{stateName}})",
1876
- "taxes_by_state_name_projected": "Projected State Taxes ({{stateName}})",
1877
- "taxes_due": "Taxes Due",
1878
1830
  "taxes_due_at": "Taxes due on {{date}}",
1879
1831
  "taxes_owed": "Taxes Owed",
1880
1832
  "taxes_owed_projected": "Projected Taxes Owed",
1881
1833
  "taxes_paid": "Taxes Paid",
1882
1834
  "tip_income": "Tip income",
1883
- "total_deductions": "Total Deductions",
1884
- "total_federal_tax_estimate": "Total Federal Tax Estimate",
1885
1835
  "total_paid": "Total Paid",
1886
- "total_state_tax_estimate": "Total State Tax Estimate",
1887
1836
  "uncategorized_transactions_one": "{{count}} uncategorized transaction",
1888
1837
  "uncategorized_transactions_other": "{{count}} uncategorized transactions",
1889
1838
  "uncategorized_transactions_with_year_one": "{{count}} uncategorized transaction ({{year}})",
@@ -1891,7 +1840,6 @@ var taxEstimates_default$1 = {
1891
1840
  "use_custom_withholding": "Use custom withholding?",
1892
1841
  "use_simplified_home_office": "Use simplified home office deduction?",
1893
1842
  "use_standard_mileage_deduction": "Use standard mileage deduction?",
1894
- "w2_income": "W-2 Income",
1895
1843
  "withholding_amount": "Withholding amount",
1896
1844
  "year_to_date": "Year to date",
1897
1845
  "your_tax_deadlines": "Your tax deadlines"
@@ -2630,7 +2578,7 @@ var common_default = {
2630
2578
  "equities": "Capitaux propres",
2631
2579
  "expenses": "Dépenses",
2632
2580
  "gross_profit": "Bénéfice brut",
2633
- "hide_details": "",
2581
+ "hide_details": "Masquer les détails",
2634
2582
  "id": "ID",
2635
2583
  "keep_editing": "Continuer à modifier",
2636
2584
  "liabilities": "Passifs",
@@ -2657,7 +2605,7 @@ var common_default = {
2657
2605
  "row": "Ligne",
2658
2606
  "savings": "Compte d’épargne",
2659
2607
  "select_all": "Tout sélectionner",
2660
- "show_details": "",
2608
+ "show_details": "Afficher les détails",
2661
2609
  "source": "Source",
2662
2610
  "status": "Statut",
2663
2611
  "tax_estimates": "Estimations fiscales",
@@ -3150,11 +3098,7 @@ var overview_default = {
3150
3098
  }
3151
3099
  };
3152
3100
  var reports_default = {
3153
- action: {
3154
- "collapse_rows": "Réduire toutes les lignes",
3155
- "expand_rows": "Afficher toutes les lignes",
3156
- "search_reports": "Rechercher des rapports"
3157
- },
3101
+ action: { "search_reports": "Rechercher des rapports" },
3158
3102
  empty: {
3159
3103
  "no_detail_lines_found": "Aucune ligne de détail trouvée",
3160
3104
  "no_detail_lines_pnl_item": "Il n’y a aucune ligne de détail pour cet élément de l’état des résultats",
@@ -3245,8 +3189,8 @@ var taxEstimates_default = {
3245
3189
  "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."
3246
3190
  },
3247
3191
  empty: {
3248
- "no_tax_details": "",
3249
- "no_tax_details_description": "",
3192
+ "no_tax_details": "Aucun détail fiscal",
3193
+ "no_tax_details_description": "Aucun détail fiscal trouvé",
3250
3194
  "no_tax_payments_to_display": "Il n’y a aucun paiement d’impôt à afficher.",
3251
3195
  "tax_payments": "Aucun paiement d’impôt trouvé"
3252
3196
  },
@@ -3254,33 +3198,25 @@ var taxEstimates_default = {
3254
3198
  "disclaimer_required": "Vous devez reconnaître l’avis de non-responsabilité pour continuer.",
3255
3199
  "feature_not_enabled": "Les estimations d'impôt ne sont pas activées.",
3256
3200
  "load_tax_deadlines": "Impossible de charger vos échéances fiscales",
3257
- "load_tax_details": "",
3201
+ "load_tax_details": "Impossible de charger vos détails fiscaux",
3258
3202
  "load_tax_estimates": "Nous n’avons pas pu charger vos estimations fiscales",
3259
3203
  "load_tax_estimates_summary": "Nous n’avons pas pu charger votre sommaire fiscal",
3260
3204
  "load_tax_information": "Impossible de charger les renseignements fiscaux",
3261
3205
  "load_tax_payments": "Nous n’avons pas pu charger vos paiements d’impôt",
3262
3206
  "retrieve_tax_profile": "Nous n’avons pas pu récupérer votre profil fiscal. Veuillez vérifier votre connexion et réessayer.",
3263
- "while_loading_tax_details": "",
3207
+ "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.",
3264
3208
  "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.",
3265
3209
  "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.",
3266
3210
  "while_loading_tax_summary": "Une erreur s’est produite lors du chargement de votre sommaire fiscal. Veuillez vérifier votre connexion et réessayer."
3267
3211
  },
3268
3212
  label: {
3269
3213
  "additional_actions": "Actions supplémentaires",
3270
- "additional_state_taxes_estimate_owed": "Estimation des impôts d’État supplémentaires (à payer)",
3271
- "adjusted_gross_income": "Revenu brut ajusté",
3272
- "amount_applied_federal_w2": "Montant appliqué de la retenue fédérale du formulaire W-2",
3273
- "amount_applied_state_withholding": "Montant appliqué de la retenue d'impôt de l'État",
3274
3214
  "annual_taxes": "Impôts annuels",
3275
3215
  "annual_w2_income": "Revenu annuel indiqué sur le formulaire W-2",
3276
- "business_income": "Revenu d’entreprise",
3277
- "business_income_deduction_rate": "Déduction pour revenu d’entreprise ({{rate}})",
3278
3216
  "business_income_taxes": "Impôts sur le revenu d’entreprise",
3279
3217
  "business_income_taxes_projected": "Impôts projetés sur le revenu d’entreprise",
3280
3218
  "calculated_from_categorized_transactions": "Calculé en fonction de vos opérations catégorisées et de votre kilométrage suivi",
3281
3219
  "categorization_incomplete": "Catégorisation incomplète",
3282
- "deductible_expenses": "Dépenses déductibles",
3283
- "deductible_mileage_expenses": "Frais de kilométrage déductibles",
3284
3220
  "deductions": "Déductions",
3285
3221
  "due": "Échéance",
3286
3222
  "due_with_date": "Échéance : {{date}}",
@@ -3289,26 +3225,15 @@ var taxEstimates_default = {
3289
3225
  "estimated_taxes": "Impôts estimés",
3290
3226
  "estimates": "Estimations",
3291
3227
  "federal": "Fédéral",
3292
- "federal_deductions": "Déductions fédérales",
3293
3228
  "federal_state_tax_payments": "Paiements d’impôt fédéral et d’État pour l’année d’imposition sélectionnée",
3294
3229
  "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",
3295
- "federal_tax": "Impôt fédéral",
3296
- "federal_tax_estimate_owed": "Estimation de l’impôt fédéral (à payer)",
3297
3230
  "federal_tax_information": "Renseignements sur l’impôt fédéral",
3298
- "federal_tax_rate": "Taux d’imposition fédéral",
3299
- "federal_taxes": "Impôts fédéraux",
3300
- "federal_taxes_projected": "Impôts fédéraux projetés",
3301
3231
  "filing_status": "Statut de déclaration",
3302
3232
  "full_year_projection": "Projection annuelle",
3303
3233
  "head_household": "Chef de famille",
3304
3234
  "home_office_area_sq": "Superficie du bureau à domicile (pi²)",
3305
- "home_office_deduction": "Déduction pour bureau à domicile",
3306
3235
  "married_filing_jointly": "Marié(e), déclaration conjointe",
3307
3236
  "married_filing_separately": "Marié(e), déclaration séparée",
3308
- "medicare_surtax_estimate_owed": "Estimation de la surtaxe Medicare (à payer)",
3309
- "medicare_surtax_rate": "Taux de la surtaxe Medicare",
3310
- "medicare_tax_estimate_owed": "Estimation de la taxe Medicare (à payer)",
3311
- "medicare_tax_rate": "Taux de la taxe Medicare",
3312
3237
  "overtime_income": "Revenu d’heures supplémentaires",
3313
3238
  "owed_quarter": "À payer ce trimestre",
3314
3239
  "paid": "Payé",
@@ -3318,59 +3243,33 @@ var taxEstimates_default = {
3318
3243
  "q2": "T2",
3319
3244
  "q3": "T3",
3320
3245
  "q4": "T4",
3321
- "qualified_overtime_deduction": "Déduction admissible pour heures supplémentaires",
3322
- "qualified_tip_deduction": "Déduction admissible pour pourboires",
3323
3246
  "qualifying_widow_er": "Veuf(ve) admissible",
3324
3247
  "quarter": "Trimestre",
3325
3248
  "quarter_taxes": "Impôts du {{quarterLabel}}",
3326
3249
  "remaining_balance": "Solde restant",
3327
3250
  "rolled_over_from_previous_quarter": "Reporté du trimestre précédent",
3328
- "self_employment_deduction": "Déduction pour travail autonome",
3329
3251
  "single": "Célibataire",
3330
- "social_security_tax_estimate_owed": "Estimation de la taxe de sécurité sociale (à payer)",
3331
- "social_security_tax_rate": "Taux de la taxe de sécurité sociale",
3332
3252
  "state": "État",
3333
- "state_adjusted_gross_income": "Revenu brut ajusté de l’État",
3334
- "state_deductions": "Déductions d’État",
3335
- "state_income_tax_estimate_owed": "Estimation de l’impôt sur le revenu de l’État (à payer)",
3336
- "state_tax": "Impôt d’État",
3337
- "state_tax_rate": "Taux d’imposition de l’État",
3338
- "state_taxable_income": "Revenu imposable de l’État",
3253
+ "tax_details": "Détails fiscaux",
3254
+ "tax_details_amount": "Montant",
3255
+ "tax_details_label": "Libellé",
3339
3256
  "tax_estimate_view": "Vue des estimations fiscales",
3340
3257
  "tax_information": "Renseignements sur l'impôt d'État",
3341
- "tax_name_estimate_owed": "Estimation de {{taxName}} (à payer)",
3342
- "tax_name_rate": "Taux de {{taxName}}",
3343
- "tax_details": "",
3344
- "tax_details_amount": "",
3345
- "tax_details_label": "",
3346
3258
  "tax_payments": "Paiements d’impôt",
3347
3259
  "tax_payments_projected": "Paiements d’impôt projetés",
3348
3260
  "tax_profile": "Profil fiscal",
3349
3261
  "tax_profile_saved": "Profil fiscal enregistré",
3350
3262
  "tax_summary": "Sommaire fiscal",
3351
- "taxable_amount_tax_name": "Montant imposable pour {{taxName}}",
3352
- "taxable_business_income": "Revenu d’entreprise imposable",
3353
- "taxable_business_income_projected": "Revenu d’entreprise imposable projeté",
3354
- "taxable_income": "Revenu imposable",
3355
3263
  "taxable_income_estimate_to_date_for_year": "Estimation du revenu imposable à ce jour pour l’année {{year}}",
3356
3264
  "taxable_income_estimate_to_date_for_year_projected": "Projection du revenu imposable pour l’année {{year}}",
3357
3265
  "taxable_income_for_year": "Revenu imposable pour {{year}}",
3358
3266
  "taxable_income_for_year_projected": "Revenu imposable projeté pour {{year}}",
3359
- "taxable_medicare_income": "Revenu Medicare imposable",
3360
- "taxable_medicare_surtax_income": "Revenu imposable pour la surtaxe Medicare",
3361
- "taxable_social_security_income": "Revenu imposable de la Sécurité Sociale",
3362
- "taxes_by_state_name": "Impôts d’État ({{stateName}})",
3363
- "taxes_by_state_name_projected": "Impôts d’État projetés ({{stateName}})",
3364
- "taxes_due": "Impôts à payer",
3365
- "taxes_due_at": "",
3267
+ "taxes_due_at": "Taxes à payer le {{date}}",
3366
3268
  "taxes_owed": "Impôts dus",
3367
3269
  "taxes_owed_projected": "Impôts dus projetés",
3368
3270
  "taxes_paid": "Impôts payés",
3369
3271
  "tip_income": "Revenu de pourboires",
3370
- "total_deductions": "",
3371
- "total_federal_tax_estimate": "Estimation totale de l’impôt fédéral",
3372
3272
  "total_paid": "Total payé",
3373
- "total_state_tax_estimate": "Estimation totale de l’impôt d’État",
3374
3273
  "uncategorized_transactions_one": "{{count}} transaction non catégorisée",
3375
3274
  "uncategorized_transactions_other": "{{count}} transactions non catégorisées",
3376
3275
  "uncategorized_transactions_with_year_one": "{{count}} transaction non catégorisée ({{year}})",
@@ -3378,7 +3277,6 @@ var taxEstimates_default = {
3378
3277
  "use_custom_withholding": "Utiliser une retenue personnalisée?",
3379
3278
  "use_simplified_home_office": "Utiliser la déduction simplifiée pour bureau à domicile?",
3380
3279
  "use_standard_mileage_deduction": "Utiliser la déduction forfaitaire kilométrique?",
3381
- "w2_income": "Revenu W-2",
3382
3280
  "withholding_amount": "Montant de la retenue",
3383
3281
  "year_to_date": "Cumul annuel",
3384
3282
  "your_tax_deadlines": "Vos échéances fiscales"
@@ -13195,6 +13093,7 @@ let ReportControl = /* @__PURE__ */ function(ReportControl$1) {
13195
13093
  ReportControl$1["Date"] = "date";
13196
13094
  ReportControl$1["DateRange"] = "date_range";
13197
13095
  ReportControl$1["GroupBy"] = "group_by";
13096
+ ReportControl$1["Year"] = "year";
13198
13097
  ReportControl$1["Unknown"] = "unknown";
13199
13098
  return ReportControl$1;
13200
13099
  }({});
@@ -18998,6 +18897,29 @@ const CategorizationRulesMobileList = ({ data, isLoading, isError, paginationPro
18998
18897
  })
18999
18898
  });
19000
18899
  };
18900
+ function useHorizontalOverflow(elementRef, options = { dependencies: [] }) {
18901
+ const { dependencies: dependencies$1 = [] } = options;
18902
+ const [hasHorizontalOverflow, setHasHorizontalOverflow] = useState(false);
18903
+ const updateHorizontalOverflow = useCallback(() => {
18904
+ const element = elementRef.current;
18905
+ if (!element) return;
18906
+ setHasHorizontalOverflow(Math.ceil(element.scrollWidth) > Math.ceil(element.clientWidth));
18907
+ }, [elementRef, ...dependencies$1]);
18908
+ useResizeObserver(elementRef, updateHorizontalOverflow);
18909
+ useEffect(() => {
18910
+ var _elementRef$current;
18911
+ const element = (_elementRef$current = elementRef.current) === null || _elementRef$current === void 0 ? void 0 : _elementRef$current.firstElementChild;
18912
+ if (!element) return;
18913
+ const observer = new ResizeObserver(() => updateHorizontalOverflow());
18914
+ observer.observe(element);
18915
+ return () => observer.disconnect();
18916
+ }, [elementRef, updateHorizontalOverflow]);
18917
+ useEffect(() => {
18918
+ const id = requestAnimationFrame(() => updateHorizontalOverflow());
18919
+ return () => cancelAnimationFrame(id);
18920
+ }, [updateHorizontalOverflow]);
18921
+ return hasHorizontalOverflow;
18922
+ }
19001
18923
  var WIDTH_CHANGE_THRESHOLD_PX = .5;
19002
18924
  var getLeafHeaderCells = (header) => {
19003
18925
  const leafRow = header === null || header === void 0 ? void 0 : header.lastElementChild;
@@ -19043,9 +18965,42 @@ const useColumnPinningStyles = (headerGroups) => {
19043
18965
  pinningStyles: useMemo(() => computePinningStyles(headerGroups, headerWidths), [headerGroups, headerWidths])
19044
18966
  };
19045
18967
  };
18968
+ const DataTableHeaderSkeleton = ({ nonAria, numColumns = 3 }) => {
18969
+ const resolvedNumColumns = numColumns > 0 ? numColumns : 3;
18970
+ return /* @__PURE__ */ jsx(Row$1, {
18971
+ nonAria,
18972
+ children: Array.from({ length: resolvedNumColumns }).map((_, index) => /* @__PURE__ */ jsx(Column$1, {
18973
+ nonAria,
18974
+ children: /* @__PURE__ */ jsx(SkeletonLoader, {
18975
+ width: index === 0 ? "60%" : "40%",
18976
+ height: "12px"
18977
+ })
18978
+ }, `loading-header-${index}`))
18979
+ });
18980
+ };
18981
+ const DataTableSkeleton = ({ numColumns, nonAria }) => {
18982
+ const resolvedNumColumns = numColumns > 0 ? numColumns : 3;
18983
+ const loadingColumns = useMemo(() => Array.from({ length: resolvedNumColumns }, (_, index) => ({ index })), [resolvedNumColumns]);
18984
+ return /* @__PURE__ */ jsx(Fragment$1, { children: Array.from({ length: 6 }).map((_, rowIndex) => /* @__PURE__ */ jsx(Row$1, {
18985
+ nonAria,
18986
+ children: loadingColumns.map((column) => {
18987
+ return /* @__PURE__ */ jsx(Cell$2, {
18988
+ className: "Layer__skeleton-loader__row",
18989
+ nonAria,
18990
+ children: /* @__PURE__ */ jsx(SkeletonLoader, {
18991
+ width: `${100 - (column.index === 0 && rowIndex >= 3 ? (rowIndex - 2) * 10 : 0)}%`,
18992
+ height: "20px"
18993
+ })
18994
+ }, `loading-${rowIndex}-${column.index}`);
18995
+ })
18996
+ }, `loading-${rowIndex}`)) });
18997
+ };
19046
18998
  const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, dependencies: dependencies$1, data, headerGroups, numColumns, withClickableRow }) => {
19047
- const nonAria = headerGroups.length > 1;
18999
+ const scrollContainerRef = useRef(null);
19000
+ const nonAria = headerGroups.length > 1 || numColumns === 0;
19048
19001
  const { EmptyState: EmptyState$8, ErrorState: ErrorState$9 } = slots;
19002
+ const hasHorizontalOverflow = useHorizontalOverflow(scrollContainerRef, { dependencies: [data, numColumns] });
19003
+ const showLoadingFallbackHeaders = isLoading && numColumns === 0;
19049
19004
  const { headerRef, pinningStyles } = useColumnPinningStyles(headerGroups);
19050
19005
  const isEmptyTable = (data === null || data === void 0 ? void 0 : data.length) === 0;
19051
19006
  const renderTableBody = useMemo(() => {
@@ -19059,15 +19014,9 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
19059
19014
  children: /* @__PURE__ */ jsx(ErrorState$9, {})
19060
19015
  })
19061
19016
  });
19062
- if (isLoading) return /* @__PURE__ */ jsx(Row$1, {
19063
- className: "Layer__DataTable__EmptyState__Row",
19064
- nonAria,
19065
- children: /* @__PURE__ */ jsx(Cell$2, {
19066
- className: "Layer__DataTable__EmptyState__Cell",
19067
- colSpan: numColumns,
19068
- nonAria,
19069
- children: /* @__PURE__ */ jsx(Loader, {})
19070
- })
19017
+ if (isLoading) return /* @__PURE__ */ jsx(DataTableSkeleton, {
19018
+ numColumns,
19019
+ nonAria
19071
19020
  });
19072
19021
  if (isEmptyTable) return /* @__PURE__ */ jsx(Row$1, {
19073
19022
  className: "Layer__DataTable__EmptyState__Row",
@@ -19114,7 +19063,8 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
19114
19063
  pinningStyles
19115
19064
  ]);
19116
19065
  return /* @__PURE__ */ jsx("div", {
19117
- className: "Layer__UI__Table-ScrollContainer",
19066
+ ref: scrollContainerRef,
19067
+ className: classNames("Layer__UI__Table-ScrollContainer", hasHorizontalOverflow && "Layer__UI__Table-ScrollContainer--has-horizontal-overflow"),
19118
19068
  children: /* @__PURE__ */ jsxs(Table$2, {
19119
19069
  "aria-label": ariaLabel,
19120
19070
  className: `Layer__UI__Table__${componentName}`,
@@ -19122,7 +19072,10 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
19122
19072
  children: [/* @__PURE__ */ jsx(TableHeader$1, {
19123
19073
  ref: headerRef,
19124
19074
  nonAria,
19125
- children: headerGroups.map((headerGroup) => /* @__PURE__ */ jsx(Row$1, {
19075
+ children: showLoadingFallbackHeaders ? /* @__PURE__ */ jsx(DataTableHeaderSkeleton, {
19076
+ nonAria,
19077
+ numColumns: 3
19078
+ }) : headerGroups.map((headerGroup) => /* @__PURE__ */ jsx(Row$1, {
19126
19079
  nonAria,
19127
19080
  children: headerGroup.headers.map((header) => {
19128
19081
  var _header$column$column, _header$column$column2;
@@ -19143,7 +19096,7 @@ const DataTable = ({ isLoading, isError, componentName, ariaLabel, slots, depend
19143
19096
  nonAria,
19144
19097
  children: renderTableBody
19145
19098
  })]
19146
- })
19099
+ }, `${componentName}-cols-${numColumns}`)
19147
19100
  });
19148
19101
  };
19149
19102
  function PaginatedTable({ data, isLoading, isError, columnConfig, componentName, ariaLabel, paginationProps, slots }) {
@@ -27034,7 +26987,6 @@ const LEDGER_ACCOUNT_TYPES_CONFIG = [
27034
26987
  _objectSpread2({ value: "REVENUE" }, translationKey("common:label.revenue", "Revenue")),
27035
26988
  _objectSpread2({ value: "EXPENSE" }, translationKey("common:label.expenses", "Expenses"))
27036
26989
  ];
27037
- Direction.DEBIT, Direction.CREDIT, Direction.CREDIT, Direction.CREDIT, Direction.DEBIT;
27038
26990
  const NORMALITY_CONFIG = [_objectSpread2({ value: Direction.DEBIT }, translationKey("common:label.debit", "Debit")), _objectSpread2({ value: Direction.CREDIT }, translationKey("common:label.credit", "Credit"))];
27039
26991
  const ASSET_LEDGER_ACCOUNT_SUBTYPES_CONFIG = [
27040
26992
  _objectSpread2({ value: "BANK_ACCOUNTS" }, translationKey("chartOfAccounts:label.bank_accounts", "Bank Accounts")),
@@ -27594,134 +27546,6 @@ const ChartOfAccountsContext = createContext({
27594
27546
  changeFormData: () => {},
27595
27547
  submitForm: () => {}
27596
27548
  });
27597
- var _excluded$22 = ["size"];
27598
- var Plus$1 = (_ref) => {
27599
- let { size = 14 } = _ref;
27600
- return /* @__PURE__ */ jsxs("svg", _objectSpread2(_objectSpread2({
27601
- xmlns: "http://www.w3.org/2000/svg",
27602
- viewBox: "0 0 14 14",
27603
- fill: "none"
27604
- }, _objectWithoutProperties(_ref, _excluded$22)), {}, {
27605
- width: size,
27606
- height: size,
27607
- children: [/* @__PURE__ */ jsx("path", {
27608
- d: "M7 2.91602V11.0827",
27609
- stroke: "currentColor",
27610
- strokeLinecap: "round",
27611
- strokeLinejoin: "round"
27612
- }), /* @__PURE__ */ jsx("path", {
27613
- d: "M2.91669 7H11.0834",
27614
- stroke: "currentColor",
27615
- strokeLinecap: "round",
27616
- strokeLinejoin: "round"
27617
- })]
27618
- }));
27619
- };
27620
- var Plus_default = Plus$1;
27621
- var Collapse = (_ref) => {
27622
- return /* @__PURE__ */ jsxs("svg", _objectSpread2(_objectSpread2({
27623
- xmlns: "http://www.w3.org/2000/svg",
27624
- width: "14",
27625
- height: "22",
27626
- viewBox: "0 0 14 22",
27627
- fill: "none"
27628
- }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ jsx("path", {
27629
- d: "M3.5 5.25L7 8.75L10.5 5.25",
27630
- stroke: "currentColor",
27631
- strokeLinecap: "round",
27632
- strokeLinejoin: "round"
27633
- }), /* @__PURE__ */ jsx("path", {
27634
- d: "M3.5 16.75L7 13.25L10.5 16.75",
27635
- stroke: "currentColor",
27636
- strokeLinecap: "round",
27637
- strokeLinejoin: "round"
27638
- })] }));
27639
- };
27640
- var Collapse_default = Collapse;
27641
- var Expand = (_ref) => {
27642
- return /* @__PURE__ */ jsxs("svg", _objectSpread2(_objectSpread2({
27643
- xmlns: "http://www.w3.org/2000/svg",
27644
- width: "14",
27645
- height: "22",
27646
- viewBox: "0 0 14 22",
27647
- fill: "none"
27648
- }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ jsx("path", {
27649
- d: "M10.5 8.75L7 5.25L3.5 8.75",
27650
- stroke: "currentColor",
27651
- strokeLinecap: "round",
27652
- strokeLinejoin: "round"
27653
- }), /* @__PURE__ */ jsx("path", {
27654
- d: "M3.5 13.25L7 16.75L10.5 13.25",
27655
- stroke: "currentColor",
27656
- strokeLinecap: "round",
27657
- strokeLinejoin: "round"
27658
- })] }));
27659
- };
27660
- var Expand_default = Expand;
27661
- const ExpandCollapseButton = ({ onClick, expanded, className, iconOnly, variant }) => {
27662
- const { t } = useTranslation();
27663
- return /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Button$2, {
27664
- onClick: () => onClick(!expanded),
27665
- variant: variant ? variant : ButtonVariant.secondary,
27666
- className: classNames(iconOnly ? "Layer__expand-collapse-all-rows-btn--sm" : "Layer__expand-collapse-all-rows-btn", className),
27667
- rightIcon: !iconOnly ? null : expanded ? /* @__PURE__ */ jsx(Collapse_default, {}) : /* @__PURE__ */ jsx(Expand_default, {}),
27668
- iconAsPrimary: iconOnly,
27669
- iconOnly,
27670
- children: iconOnly ? null : !expanded ? t("reports:action.expand_rows", "Expand all rows") : t("reports:action.collapse_rows", "Collapse all rows")
27671
- }) });
27672
- };
27673
- var getLedgerAccountBalancesCSV = get(({ businessId }) => `/v1/businesses/${businessId}/ledger/balances/exports/csv`);
27674
- function buildKey$51({ access_token: accessToken, apiUrl, businessId, startCutoff, endCutoff }) {
27675
- if (accessToken && apiUrl) return {
27676
- accessToken,
27677
- apiUrl,
27678
- businessId,
27679
- startCutoff,
27680
- endCutoff,
27681
- tags: [
27682
- "#account-balances",
27683
- "#exports",
27684
- "#csv"
27685
- ]
27686
- };
27687
- }
27688
- function useAccountBalancesDownload({ startCutoff, endCutoff, onSuccess }) {
27689
- const withLocale = useLocalizedKey();
27690
- const { data: auth } = useAuth();
27691
- const { businessId } = useLayerContext();
27692
- return useSWRMutation(() => withLocale(buildKey$51(_objectSpread2(_objectSpread2({}, auth), {}, {
27693
- businessId,
27694
- startCutoff,
27695
- endCutoff
27696
- }))), ({ accessToken, apiUrl, businessId: businessId$1, startCutoff: startCutoff$1, endCutoff: endCutoff$1 }) => getLedgerAccountBalancesCSV(apiUrl, accessToken, { params: {
27697
- businessId: businessId$1,
27698
- startCutoff: startCutoff$1 === null || startCutoff$1 === void 0 ? void 0 : startCutoff$1.toISOString(),
27699
- endCutoff: endCutoff$1 === null || endCutoff$1 === void 0 ? void 0 : endCutoff$1.toISOString()
27700
- } })().then(({ data }) => {
27701
- if (onSuccess) return onSuccess(data);
27702
- }), {
27703
- revalidate: false,
27704
- throwOnError: false
27705
- });
27706
- }
27707
- function AccountBalancesDownloadButton({ startCutoff, endCutoff, iconOnly }) {
27708
- const { t } = useTranslation();
27709
- const { invisibleDownloadRef, triggerInvisibleDownload } = useInvisibleDownload();
27710
- const { trigger, isMutating, error: error$38 } = useAccountBalancesDownload({
27711
- startCutoff,
27712
- endCutoff,
27713
- onSuccess: ({ presignedUrl }) => triggerInvisibleDownload({ url: presignedUrl })
27714
- });
27715
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DownloadButton, {
27716
- iconOnly,
27717
- onClick: () => {
27718
- trigger();
27719
- },
27720
- isDownloading: isMutating,
27721
- requestFailed: Boolean(error$38),
27722
- text: t("common:action.download_csv", "Download CSV")
27723
- }), /* @__PURE__ */ jsx(InvisibleDownload_default, { ref: invisibleDownloadRef })] });
27724
- }
27725
27549
  const useParentOptions = (data) => 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) => {
27726
27550
  return {
27727
27551
  label: x.name,
@@ -27912,23 +27736,20 @@ const ChartOfAccountsForm = ({ stringOverrides }) => {
27912
27736
  ]
27913
27737
  });
27914
27738
  };
27915
- const ChartOfAccountsSidebar = ({ parentRef: _parentRef, stringOverrides }) => {
27916
- return /* @__PURE__ */ jsx(ChartOfAccountsForm, { stringOverrides });
27917
- };
27918
27739
  let LedgerAccountNodeType = /* @__PURE__ */ function(LedgerAccountNodeType$1) {
27919
27740
  LedgerAccountNodeType$1["Leaf"] = "Leaf";
27920
27741
  LedgerAccountNodeType$1["Root"] = "Root";
27921
27742
  LedgerAccountNodeType$1["Parent"] = "Parent";
27922
27743
  return LedgerAccountNodeType$1;
27923
27744
  }({});
27924
- var _excluded$21 = ["size"];
27745
+ var _excluded$22 = ["size"];
27925
27746
  var Edit2 = (_ref) => {
27926
27747
  let { size = 18 } = _ref;
27927
27748
  return /* @__PURE__ */ jsx("svg", _objectSpread2(_objectSpread2({
27928
27749
  xmlns: "http://www.w3.org/2000/svg",
27929
27750
  viewBox: "0 0 18 18",
27930
27751
  fill: "none"
27931
- }, _objectWithoutProperties(_ref, _excluded$21)), {}, {
27752
+ }, _objectWithoutProperties(_ref, _excluded$22)), {}, {
27932
27753
  width: size,
27933
27754
  height: size,
27934
27755
  children: /* @__PURE__ */ jsx("path", {
@@ -27963,6 +27784,20 @@ const filterAccounts = (accounts, query, formatCurrencyFromCents$1) => {
27963
27784
  return [];
27964
27785
  });
27965
27786
  };
27787
+ const getRowId$2 = (row) => row.accountId;
27788
+ const getInitialExpandedState = (accounts) => {
27789
+ const expandedState = {};
27790
+ if (!accounts) return expandedState;
27791
+ const collectExpanded = (nestedAccounts, depth) => {
27792
+ for (const account of nestedAccounts) {
27793
+ if (!(account.subAccounts.length > 0)) continue;
27794
+ if (depth === 0 || account.isMatching) expandedState[getRowId$2(account)] = true;
27795
+ collectExpanded(account.subAccounts, depth + 1);
27796
+ }
27797
+ };
27798
+ collectExpanded(accounts, 0);
27799
+ return expandedState;
27800
+ };
27966
27801
  var skippedChars = ["$", ","];
27967
27802
  const getMatchedTextIndices = ({ text, query, isMatching }) => {
27968
27803
  if (!query || !isMatching) return null;
@@ -27988,6 +27823,121 @@ const getMatchedTextIndices = ({ text, query, isMatching }) => {
27988
27823
  endIdx: matchEndIdx
27989
27824
  };
27990
27825
  };
27826
+ const ExpandableDataTableContext = createContext({
27827
+ expanded: {},
27828
+ setExpanded: () => {}
27829
+ });
27830
+ function ExpandableDataTableProvider({ children }) {
27831
+ const [expanded, setExpanded] = useState({});
27832
+ const value = useMemo(() => ({
27833
+ expanded,
27834
+ setExpanded
27835
+ }), [expanded]);
27836
+ return /* @__PURE__ */ jsx(ExpandableDataTableContext.Provider, {
27837
+ value,
27838
+ children
27839
+ });
27840
+ }
27841
+ var baseClassName = "Layer__ExpandButton";
27842
+ const ExpandButton = ({ isExpanded }) => {
27843
+ return /* @__PURE__ */ jsx(ChevronDownFill_default, {
27844
+ className: classNames(baseClassName, `${baseClassName}--${isExpanded ? "expanded" : "collapsed"}`),
27845
+ size: 16,
27846
+ "aria-label": isExpanded ? "Collapse row" : "Expand row"
27847
+ });
27848
+ };
27849
+ var INDENT_SIZE_XS = 10;
27850
+ var INDENT_SIZE_SM = 20;
27851
+ var INDENT_SIZE_MD = 40;
27852
+ var CHEVRON_OFFSET_PX = 4;
27853
+ var getRowIndentStyle = ({ depth, canExpand, indentSizePx }) => ({
27854
+ paddingInlineStart: depth * indentSizePx + (canExpand ? 0 : CHEVRON_OFFSET_PX),
27855
+ overflow: "hidden"
27856
+ });
27857
+ var EMPTY_ARRAY$2 = [];
27858
+ function ExpandableDataTable({ data, isLoading, isError, columnConfig, componentName, ariaLabel, slots, getSubRows: getSubRows$4, getRowId: getRowId$3, indentSize = "sm" }) {
27859
+ const { expanded, setExpanded } = useContext(ExpandableDataTableContext);
27860
+ const wrappedColumnConfig = useMemo(() => {
27861
+ const indentSizePx = indentSize === "xs" ? INDENT_SIZE_XS : indentSize === "md" ? INDENT_SIZE_MD : INDENT_SIZE_SM;
27862
+ const [first, ...rest] = columnConfig;
27863
+ if (!first || !isLeafColumn(first)) return columnConfig;
27864
+ const cellRenderer = first.cell;
27865
+ return [_objectSpread2(_objectSpread2({}, first), {}, { cell: (row) => {
27866
+ const canExpand = row.getCanExpand();
27867
+ const rowIndentStyle = getRowIndentStyle({
27868
+ canExpand,
27869
+ depth: row.depth,
27870
+ indentSizePx
27871
+ });
27872
+ if (!canExpand) return /* @__PURE__ */ jsx("div", {
27873
+ style: rowIndentStyle,
27874
+ children: cellRenderer(row)
27875
+ });
27876
+ return /* @__PURE__ */ jsx("div", {
27877
+ style: rowIndentStyle,
27878
+ children: /* @__PURE__ */ jsxs(HStack, {
27879
+ align: "center",
27880
+ gap: "xs",
27881
+ children: [/* @__PURE__ */ jsx(ExpandButton, { isExpanded: row.getIsExpanded() }), cellRenderer(row)]
27882
+ })
27883
+ });
27884
+ } }), ...rest];
27885
+ }, [columnConfig, indentSize]);
27886
+ const columnDefs = getColumnDefs(wrappedColumnConfig);
27887
+ const columnPinning = useMemo(() => getColumnPinning(wrappedColumnConfig), [wrappedColumnConfig]);
27888
+ const table$1 = useReactTable({
27889
+ data: data !== null && data !== void 0 ? data : EMPTY_ARRAY$2,
27890
+ columns: columnDefs,
27891
+ getSubRows: getSubRows$4,
27892
+ getCoreRowModel: getCoreRowModel(),
27893
+ getExpandedRowModel: getExpandedRowModel(),
27894
+ state: {
27895
+ expanded,
27896
+ columnPinning
27897
+ },
27898
+ onExpandedChange: setExpanded,
27899
+ autoResetPageIndex: false,
27900
+ getRowId: getRowId$3
27901
+ });
27902
+ const { rows } = table$1.getExpandedRowModel();
27903
+ const dependencies$1 = useMemo(() => [expanded], [expanded]);
27904
+ const headerGroups = table$1.getHeaderGroups();
27905
+ const numColumns = table$1.getVisibleLeafColumns().length;
27906
+ const isRowClickable = useCallback((row) => {
27907
+ return row.getCanExpand();
27908
+ }, []);
27909
+ const onRowClick = useCallback((row) => {
27910
+ row.toggleExpanded();
27911
+ }, []);
27912
+ return /* @__PURE__ */ jsx(DataTable, {
27913
+ ariaLabel,
27914
+ numColumns,
27915
+ data: rows,
27916
+ isLoading,
27917
+ isError,
27918
+ componentName,
27919
+ slots,
27920
+ dependencies: dependencies$1,
27921
+ headerGroups,
27922
+ withClickableRow: useMemo(() => ({
27923
+ onRowClick,
27924
+ isRowClickable
27925
+ }), [onRowClick, isRowClickable])
27926
+ });
27927
+ }
27928
+ var ChartOfAccountsColumn = /* @__PURE__ */ function(ChartOfAccountsColumn$1) {
27929
+ ChartOfAccountsColumn$1["AccountNumber"] = "AccountNumber";
27930
+ ChartOfAccountsColumn$1["Name"] = "Name";
27931
+ ChartOfAccountsColumn$1["Type"] = "Type";
27932
+ ChartOfAccountsColumn$1["Subtype"] = "Subtype";
27933
+ ChartOfAccountsColumn$1["Balance"] = "Balance";
27934
+ ChartOfAccountsColumn$1["Actions"] = "Actions";
27935
+ return ChartOfAccountsColumn$1;
27936
+ }(ChartOfAccountsColumn || {});
27937
+ var COMPONENT_NAME$8 = "chart-of-accounts";
27938
+ var getSubRows$3 = (row) => {
27939
+ return row.subAccounts.length > 0 ? asMutable(row.subAccounts) : void 0;
27940
+ };
27991
27941
  var highlightMatch = ({ text, query, isMatching }) => {
27992
27942
  const matchedTextIndices = getMatchedTextIndices({
27993
27943
  text,
@@ -28011,41 +27961,36 @@ var highlightMatch = ({ text, query, isMatching }) => {
28011
27961
  ]
28012
27962
  });
28013
27963
  };
28014
- const ChartOfAccountsTable = ({ view, stringOverrides, data, searchQuery, expandAll, templateAccountsEditable = true }) => /* @__PURE__ */ jsx(TableProvider, { children: /* @__PURE__ */ jsx(ChartOfAccountsTableContent, {
28015
- view,
28016
- data,
28017
- searchQuery,
28018
- stringOverrides,
28019
- expandAll,
28020
- templateAccountsEditable
28021
- }) });
28022
- const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expandAll, templateAccountsEditable }) => {
27964
+ var ChartOfAccountsEmptyState = () => {
27965
+ const { t } = useTranslation();
27966
+ return /* @__PURE__ */ jsx(DataState, {
27967
+ status: DataStateStatus.info,
27968
+ title: t("chartOfAccounts:empty.accounts", "No accounts found"),
27969
+ description: t("chartOfAccounts:empty.accounts_match_filters", "No accounts match the current filters. Click \"Add Account\" to create a new one."),
27970
+ spacing: true
27971
+ });
27972
+ };
27973
+ var ChartOfAccountsErrorState = () => {
27974
+ const { t } = useTranslation();
27975
+ const { refetch, isValidating, isLoading } = useContext(ChartOfAccountsContext);
27976
+ return /* @__PURE__ */ jsx(DataState, {
27977
+ status: DataStateStatus.failed,
27978
+ title: t("common:error.something_went_wrong", "Something went wrong"),
27979
+ description: t("common:error.couldnt_load_data", "We couldn’t load your data."),
27980
+ onRefresh: () => void refetch(),
27981
+ isLoading: isValidating || isLoading,
27982
+ spacing: true
27983
+ });
27984
+ };
27985
+ const ChartOfAccountsTable = ({ stringOverrides, searchQuery, templateAccountsEditable = true }) => {
28023
27986
  const { t } = useTranslation();
28024
27987
  const { formatCurrencyFromCents: formatCurrencyFromCents$1 } = useIntlFormatter();
28025
27988
  const { setSelectedAccount } = useContext(LedgerAccountsContext);
28026
- const { editAccount, deleteAccount, isError } = useContext(ChartOfAccountsContext);
28027
- const [toggledKeys, setToggledKeys] = useState({});
27989
+ const { setExpanded } = useContext(ExpandableDataTableContext);
27990
+ const { data, isLoading, isError, editAccount, deleteAccount } = useContext(ChartOfAccountsContext);
28028
27991
  const [accountToDelete, setAccountToDelete] = useState(null);
28029
27992
  const { accountingConfiguration } = useLayerContext();
28030
27993
  const enableAccountNumbers = !!(accountingConfiguration === null || accountingConfiguration === void 0 ? void 0 : accountingConfiguration.enableAccountNumbers);
28031
- const allRowKeys = useMemo(() => {
28032
- const keys = [];
28033
- const collect = (accounts) => {
28034
- for (const account of accounts) {
28035
- const key = `coa-row-${account.accountId}`;
28036
- if (account.subAccounts.length > 0) {
28037
- keys.push(key);
28038
- collect(account.subAccounts);
28039
- }
28040
- }
28041
- };
28042
- collect(data.accounts);
28043
- return keys;
28044
- }, [data.accounts]);
28045
- useEffect(() => {
28046
- if (expandAll === void 0) return;
28047
- setToggledKeys(Object.fromEntries(allRowKeys.map((key) => [key, expandAll === "expanded"])));
28048
- }, [allRowKeys, expandAll]);
28049
27994
  const onConfirmDelete = function() {
28050
27995
  var _ref = _asyncToGenerator(function* () {
28051
27996
  if (!accountToDelete) return;
@@ -28055,109 +28000,106 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
28055
28000
  return _ref.apply(this, arguments);
28056
28001
  };
28057
28002
  }();
28058
- const getDeleteButtonTooltip = (account) => {
28003
+ const getDeleteButtonTooltip = useCallback((account) => {
28059
28004
  if (account.isDeletable) return;
28060
28005
  if (account.subAccounts.length > 0) return t("chartOfAccounts:validation.delete_account_has_children", "This account cannot be deleted because it has child accounts");
28061
28006
  if (account.balance !== 0) return t("chartOfAccounts:validation.delete_account_has_ledger_entries", "This account cannot be deleted because it has ledger entries");
28062
28007
  return t("chartOfAccounts:validation.delete_account_is_required", "This account cannot be deleted because it is a required account");
28063
- };
28064
- useEffect(() => {
28065
- setToggledKeys({});
28066
- }, [searchQuery]);
28008
+ }, [t]);
28067
28009
  const filteredAccounts = useMemo(() => {
28010
+ if (!data) return void 0;
28068
28011
  if (!searchQuery) return data.accounts;
28069
28012
  return filterAccounts(asMutable(data.accounts), searchQuery.toLowerCase(), formatCurrencyFromCents$1);
28070
28013
  }, [
28071
- data.accounts,
28014
+ data,
28072
28015
  formatCurrencyFromCents$1,
28073
28016
  searchQuery
28074
28017
  ]);
28075
- const renderChartOfAccountsDesktopRow = ({ account, index, depth, searchQuery: searchQuery$1 }) => {
28076
- var _account$accountType, _account$accountSubty;
28077
- const rowKey = `coa-row-${account.accountId}`;
28078
- const hasSubAccounts = !!account.subAccounts && account.subAccounts.length > 0;
28079
- const nodeType = depth === 0 ? LedgerAccountNodeType.Root : hasSubAccounts ? LedgerAccountNodeType.Parent : LedgerAccountNodeType.Leaf;
28080
- const manuallyToggled = toggledKeys[rowKey];
28081
- const isExpanded = !hasSubAccounts || manuallyToggled === true || manuallyToggled !== false && (account.isMatching || depth === 0);
28082
- const isNonEditable = !templateAccountsEditable && !!account.stableName;
28083
- const isDeleteDisabled = !account.isDeletable;
28084
- const onClickRow = (e) => {
28085
- e.stopPropagation();
28086
- if (!hasSubAccounts) return;
28087
- setToggledKeys((prev) => _objectSpread2(_objectSpread2({}, prev), {}, { [rowKey]: !isExpanded }));
28088
- };
28089
- const onClickAccountName = (e) => {
28090
- e.stopPropagation();
28091
- setSelectedAccount(_objectSpread2(_objectSpread2({}, account), {}, { nodeType }));
28092
- };
28093
- const onClickEdit = (e) => {
28094
- e.preventDefault();
28095
- e.stopPropagation();
28096
- editAccount(account.accountId);
28097
- };
28098
- const onClickView = (e) => {
28099
- e.preventDefault();
28100
- e.stopPropagation();
28101
- setSelectedAccount(_objectSpread2(_objectSpread2({}, account), {}, { nodeType }));
28102
- };
28103
- const onClickDelete = (e) => {
28104
- e.preventDefault();
28105
- e.stopPropagation();
28106
- setAccountToDelete(account);
28018
+ useLayoutEffect(() => {
28019
+ setExpanded(getInitialExpandedState(filteredAccounts));
28020
+ }, [filteredAccounts, setExpanded]);
28021
+ const getNodeType = (row) => {
28022
+ if (row.depth === 0) return LedgerAccountNodeType.Root;
28023
+ return row.getCanExpand() ? LedgerAccountNodeType.Parent : LedgerAccountNodeType.Leaf;
28024
+ };
28025
+ const onClickView = useCallback((row, e) => {
28026
+ e.preventDefault();
28027
+ e.stopPropagation();
28028
+ setSelectedAccount(_objectSpread2(_objectSpread2({}, row.original), {}, { nodeType: getNodeType(row) }));
28029
+ }, [setSelectedAccount]);
28030
+ const onClickEdit = useCallback((account, e) => {
28031
+ e.preventDefault();
28032
+ e.stopPropagation();
28033
+ editAccount(account.accountId);
28034
+ }, [editAccount]);
28035
+ const onClickDelete = (account, e) => {
28036
+ e.preventDefault();
28037
+ e.stopPropagation();
28038
+ setAccountToDelete(account);
28039
+ };
28040
+ const renderHighlightedValue = useCallback((row, text) => {
28041
+ return highlightMatch({
28042
+ text,
28043
+ query: searchQuery,
28044
+ isMatching: row.original.isMatching
28045
+ });
28046
+ }, [searchQuery]);
28047
+ const renderHighlightedNonRootValue = useCallback((row, text) => {
28048
+ if (row.depth === 0) return null;
28049
+ return renderHighlightedValue(row, text);
28050
+ }, [renderHighlightedValue]);
28051
+ const slots = useMemo(() => ({
28052
+ EmptyState: ChartOfAccountsEmptyState,
28053
+ ErrorState: ChartOfAccountsErrorState
28054
+ }), []);
28055
+ const columnConfig = useMemo(() => {
28056
+ const accountNumberColumn = {
28057
+ id: ChartOfAccountsColumn.AccountNumber,
28058
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.numberColumnHeader) || t("generalLedger:label.account_number", "Account Number"),
28059
+ cell: (row) => renderHighlightedValue(row, row.original.accountNumber || "")
28107
28060
  };
28108
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(TableRow, {
28109
- rowKey: rowKey + "-" + index,
28110
- expandable: hasSubAccounts,
28111
- isExpanded,
28112
- onClick: onClickRow,
28113
- depth,
28114
- variant: depth === 0 ? "expandable" : "default",
28115
- children: [
28116
- enableAccountNumbers && /* @__PURE__ */ jsx(TableCell, {
28117
- withExpandIcon: hasSubAccounts,
28118
- children: /* @__PURE__ */ jsx(HStack, _objectSpread2(_objectSpread2({}, !hasSubAccounts && { pis: "lg" }), {}, {
28119
- overflow: "hidden",
28120
- children: enableAccountNumbers && highlightMatch({
28121
- text: account.accountNumber || "",
28122
- query: searchQuery$1,
28123
- isMatching: account.isMatching
28124
- })
28125
- }))
28126
- }),
28127
- /* @__PURE__ */ jsx(TableCell, {
28128
- withExpandIcon: hasSubAccounts && !enableAccountNumbers,
28129
- children: /* @__PURE__ */ jsx(HStack, _objectSpread2(_objectSpread2({}, !hasSubAccounts && !enableAccountNumbers ? { pis: "lg" } : {}), {}, {
28130
- overflow: "hidden",
28131
- children: /* @__PURE__ */ jsx(Button$1, {
28132
- variant: "text",
28133
- ellipsis: true,
28134
- onClick: onClickAccountName,
28135
- children: highlightMatch({
28136
- text: account.name,
28137
- query: searchQuery$1,
28138
- isMatching: account.isMatching
28139
- })
28140
- })
28141
- }))
28061
+ const columns = [
28062
+ {
28063
+ id: ChartOfAccountsColumn.Name,
28064
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.nameColumnHeader) || t("generalLedger:label.account_name_title_case", "Account Name"),
28065
+ cell: (row) => /* @__PURE__ */ jsx(Button$1, {
28066
+ variant: "text",
28067
+ ellipsis: true,
28068
+ onClick: (e) => onClickView(row, e),
28069
+ children: renderHighlightedValue(row, row.original.name)
28142
28070
  }),
28143
- /* @__PURE__ */ jsx(TableCell, { children: depth != 0 && highlightMatch({
28144
- text: ((_account$accountType = account.accountType) === null || _account$accountType === void 0 ? void 0 : _account$accountType.displayName) || "",
28145
- query: searchQuery$1,
28146
- isMatching: account.isMatching
28147
- }) }),
28148
- /* @__PURE__ */ jsx(TableCell, { children: depth != 0 && highlightMatch({
28149
- text: ((_account$accountSubty = account.accountSubtype) === null || _account$accountSubty === void 0 ? void 0 : _account$accountSubty.displayName) || "",
28150
- query: searchQuery$1,
28151
- isMatching: account.isMatching
28152
- }) }),
28153
- /* @__PURE__ */ jsx(TableCell, { children: highlightMatch({
28154
- text: formatCurrencyFromCents$1(account.balance),
28155
- query: searchQuery$1,
28156
- isMatching: account.isMatching
28157
- }) }),
28158
- /* @__PURE__ */ jsx(TableCell, {
28159
- align: TableCellAlign.RIGHT,
28160
- children: /* @__PURE__ */ jsxs(HStack, {
28071
+ isRowHeader: true
28072
+ },
28073
+ {
28074
+ id: ChartOfAccountsColumn.Type,
28075
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.typeColumnHeader) || t("common:label.type", "Type"),
28076
+ cell: (row) => {
28077
+ var _row$original$account;
28078
+ return renderHighlightedNonRootValue(row, ((_row$original$account = row.original.accountType) === null || _row$original$account === void 0 ? void 0 : _row$original$account.displayName) || "");
28079
+ }
28080
+ },
28081
+ {
28082
+ id: ChartOfAccountsColumn.Subtype,
28083
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.subtypeColumnHeader) || t("chartOfAccounts:label.sub_type", "Sub-Type"),
28084
+ cell: (row) => {
28085
+ var _row$original$account2;
28086
+ return renderHighlightedNonRootValue(row, ((_row$original$account2 = row.original.accountSubtype) === null || _row$original$account2 === void 0 ? void 0 : _row$original$account2.displayName) || "");
28087
+ }
28088
+ },
28089
+ {
28090
+ id: ChartOfAccountsColumn.Balance,
28091
+ header: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.balanceColumnHeader) || t("common:label.balance", "Balance"),
28092
+ cell: (row) => renderHighlightedValue(row, formatCurrencyFromCents$1(row.original.balance))
28093
+ },
28094
+ {
28095
+ id: ChartOfAccountsColumn.Actions,
28096
+ header: null,
28097
+ alignment: Alignment.Right,
28098
+ cell: (row) => {
28099
+ const account = row.original;
28100
+ const isNonEditable = !templateAccountsEditable && !!account.stableName;
28101
+ const isDeleteDisabled = !account.isDeletable;
28102
+ return /* @__PURE__ */ jsxs(HStack, {
28161
28103
  className: "Layer__coa__actions",
28162
28104
  gap: "xs",
28163
28105
  children: [
@@ -28165,7 +28107,7 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
28165
28107
  variant: ButtonVariant.secondary,
28166
28108
  rightIcon: /* @__PURE__ */ jsx(List, { size: 14 }),
28167
28109
  iconOnly: true,
28168
- onClick: onClickView,
28110
+ onClick: (e) => onClickView(row, e),
28169
28111
  children: t("common:action.view_label", "View")
28170
28112
  }),
28171
28113
  /* @__PURE__ */ jsx(Button$2, {
@@ -28173,7 +28115,7 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
28173
28115
  rightIcon: /* @__PURE__ */ jsx(Edit2_default, { size: 14 }),
28174
28116
  iconOnly: true,
28175
28117
  disabled: isNonEditable,
28176
- onClick: onClickEdit,
28118
+ onClick: (e) => onClickEdit(account, e),
28177
28119
  tooltip: isNonEditable ? t("chartOfAccounts:validation.account_not_modifiable", "This account cannot be modified") : void 0,
28178
28120
  children: t("common:action.edit_label", "Edit")
28179
28121
  }),
@@ -28181,77 +28123,40 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
28181
28123
  variant: ButtonVariant.secondary,
28182
28124
  rightIcon: /* @__PURE__ */ jsx(Trash2, { size: 14 }),
28183
28125
  iconOnly: true,
28184
- onClick: onClickDelete,
28126
+ onClick: (e) => onClickDelete(account, e),
28185
28127
  disabled: isDeleteDisabled,
28186
28128
  tooltip: getDeleteButtonTooltip(account),
28187
28129
  children: t("common:action.delete_label", "Delete")
28188
28130
  })
28189
28131
  ]
28190
- })
28191
- })
28192
- ]
28193
- }), hasSubAccounts && isExpanded && account.subAccounts.map((subItem, subIdx) => {
28194
- return renderChartOfAccountsDesktopRow({
28195
- account: subItem,
28196
- index: subIdx,
28197
- depth: depth + 1,
28198
- searchQuery: searchQuery$1
28199
- });
28200
- })] }, rowKey + "-" + index);
28201
- };
28202
- if (filteredAccounts.length === 0) return /* @__PURE__ */ jsx("div", {
28203
- className: "Layer__table-state-container",
28204
- children: /* @__PURE__ */ jsx(DataState, {
28205
- status: DataStateStatus.info,
28206
- title: t("chartOfAccounts:empty.accounts", "No accounts found"),
28207
- description: t("chartOfAccounts:empty.accounts_match_filters", "No accounts match the current filters. Click \"Add Account\" to create a new one.")
28208
- })
28209
- });
28210
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Table$1, {
28211
- componentName: "chart-of-accounts",
28212
- children: [
28213
- /* @__PURE__ */ jsxs("colgroup", { children: [
28214
- enableAccountNumbers && /* @__PURE__ */ jsx("col", { className: "Layer__chart-of-accounts--accountnumber" }),
28215
- /* @__PURE__ */ jsx("col", { className: "Layer__chart-of-accounts--name" }),
28216
- /* @__PURE__ */ jsx("col", { className: "Layer__chart-of-accounts--type" }),
28217
- /* @__PURE__ */ jsx("col", { className: "Layer__chart-of-accounts--subtype" }),
28218
- /* @__PURE__ */ jsx("col", { className: "Layer__chart-of-accounts--balance" }),
28219
- /* @__PURE__ */ jsx("col", { className: "Layer__chart-of-accounts--actions" })
28220
- ] }),
28221
- /* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsxs(TableRow, {
28222
- isHeadRow: true,
28223
- rowKey: "charts-of-accounts-head-row",
28224
- children: [
28225
- enableAccountNumbers && /* @__PURE__ */ jsx(TableCell, {
28226
- isHeaderCell: true,
28227
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.numberColumnHeader) || t("generalLedger:label.account_number", "Account Number")
28228
- }),
28229
- /* @__PURE__ */ jsx(TableCell, {
28230
- isHeaderCell: true,
28231
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.nameColumnHeader) || t("generalLedger:label.account_name_title_case", "Account Name")
28232
- }),
28233
- /* @__PURE__ */ jsx(TableCell, {
28234
- isHeaderCell: true,
28235
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.typeColumnHeader) || t("common:label.type", "Type")
28236
- }),
28237
- /* @__PURE__ */ jsx(TableCell, {
28238
- isHeaderCell: true,
28239
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.subtypeColumnHeader) || t("chartOfAccounts:label.sub_type", "Sub-Type")
28240
- }),
28241
- /* @__PURE__ */ jsx(TableCell, {
28242
- isHeaderCell: true,
28243
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.balanceColumnHeader) || t("common:label.balance", "Balance")
28244
- }),
28245
- /* @__PURE__ */ jsx(TableCell, { isHeaderCell: true })
28246
- ]
28247
- }) }),
28248
- /* @__PURE__ */ jsx(TableBody$1, { children: !isError && filteredAccounts.map((account, index) => renderChartOfAccountsDesktopRow({
28249
- account,
28250
- index,
28251
- depth: 0,
28252
- searchQuery
28253
- })) })
28254
- ]
28132
+ });
28133
+ }
28134
+ }
28135
+ ];
28136
+ if (enableAccountNumbers) columns.unshift(accountNumberColumn);
28137
+ return columns;
28138
+ }, [
28139
+ enableAccountNumbers,
28140
+ formatCurrencyFromCents$1,
28141
+ getDeleteButtonTooltip,
28142
+ onClickEdit,
28143
+ onClickView,
28144
+ renderHighlightedNonRootValue,
28145
+ renderHighlightedValue,
28146
+ stringOverrides,
28147
+ t,
28148
+ templateAccountsEditable
28149
+ ]);
28150
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ExpandableDataTable, {
28151
+ componentName: COMPONENT_NAME$8,
28152
+ ariaLabel: t("chartOfAccounts:label.chart_of_accounts", "Chart of Accounts"),
28153
+ columnConfig,
28154
+ data: filteredAccounts ? asMutable(filteredAccounts) : void 0,
28155
+ isLoading,
28156
+ isError,
28157
+ slots,
28158
+ getSubRows: getSubRows$3,
28159
+ getRowId: getRowId$2
28255
28160
  }), /* @__PURE__ */ jsx(BaseConfirmationModal, {
28256
28161
  isOpen: accountToDelete !== null,
28257
28162
  onOpenChange: (isOpen) => {
@@ -28264,88 +28169,201 @@ const ChartOfAccountsTableContent = ({ stringOverrides, data, searchQuery, expan
28264
28169
  cancelLabel: t("common:action.cancel_label", "Cancel")
28265
28170
  })] });
28266
28171
  };
28267
- var COMPONENT_NAME$8 = "chart-of-accounts";
28268
- const ChartOfAccountsTableWithPanel = ({ view, containerRef, asWidget = false, withDateControl = false, withExpandAllButton = false, showAddAccountButton = true, stringOverrides, templateAccountsEditable }) => {
28172
+ var _excluded$21 = ["size"];
28173
+ var Plus$1 = (_ref) => {
28174
+ let { size = 14 } = _ref;
28175
+ return /* @__PURE__ */ jsxs("svg", _objectSpread2(_objectSpread2({
28176
+ xmlns: "http://www.w3.org/2000/svg",
28177
+ viewBox: "0 0 14 14",
28178
+ fill: "none"
28179
+ }, _objectWithoutProperties(_ref, _excluded$21)), {}, {
28180
+ width: size,
28181
+ height: size,
28182
+ children: [/* @__PURE__ */ jsx("path", {
28183
+ d: "M7 2.91602V11.0827",
28184
+ stroke: "currentColor",
28185
+ strokeLinecap: "round",
28186
+ strokeLinejoin: "round"
28187
+ }), /* @__PURE__ */ jsx("path", {
28188
+ d: "M2.91669 7H11.0834",
28189
+ stroke: "currentColor",
28190
+ strokeLinecap: "round",
28191
+ strokeLinejoin: "round"
28192
+ })]
28193
+ }));
28194
+ };
28195
+ var Plus_default = Plus$1;
28196
+ var getLedgerAccountBalancesCSV = get(({ businessId }) => `/v1/businesses/${businessId}/ledger/balances/exports/csv`);
28197
+ function buildKey$51({ access_token: accessToken, apiUrl, businessId, startCutoff, endCutoff }) {
28198
+ if (accessToken && apiUrl) return {
28199
+ accessToken,
28200
+ apiUrl,
28201
+ businessId,
28202
+ startCutoff,
28203
+ endCutoff,
28204
+ tags: [
28205
+ "#account-balances",
28206
+ "#exports",
28207
+ "#csv"
28208
+ ]
28209
+ };
28210
+ }
28211
+ function useAccountBalancesDownload({ startCutoff, endCutoff, onSuccess }) {
28212
+ const withLocale = useLocalizedKey();
28213
+ const { data: auth } = useAuth();
28214
+ const { businessId } = useLayerContext();
28215
+ return useSWRMutation(() => withLocale(buildKey$51(_objectSpread2(_objectSpread2({}, auth), {}, {
28216
+ businessId,
28217
+ startCutoff,
28218
+ endCutoff
28219
+ }))), ({ accessToken, apiUrl, businessId: businessId$1, startCutoff: startCutoff$1, endCutoff: endCutoff$1 }) => getLedgerAccountBalancesCSV(apiUrl, accessToken, { params: {
28220
+ businessId: businessId$1,
28221
+ startCutoff: startCutoff$1 === null || startCutoff$1 === void 0 ? void 0 : startCutoff$1.toISOString(),
28222
+ endCutoff: endCutoff$1 === null || endCutoff$1 === void 0 ? void 0 : endCutoff$1.toISOString()
28223
+ } })().then(({ data }) => {
28224
+ if (onSuccess) return onSuccess(data);
28225
+ }), {
28226
+ revalidate: false,
28227
+ throwOnError: false
28228
+ });
28229
+ }
28230
+ function AccountBalancesDownloadButton({ startCutoff, endCutoff, iconOnly }) {
28231
+ const { t } = useTranslation();
28232
+ const { invisibleDownloadRef, triggerInvisibleDownload } = useInvisibleDownload();
28233
+ const { trigger, isMutating, error: error$38 } = useAccountBalancesDownload({
28234
+ startCutoff,
28235
+ endCutoff,
28236
+ onSuccess: ({ presignedUrl }) => triggerInvisibleDownload({ url: presignedUrl })
28237
+ });
28238
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(DownloadButton, {
28239
+ iconOnly,
28240
+ onClick: () => {
28241
+ trigger();
28242
+ },
28243
+ isDownloading: isMutating,
28244
+ requestFailed: Boolean(error$38),
28245
+ text: t("common:action.download_csv", "Download CSV")
28246
+ }), /* @__PURE__ */ jsx(InvisibleDownload_default, { ref: invisibleDownloadRef })] });
28247
+ }
28248
+ var Collapse = (_ref) => {
28249
+ return /* @__PURE__ */ jsxs("svg", _objectSpread2(_objectSpread2({
28250
+ xmlns: "http://www.w3.org/2000/svg",
28251
+ width: "14",
28252
+ height: "22",
28253
+ viewBox: "0 0 14 22",
28254
+ fill: "none"
28255
+ }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ jsx("path", {
28256
+ d: "M3.5 5.25L7 8.75L10.5 5.25",
28257
+ stroke: "currentColor",
28258
+ strokeLinecap: "round",
28259
+ strokeLinejoin: "round"
28260
+ }), /* @__PURE__ */ jsx("path", {
28261
+ d: "M3.5 16.75L7 13.25L10.5 16.75",
28262
+ stroke: "currentColor",
28263
+ strokeLinecap: "round",
28264
+ strokeLinejoin: "round"
28265
+ })] }));
28266
+ };
28267
+ var Collapse_default = Collapse;
28268
+ var Expand = (_ref) => {
28269
+ return /* @__PURE__ */ jsxs("svg", _objectSpread2(_objectSpread2({
28270
+ xmlns: "http://www.w3.org/2000/svg",
28271
+ width: "14",
28272
+ height: "22",
28273
+ viewBox: "0 0 14 22",
28274
+ fill: "none"
28275
+ }, _extends({}, (_objectDestructuringEmpty(_ref), _ref))), {}, { children: [/* @__PURE__ */ jsx("path", {
28276
+ d: "M10.5 8.75L7 5.25L3.5 8.75",
28277
+ stroke: "currentColor",
28278
+ strokeLinecap: "round",
28279
+ strokeLinejoin: "round"
28280
+ }), /* @__PURE__ */ jsx("path", {
28281
+ d: "M3.5 13.25L7 16.75L10.5 13.25",
28282
+ stroke: "currentColor",
28283
+ strokeLinecap: "round",
28284
+ strokeLinejoin: "round"
28285
+ })] }));
28286
+ };
28287
+ var Expand_default = Expand;
28288
+ const ExpandableDataTableToggleButton = () => {
28289
+ const { t } = useTranslation();
28290
+ const { expanded, setExpanded } = useContext(ExpandableDataTableContext);
28291
+ const { isDesktop } = useSizeClass();
28292
+ const shouldCollapse = expanded === true;
28293
+ const onClickExpandOrCollapse = useCallback(() => {
28294
+ if (shouldCollapse) setExpanded({});
28295
+ else setExpanded(true);
28296
+ }, [setExpanded, shouldCollapse]);
28297
+ const buttonText = shouldCollapse ? t("common:action.collapse_all", "Collapse All") : t("common:action.expand_all", "Expand All");
28298
+ const Icon = shouldCollapse ? Collapse_default : Expand_default;
28299
+ return /* @__PURE__ */ jsx(Button$1, {
28300
+ icon: !isDesktop,
28301
+ variant: "outlined",
28302
+ onClick: onClickExpandOrCollapse,
28303
+ "aria-label": !isDesktop ? buttonText : void 0,
28304
+ children: !isDesktop ? /* @__PURE__ */ jsx(Icon, {}) : buttonText
28305
+ });
28306
+ };
28307
+ const ChartOfAccountsTableHeader = ({ asWidget, withDateControl, withExpandAllButton, showAddAccountButton, inputValue, onSearchChange, stringOverrides }) => {
28269
28308
  const { t } = useTranslation();
28270
- const { data, isLoading, addAccount, isError, isValidating, refetch, form } = useContext(ChartOfAccountsContext);
28271
- const [expandAll, setExpandAll] = useState();
28309
+ const { addAccount } = useContext(ChartOfAccountsContext);
28310
+ const { isDesktop } = useSizeClass();
28311
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Header$2, {
28312
+ asHeader: true,
28313
+ rounded: true,
28314
+ children: /* @__PURE__ */ jsx(HeaderRow, { children: /* @__PURE__ */ jsx(HeaderCol, { children: /* @__PURE__ */ jsx(Heading$2, {
28315
+ size: asWidget ? HeadingSize.view : HeadingSize.primary,
28316
+ children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.headerText) || t("chartOfAccounts:label.chart_of_accounts", "Chart of Accounts")
28317
+ }) }) })
28318
+ }), /* @__PURE__ */ jsx(Header$2, {
28319
+ sticky: true,
28320
+ children: /* @__PURE__ */ jsxs(HeaderRow, { children: [/* @__PURE__ */ jsx(HeaderCol, { children: /* @__PURE__ */ jsx(Heading$2, {
28321
+ size: HeadingSize.secondary,
28322
+ children: withDateControl || withExpandAllButton ? /* @__PURE__ */ jsxs(HStack, {
28323
+ align: "center",
28324
+ gap: "xs",
28325
+ children: [withDateControl && /* @__PURE__ */ jsx(GlobalMonthPicker, {}), withExpandAllButton && /* @__PURE__ */ jsx(ExpandableDataTableToggleButton, {})]
28326
+ }) : null
28327
+ }) }), /* @__PURE__ */ jsxs(HeaderCol, {
28328
+ className: "Layer__chart-of-accounts__actions",
28329
+ children: [
28330
+ /* @__PURE__ */ jsx(SearchField$1, {
28331
+ label: t("chartOfAccounts:label.search_accounts", "Search accounts"),
28332
+ value: inputValue,
28333
+ onChange: onSearchChange
28334
+ }),
28335
+ /* @__PURE__ */ jsx(AccountBalancesDownloadButton, { iconOnly: !isDesktop }),
28336
+ showAddAccountButton && /* @__PURE__ */ jsx(Button$2, {
28337
+ onClick: () => addAccount(),
28338
+ iconOnly: !isDesktop,
28339
+ leftIcon: !isDesktop && /* @__PURE__ */ jsx(Plus_default, { size: 14 }),
28340
+ children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.addAccountButtonText) || t("chartOfAccounts:action.add_account", "Add Account")
28341
+ })
28342
+ ]
28343
+ })] })
28344
+ })] });
28345
+ };
28346
+ const ChartOfAccountsTableWithPanel = ({ containerRef, asWidget = false, withDateControl = false, withExpandAllButton = false, showAddAccountButton = true, stringOverrides, templateAccountsEditable }) => {
28347
+ const { form } = useContext(ChartOfAccountsContext);
28272
28348
  const { inputValue, searchQuery, handleInputChange } = useDebouncedSearchInput({ initialInputState: "" });
28273
- return /* @__PURE__ */ jsxs(Panel, {
28274
- sidebar: /* @__PURE__ */ jsx(ChartOfAccountsSidebar, {
28275
- parentRef: containerRef,
28276
- stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.chartOfAccountsForm
28277
- }),
28278
- sidebarIsOpen: Boolean(form),
28349
+ return /* @__PURE__ */ jsx(ExpandableDataTableProvider, { children: /* @__PURE__ */ jsxs(Panel, {
28350
+ sidebar: /* @__PURE__ */ jsx(ChartOfAccountsForm, { stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.chartOfAccountsForm }),
28351
+ sidebarIsOpen: !!form,
28279
28352
  parentRef: containerRef,
28280
- children: [
28281
- /* @__PURE__ */ jsx(Header$2, {
28282
- className: `Layer__${COMPONENT_NAME$8}__header`,
28283
- asHeader: true,
28284
- rounded: true,
28285
- children: /* @__PURE__ */ jsx(HeaderRow, { children: /* @__PURE__ */ jsx(HeaderCol, { children: /* @__PURE__ */ jsx(Heading$2, {
28286
- className: `Layer__${COMPONENT_NAME$8}__title`,
28287
- size: asWidget ? HeadingSize.view : HeadingSize.primary,
28288
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.headerText) || t("chartOfAccounts:label.chart_of_accounts", "Chart of Accounts")
28289
- }) }) })
28290
- }),
28291
- /* @__PURE__ */ jsx(Header$2, {
28292
- className: `Layer__${COMPONENT_NAME$8}__header`,
28293
- sticky: true,
28294
- children: /* @__PURE__ */ jsxs(HeaderRow, { children: [/* @__PURE__ */ jsx(HeaderCol, { children: /* @__PURE__ */ jsx(Heading$2, {
28295
- size: HeadingSize.secondary,
28296
- className: `Layer__${COMPONENT_NAME$8}__subtitle`,
28297
- children: withDateControl || withExpandAllButton ? /* @__PURE__ */ jsxs(HStack, {
28298
- align: "center",
28299
- gap: "xs",
28300
- children: [withDateControl && /* @__PURE__ */ jsx(GlobalMonthPicker, {}), withExpandAllButton && /* @__PURE__ */ jsx(ExpandCollapseButton, {
28301
- iconOnly: view === "mobile",
28302
- onClick: () => setExpandAll(!expandAll || expandAll === "collapsed" ? "expanded" : "collapsed"),
28303
- expanded: !(!expandAll || expandAll === "collapsed"),
28304
- variant: ButtonVariant.secondary
28305
- })]
28306
- }) : null
28307
- }) }), /* @__PURE__ */ jsxs(HeaderCol, {
28308
- className: "Layer__chart-of-accounts__actions",
28309
- children: [
28310
- /* @__PURE__ */ jsx(SearchField$1, {
28311
- label: t("chartOfAccounts:label.search_accounts", "Search accounts"),
28312
- value: inputValue,
28313
- onChange: handleInputChange
28314
- }),
28315
- /* @__PURE__ */ jsx(AccountBalancesDownloadButton, { iconOnly: ["mobile", "tablet"].includes(view) }),
28316
- showAddAccountButton && /* @__PURE__ */ jsx(Button$2, {
28317
- onClick: () => addAccount(),
28318
- iconOnly: ["mobile", "tablet"].includes(view),
28319
- leftIcon: ["mobile", "tablet"].includes(view) && /* @__PURE__ */ jsx(Plus_default, { size: 14 }),
28320
- children: (stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.addAccountButtonText) || t("chartOfAccounts:action.add_account", "Add Account")
28321
- })
28322
- ]
28323
- })] })
28324
- }),
28325
- data && /* @__PURE__ */ jsx(ChartOfAccountsTable, {
28326
- view,
28327
- data,
28328
- searchQuery,
28329
- stringOverrides,
28330
- expandAll,
28331
- templateAccountsEditable
28332
- }),
28333
- isError ? /* @__PURE__ */ jsx("div", {
28334
- className: "Layer__table-state-container",
28335
- children: /* @__PURE__ */ jsx(DataState, {
28336
- status: DataStateStatus.failed,
28337
- title: t("common:error.something_went_wrong", "Something went wrong"),
28338
- description: t("common:error.couldnt_load_data", "We couldn’t load your data."),
28339
- onRefresh: () => void refetch(),
28340
- isLoading: isValidating || isLoading
28341
- })
28342
- }) : null,
28343
- (!data || isLoading) && !isError ? /* @__PURE__ */ jsx("div", {
28344
- className: `Layer__${COMPONENT_NAME$8}__loader-container`,
28345
- children: /* @__PURE__ */ jsx(Loader, {})
28346
- }) : null
28347
- ]
28348
- });
28353
+ children: [/* @__PURE__ */ jsx(ChartOfAccountsTableHeader, {
28354
+ asWidget,
28355
+ withDateControl,
28356
+ withExpandAllButton,
28357
+ showAddAccountButton,
28358
+ inputValue,
28359
+ onSearchChange: handleInputChange,
28360
+ stringOverrides
28361
+ }), /* @__PURE__ */ jsx(ChartOfAccountsTable, {
28362
+ searchQuery,
28363
+ stringOverrides,
28364
+ templateAccountsEditable
28365
+ })]
28366
+ }) });
28349
28367
  };
28350
28368
  const LedgerAccountRow = ({ row, index, view, nodeType }) => {
28351
28369
  var _ledgerEntrySource$di3, _row$account$name3, _row$account3;
@@ -28704,7 +28722,6 @@ var ChartOfAccountsContent = ({ asWidget, withDateControl, withExpandAllButton,
28704
28722
  asWidget,
28705
28723
  withDateControl,
28706
28724
  withExpandAllButton,
28707
- view,
28708
28725
  containerRef,
28709
28726
  showAddAccountButton,
28710
28727
  stringOverrides: stringOverrides === null || stringOverrides === void 0 ? void 0 : stringOverrides.chartOfAccountsTable,
@@ -29433,10 +29450,10 @@ const JournalEntryLineItem = ({ form, index, displayIndex, isReadOnly, onDeleteL
29433
29450
  })
29434
29451
  });
29435
29452
  };
29436
- var EMPTY_ARRAY$2 = [];
29453
+ var EMPTY_ARRAY$1 = [];
29437
29454
  const JournalEntryLineItemsTable = ({ form, isReadOnly, title, direction, showTags = false }) => {
29438
29455
  const { t } = useTranslation();
29439
- const lineItems = useStore$1(form.store, (state$16) => state$16.values.lineItems || EMPTY_ARRAY$2);
29456
+ const lineItems = useStore$1(form.store, (state$16) => state$16.values.lineItems || EMPTY_ARRAY$1);
29440
29457
  const filteredIndices = useMemo(() => {
29441
29458
  const indices = [];
29442
29459
  lineItems.forEach((item, index) => {
@@ -37811,18 +37828,20 @@ function useUnifiedReportParams() {
37811
37828
  const dateSelectionMode = useUnifiedReportDateSelectionMode();
37812
37829
  const { date: effectiveDate } = useGlobalDate({ dateSelectionMode });
37813
37830
  const { startDate, endDate } = useGlobalDateRange({ dateSelectionMode });
37831
+ const { startDate: yearStartDate } = useGlobalDateRange({ dateSelectionMode: "year" });
37814
37832
  return useMemo(() => {
37815
37833
  if (!report) return null;
37816
- return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({ route: report.reportRoute }, report.baseQueryParameters), hasControl(report, ReportControl.Date) && { effectiveDate }), hasControl(report, ReportControl.DateRange) && {
37834
+ return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({ route: report.reportRoute }, report.baseQueryParameters), hasControl(report, ReportControl.Date) && { effectiveDate }), hasControl(report, ReportControl.DateRange) && {
37817
37835
  startDate,
37818
37836
  endDate
37819
- }), hasControl(report, ReportControl.GroupBy) && groupBy != null && { groupBy });
37837
+ }), hasControl(report, ReportControl.GroupBy) && groupBy != null && { groupBy }), hasControl(report, ReportControl.Year) && { year: getYear(yearStartDate) });
37820
37838
  }, [
37821
37839
  effectiveDate,
37822
37840
  endDate,
37823
37841
  groupBy,
37824
37842
  report,
37825
- startDate
37843
+ startDate,
37844
+ yearStartDate
37826
37845
  ]);
37827
37846
  }
37828
37847
  var findDefaultReport = (groups) => {
@@ -37878,21 +37897,6 @@ function UnifiedReportStoreProvider({ children, dateSelectionMode = "full" }) {
37878
37897
  children
37879
37898
  });
37880
37899
  }
37881
- const ExpandableDataTableContext = createContext({
37882
- expanded: {},
37883
- setExpanded: () => {}
37884
- });
37885
- function ExpandableDataTableProvider({ children }) {
37886
- const [expanded, setExpanded] = useState({});
37887
- const value = useMemo(() => ({
37888
- expanded,
37889
- setExpanded
37890
- }), [expanded]);
37891
- return /* @__PURE__ */ jsx(ExpandableDataTableContext.Provider, {
37892
- value,
37893
- children
37894
- });
37895
- }
37896
37900
  var _excluded$8 = ["children", "className"], _excluded2$3 = ["children"], _excluded3 = ["children"];
37897
37901
  var TREE_CLASS_NAME = "Layer__UI__Tree";
37898
37902
  var TREE_ITEM_CLASS_NAME = "Layer__UI__TreeItem";
@@ -37965,11 +37969,7 @@ var renderTreeGroup = ({ group, groupConfig: groupConfig$1, onToggle, renderItem
37965
37969
  var renderTreeLeaf = ({ leaf, leafConfig }) => /* @__PURE__ */ jsx(TreeItem$1, {
37966
37970
  id: leafConfig.getId(leaf),
37967
37971
  textValue: leafConfig.getTextValue(leaf),
37968
- children: /* @__PURE__ */ jsx(TreeItemContent$1, { children: /* @__PURE__ */ jsxs(HStack, {
37969
- align: "center",
37970
- justify: "space-between",
37971
- children: [leafConfig.renderLabel(leaf), /* @__PURE__ */ jsx(Check_default, { className: "Layer__TreeNavigation__Check" })]
37972
- }) })
37972
+ children: /* @__PURE__ */ jsx(TreeItemContent$1, { children: leafConfig.renderLabel(leaf) })
37973
37973
  });
37974
37974
  function TreeNavigation({ items, selectedItem, isGroup: isGroup$1, groupConfig: groupConfig$1, leafConfig, ariaLabel }) {
37975
37975
  const { t } = useTranslation();
@@ -38104,25 +38104,6 @@ function ReportsNavigation() {
38104
38104
  }
38105
38105
  });
38106
38106
  }
38107
- const ExpandableDataTableToggleButton = () => {
38108
- const { t } = useTranslation();
38109
- const { expanded, setExpanded } = useContext(ExpandableDataTableContext);
38110
- const { isDesktop } = useSizeClass();
38111
- const shouldCollapse = expanded === true;
38112
- const onClickExpandOrCollapse = useCallback(() => {
38113
- if (shouldCollapse) setExpanded({});
38114
- else setExpanded(true);
38115
- }, [setExpanded, shouldCollapse]);
38116
- const buttonText = shouldCollapse ? t("common:action.collapse_all", "Collapse All") : t("common:action.expand_all", "Expand All");
38117
- const Icon = shouldCollapse ? Collapse_default : Expand_default;
38118
- return /* @__PURE__ */ jsx(Button$1, {
38119
- icon: !isDesktop,
38120
- variant: "outlined",
38121
- onClick: onClickExpandOrCollapse,
38122
- "aria-label": !isDesktop ? buttonText : void 0,
38123
- children: !isDesktop ? /* @__PURE__ */ jsx(Icon, {}) : buttonText
38124
- });
38125
- };
38126
38107
  var ReportComboBoxOption = class extends BaseComboBoxOption {
38127
38108
  constructor(report) {
38128
38109
  super(report);
@@ -38288,90 +38269,6 @@ function useUnifiedReport() {
38288
38269
  return getUnifiedReport(apiUrl$1, accessToken, { params: _objectSpread2({ businessId: businessId$1 }, restParams) })().then(({ data }) => Schema.decodeUnknownPromise(UnifiedReportSchema)(data));
38289
38270
  }));
38290
38271
  }
38291
- var baseClassName = "Layer__ExpandButton";
38292
- const ExpandButton = ({ isExpanded }) => {
38293
- return /* @__PURE__ */ jsx(ChevronDownFill_default, {
38294
- className: classNames(baseClassName, `${baseClassName}--${isExpanded ? "expanded" : "collapsed"}`),
38295
- size: 16,
38296
- "aria-label": isExpanded ? "Collapse row" : "Expand row"
38297
- });
38298
- };
38299
- var INDENT_SIZE_XS = 10;
38300
- var INDENT_SIZE_SM = 20;
38301
- var INDENT_SIZE_MD = 40;
38302
- var CHEVRON_OFFSET_PX = 4;
38303
- var getRowIndentStyle = ({ depth, canExpand, indentSizePx }) => ({ paddingInlineStart: depth * indentSizePx + (canExpand ? 0 : CHEVRON_OFFSET_PX) });
38304
- var EMPTY_ARRAY$1 = [];
38305
- function ExpandableDataTable({ data, isLoading, isError, columnConfig, componentName, ariaLabel, slots, getSubRows: getSubRows$3, getRowId: getRowId$2, indentSize = "sm" }) {
38306
- const { expanded, setExpanded } = useContext(ExpandableDataTableContext);
38307
- const wrappedColumnConfig = useMemo(() => {
38308
- const indentSizePx = indentSize === "xs" ? INDENT_SIZE_XS : indentSize === "md" ? INDENT_SIZE_MD : INDENT_SIZE_SM;
38309
- const [first, ...rest] = columnConfig;
38310
- if (!first || !isLeafColumn(first)) return columnConfig;
38311
- const cellRenderer = first.cell;
38312
- return [_objectSpread2(_objectSpread2({}, first), {}, { cell: (row) => {
38313
- const canExpand = row.getCanExpand();
38314
- const rowIndentStyle = getRowIndentStyle({
38315
- canExpand,
38316
- depth: row.depth,
38317
- indentSizePx
38318
- });
38319
- if (!canExpand) return /* @__PURE__ */ jsx("div", {
38320
- style: rowIndentStyle,
38321
- children: cellRenderer(row)
38322
- });
38323
- return /* @__PURE__ */ jsx("div", {
38324
- style: rowIndentStyle,
38325
- children: /* @__PURE__ */ jsxs(HStack, {
38326
- align: "center",
38327
- gap: "xs",
38328
- children: [/* @__PURE__ */ jsx(ExpandButton, { isExpanded: row.getIsExpanded() }), cellRenderer(row)]
38329
- })
38330
- });
38331
- } }), ...rest];
38332
- }, [columnConfig, indentSize]);
38333
- const columnDefs = getColumnDefs(wrappedColumnConfig);
38334
- const columnPinning = useMemo(() => getColumnPinning(wrappedColumnConfig), [wrappedColumnConfig]);
38335
- const table$1 = useReactTable({
38336
- data: data !== null && data !== void 0 ? data : EMPTY_ARRAY$1,
38337
- columns: columnDefs,
38338
- getSubRows: getSubRows$3,
38339
- getCoreRowModel: getCoreRowModel(),
38340
- getExpandedRowModel: getExpandedRowModel(),
38341
- state: {
38342
- expanded,
38343
- columnPinning
38344
- },
38345
- onExpandedChange: setExpanded,
38346
- autoResetPageIndex: false,
38347
- getRowId: getRowId$2
38348
- });
38349
- const { rows } = table$1.getExpandedRowModel();
38350
- const dependencies$1 = useMemo(() => [expanded], [expanded]);
38351
- const headerGroups = table$1.getHeaderGroups();
38352
- const numColumns = table$1.getVisibleLeafColumns().length;
38353
- const isRowClickable = useCallback((row) => {
38354
- return row.getCanExpand();
38355
- }, []);
38356
- const onRowClick = useCallback((row) => {
38357
- row.toggleExpanded();
38358
- }, []);
38359
- return /* @__PURE__ */ jsx(DataTable, {
38360
- ariaLabel,
38361
- numColumns,
38362
- data: rows,
38363
- isLoading,
38364
- isError,
38365
- componentName,
38366
- slots,
38367
- dependencies: dependencies$1,
38368
- headerGroups,
38369
- withClickableRow: useMemo(() => ({
38370
- onRowClick,
38371
- isRowClickable
38372
- }), [onRowClick, isRowClickable])
38373
- });
38374
- }
38375
38272
  var _excluded$5 = [
38376
38273
  "durationMinutes",
38377
38274
  "className",
@@ -38505,8 +38402,8 @@ const UnifiedReportTable = () => {
38505
38402
  const UnifiedReportEmptyState = useCallback(() => {
38506
38403
  return /* @__PURE__ */ jsx(DataState, {
38507
38404
  status: DataStateStatus.allDone,
38508
- title: t("reports:empty.no_rows_found", "No rows found"),
38509
- description: t("reports:empty.report_has_no_rows", "This report has no rows."),
38405
+ title: t("reports:empty.no_rows_found", "No line items found"),
38406
+ description: t("reports:empty.report_has_no_rows", "This report has no line items."),
38510
38407
  spacing: true
38511
38408
  });
38512
38409
  }, [t]);
@@ -38534,6 +38431,63 @@ const UnifiedReportTable = () => {
38534
38431
  getRowId: (row) => row.rowKey
38535
38432
  });
38536
38433
  };
38434
+ const YearPicker = ({ label: label$50, year, onChange, minDate = null, maxDate = null, isDisabled = false }) => {
38435
+ var _minDate$year, _maxDate$year;
38436
+ const { t } = useTranslation();
38437
+ const { formatDate: formatDate$1 } = useIntlFormatter();
38438
+ const coercedLabel = label$50 !== null && label$50 !== void 0 ? label$50 : t("date:label.year", "Year");
38439
+ const minYear = (_minDate$year = minDate === null || minDate === void 0 ? void 0 : minDate.year) !== null && _minDate$year !== void 0 ? _minDate$year : null;
38440
+ const maxYear = (_maxDate$year = maxDate === null || maxDate === void 0 ? void 0 : maxDate.year) !== null && _maxDate$year !== void 0 ? _maxDate$year : null;
38441
+ const yearOptions = useMemo(() => {
38442
+ const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
38443
+ const effectiveMinYear = minYear !== null && minYear !== void 0 ? minYear : currentYear - 10;
38444
+ const effectiveMaxYear = maxYear !== null && maxYear !== void 0 ? maxYear : currentYear;
38445
+ const count = effectiveMaxYear - effectiveMinYear + 1;
38446
+ if (count <= 0) return [];
38447
+ return Array.from({ length: count }, (_, i) => {
38448
+ const optionYear = effectiveMaxYear - i;
38449
+ return {
38450
+ label: formatDate$1(new Date(optionYear, 0, 1), DateFormat.Year),
38451
+ value: String(optionYear)
38452
+ };
38453
+ });
38454
+ }, [
38455
+ formatDate$1,
38456
+ minYear,
38457
+ maxYear
38458
+ ]);
38459
+ return /* @__PURE__ */ jsx(ComboBox, {
38460
+ selectedValue: useMemo(() => {
38461
+ var _yearOptions$find;
38462
+ return (_yearOptions$find = yearOptions.find((opt) => opt.value === String(year))) !== null && _yearOptions$find !== void 0 ? _yearOptions$find : yearOptions[0];
38463
+ }, [yearOptions, year]),
38464
+ onSelectedValueChange: useCallback((option) => {
38465
+ if (option) onChange(Number(option.value));
38466
+ }, [onChange]),
38467
+ options: yearOptions,
38468
+ isSearchable: false,
38469
+ isClearable: false,
38470
+ isDisabled,
38471
+ "aria-label": coercedLabel,
38472
+ className: "Layer__YearPicker"
38473
+ });
38474
+ };
38475
+ const GlobalYearPicker = () => {
38476
+ const { minDate, maxDate } = useGlobalDatePickerBounds();
38477
+ const { setYear } = useGlobalDateRangeActions();
38478
+ const { startDate } = useGlobalDateRange({ dateSelectionMode: "year" });
38479
+ const selectedYear = getYear(startDate);
38480
+ const minDateZdt = useMemo(() => minDate ? convertDateToZonedDateTime(minDate) : null, [minDate]);
38481
+ const maxDateZdt = useMemo(() => convertDateToZonedDateTime(maxDate), [maxDate]);
38482
+ return /* @__PURE__ */ jsx(YearPicker, {
38483
+ year: selectedYear,
38484
+ onChange: useCallback((year) => {
38485
+ setYear({ startDate: new Date(year, 0, 1) });
38486
+ }, [setYear]),
38487
+ minDate: minDateZdt,
38488
+ maxDate: maxDateZdt
38489
+ });
38490
+ };
38537
38491
  var SMALL_BREAKPOINT$1 = 560;
38538
38492
  var MEDIUM_BREAKPOINT$1 = 760;
38539
38493
  var getVariantForWidth = (width) => {
@@ -38565,39 +38519,43 @@ const UnifiedReportControls = () => {
38565
38519
  });
38566
38520
  const variant = getVariantForWidth(size);
38567
38521
  const hasGroupBy = dateSelectionMode === "full" && hasControl(baseReport, ReportControl.GroupBy);
38522
+ const hasYear = hasControl(baseReport, ReportControl.Year);
38568
38523
  return /* @__PURE__ */ jsxs(Stack, {
38569
38524
  ref: containerRef,
38570
38525
  direction: variant === "large" ? "row" : "column",
38571
38526
  pb: "md",
38572
38527
  pi: "lg",
38573
38528
  gap: "xs",
38574
- children: [/* @__PURE__ */ jsx(UnifiedReportDateSelection, { isCompact: variant === "small" }), hasGroupBy && /* @__PURE__ */ jsx("div", {
38529
+ children: [/* @__PURE__ */ jsx(UnifiedReportDateSelection, { isCompact: variant === "small" }), (hasYear || hasGroupBy) && /* @__PURE__ */ jsxs("div", {
38575
38530
  className: "Layer__UnifiedReport__AdditionalControls",
38576
38531
  "data-variant": variant,
38577
- children: /* @__PURE__ */ jsx(DateGroupByComboBox, {
38532
+ children: [hasYear && /* @__PURE__ */ jsx(GlobalYearPicker, {}), hasGroupBy && /* @__PURE__ */ jsx(DateGroupByComboBox, {
38578
38533
  value: groupBy,
38579
38534
  onValueChange: setGroupBy
38580
- })
38535
+ })]
38581
38536
  })]
38582
38537
  });
38583
38538
  };
38584
38539
  const UnifiedReportBaseHeader = () => {
38585
38540
  const { baseReport } = useBaseUnifiedReport();
38586
38541
  const { isDesktop } = useSizeClass();
38587
- return /* @__PURE__ */ jsxs(VStack, { children: [isDesktop && /* @__PURE__ */ jsxs(HStack, {
38588
- pi: "lg",
38589
- pbs: "lg",
38590
- align: "center",
38591
- justify: "space-between",
38592
- children: [baseReport ? /* @__PURE__ */ jsx(Span, {
38593
- size: "lg",
38594
- weight: "bold",
38595
- children: baseReport.displayName
38596
- }) : /* @__PURE__ */ jsx(SkeletonLoader, {
38597
- width: "192px",
38598
- height: "24px"
38599
- }), /* @__PURE__ */ jsx(UnifiedReportHeaderButtons, {})]
38600
- }), /* @__PURE__ */ jsx(UnifiedReportControls, {})] });
38542
+ return /* @__PURE__ */ jsxs(VStack, {
38543
+ className: "Layer__UnifiedReport__BaseHeader",
38544
+ children: [isDesktop && /* @__PURE__ */ jsxs(HStack, {
38545
+ pi: "lg",
38546
+ pbs: "lg",
38547
+ align: "center",
38548
+ justify: "space-between",
38549
+ children: [baseReport ? /* @__PURE__ */ jsx(Span, {
38550
+ size: "lg",
38551
+ weight: "bold",
38552
+ children: baseReport.displayName
38553
+ }) : /* @__PURE__ */ jsx(SkeletonLoader, {
38554
+ width: "192px",
38555
+ height: "24px"
38556
+ }), /* @__PURE__ */ jsx(UnifiedReportHeaderButtons, {})]
38557
+ }), /* @__PURE__ */ jsx(UnifiedReportControls, {})]
38558
+ });
38601
38559
  };
38602
38560
  var _excluded$4 = [
38603
38561
  "children",
@@ -38718,14 +38676,17 @@ var UnifiedReportContent = () => {
38718
38676
  title: t("reports:label.reports", "Reports"),
38719
38677
  viewClassName: "Layer__UnifiedReport",
38720
38678
  header,
38721
- children: /* @__PURE__ */ jsxs(HStack, { children: [isDesktop && /* @__PURE__ */ jsx(VStack, {
38722
- className: "Layer__UnifiedReport__Sidebar",
38723
- children: /* @__PURE__ */ jsx(ReportsNavigation, {})
38724
- }), /* @__PURE__ */ jsxs(VStack, {
38725
- fluid: true,
38726
- className: "Layer__UnifiedReport__Content",
38727
- children: [/* @__PURE__ */ jsx(UnifiedReportTableHeader, {}), /* @__PURE__ */ jsx(UnifiedReportTable, {})]
38728
- })] })
38679
+ children: /* @__PURE__ */ jsxs(HStack, {
38680
+ className: "Layer__UnifiedReport__Body",
38681
+ children: [isDesktop && /* @__PURE__ */ jsx(VStack, {
38682
+ className: "Layer__UnifiedReport__Sidebar",
38683
+ children: /* @__PURE__ */ jsx(ReportsNavigation, {})
38684
+ }), /* @__PURE__ */ jsxs(VStack, {
38685
+ fluid: true,
38686
+ className: "Layer__UnifiedReport__Content",
38687
+ children: [/* @__PURE__ */ jsx(UnifiedReportTableHeader, {}), /* @__PURE__ */ jsx(UnifiedReportTable, {})]
38688
+ })]
38689
+ })
38729
38690
  });
38730
38691
  };
38731
38692
  const UnifiedReport = ({ dateSelectionMode }) => {
@@ -39426,63 +39387,6 @@ const GeneralLedgerView = ({ title, showTitle = true, showTags = true, showCusto
39426
39387
  })
39427
39388
  });
39428
39389
  };
39429
- const YearPicker = ({ label: label$50, year, onChange, minDate = null, maxDate = null, isDisabled = false }) => {
39430
- var _minDate$year, _maxDate$year;
39431
- const { t } = useTranslation();
39432
- const { formatDate: formatDate$1 } = useIntlFormatter();
39433
- const coercedLabel = label$50 !== null && label$50 !== void 0 ? label$50 : t("date:label.year", "Year");
39434
- const minYear = (_minDate$year = minDate === null || minDate === void 0 ? void 0 : minDate.year) !== null && _minDate$year !== void 0 ? _minDate$year : null;
39435
- const maxYear = (_maxDate$year = maxDate === null || maxDate === void 0 ? void 0 : maxDate.year) !== null && _maxDate$year !== void 0 ? _maxDate$year : null;
39436
- const yearOptions = useMemo(() => {
39437
- const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
39438
- const effectiveMinYear = minYear !== null && minYear !== void 0 ? minYear : currentYear - 10;
39439
- const effectiveMaxYear = maxYear !== null && maxYear !== void 0 ? maxYear : currentYear;
39440
- const count = effectiveMaxYear - effectiveMinYear + 1;
39441
- if (count <= 0) return [];
39442
- return Array.from({ length: count }, (_, i) => {
39443
- const optionYear = effectiveMaxYear - i;
39444
- return {
39445
- label: formatDate$1(new Date(optionYear, 0, 1), DateFormat.Year),
39446
- value: String(optionYear)
39447
- };
39448
- });
39449
- }, [
39450
- formatDate$1,
39451
- minYear,
39452
- maxYear
39453
- ]);
39454
- return /* @__PURE__ */ jsx(ComboBox, {
39455
- selectedValue: useMemo(() => {
39456
- var _yearOptions$find;
39457
- return (_yearOptions$find = yearOptions.find((opt) => opt.value === String(year))) !== null && _yearOptions$find !== void 0 ? _yearOptions$find : yearOptions[0];
39458
- }, [yearOptions, year]),
39459
- onSelectedValueChange: useCallback((option) => {
39460
- if (option) onChange(Number(option.value));
39461
- }, [onChange]),
39462
- options: yearOptions,
39463
- isSearchable: false,
39464
- isClearable: false,
39465
- isDisabled,
39466
- "aria-label": coercedLabel,
39467
- className: "Layer__YearPicker"
39468
- });
39469
- };
39470
- const GlobalYearPicker = () => {
39471
- const { minDate, maxDate } = useGlobalDatePickerBounds();
39472
- const { setYear } = useGlobalDateRangeActions();
39473
- const { startDate } = useGlobalDateRange({ dateSelectionMode: "year" });
39474
- const selectedYear = getYear(startDate);
39475
- const minDateZdt = useMemo(() => minDate ? convertDateToZonedDateTime(minDate) : null, [minDate]);
39476
- const maxDateZdt = useMemo(() => convertDateToZonedDateTime(maxDate), [maxDate]);
39477
- return /* @__PURE__ */ jsx(YearPicker, {
39478
- year: selectedYear,
39479
- onChange: useCallback((year) => {
39480
- setYear({ startDate: new Date(year, 0, 1) });
39481
- }, [setYear]),
39482
- minDate: minDateZdt,
39483
- maxDate: maxDateZdt
39484
- });
39485
- };
39486
39390
  var MileageDeductionChartTooltipContent = ({ active, payload }) => {
39487
39391
  const { t } = useTranslation();
39488
39392
  const { formatNumber: formatNumber$1 } = useIntlFormatter();