@powerhousedao/contributor-billing 0.1.41 → 0.1.43

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.
Files changed (729) hide show
  1. package/dist/document-models/account-transactions/actions.d.ts.map +1 -1
  2. package/dist/document-models/account-transactions/gen/account/actions.d.ts +1 -1
  3. package/dist/document-models/account-transactions/gen/account/actions.d.ts.map +1 -1
  4. package/dist/document-models/account-transactions/gen/account/actions.js +1 -1
  5. package/dist/document-models/account-transactions/gen/account/operations.d.ts +2 -2
  6. package/dist/document-models/account-transactions/gen/account/operations.d.ts.map +1 -1
  7. package/dist/document-models/account-transactions/gen/account/operations.js +0 -2
  8. package/dist/document-models/account-transactions/gen/budgets/actions.d.ts +1 -1
  9. package/dist/document-models/account-transactions/gen/budgets/actions.d.ts.map +1 -1
  10. package/dist/document-models/account-transactions/gen/budgets/actions.js +1 -1
  11. package/dist/document-models/account-transactions/gen/budgets/operations.d.ts +2 -2
  12. package/dist/document-models/account-transactions/gen/budgets/operations.d.ts.map +1 -1
  13. package/dist/document-models/account-transactions/gen/budgets/operations.js +0 -2
  14. package/dist/document-models/account-transactions/gen/document-model.js +45 -45
  15. package/dist/document-models/account-transactions/gen/document-schema.d.ts +21 -151
  16. package/dist/document-models/account-transactions/gen/document-schema.d.ts.map +1 -1
  17. package/dist/document-models/account-transactions/gen/reducer.d.ts.map +1 -1
  18. package/dist/document-models/account-transactions/gen/reducer.js +16 -8
  19. package/dist/document-models/account-transactions/gen/schema/types.d.ts +13 -1
  20. package/dist/document-models/account-transactions/gen/schema/types.d.ts.map +1 -1
  21. package/dist/document-models/account-transactions/gen/schema/zod.d.ts +11 -5
  22. package/dist/document-models/account-transactions/gen/schema/zod.d.ts.map +1 -1
  23. package/dist/document-models/account-transactions/gen/schema/zod.js +18 -18
  24. package/dist/document-models/account-transactions/gen/transactions/actions.d.ts +1 -1
  25. package/dist/document-models/account-transactions/gen/transactions/actions.d.ts.map +1 -1
  26. package/dist/document-models/account-transactions/gen/transactions/actions.js +1 -1
  27. package/dist/document-models/account-transactions/gen/transactions/operations.d.ts +2 -2
  28. package/dist/document-models/account-transactions/gen/transactions/operations.d.ts.map +1 -1
  29. package/dist/document-models/account-transactions/gen/transactions/operations.js +0 -2
  30. package/dist/document-models/account-transactions/gen/types.d.ts.map +1 -1
  31. package/dist/document-models/account-transactions/hooks.d.ts +5 -2
  32. package/dist/document-models/account-transactions/hooks.d.ts.map +1 -1
  33. package/dist/document-models/account-transactions/hooks.js +3 -4
  34. package/dist/document-models/account-transactions/index.d.ts +0 -4
  35. package/dist/document-models/account-transactions/index.d.ts.map +1 -1
  36. package/dist/document-models/account-transactions/index.js +0 -4
  37. package/dist/document-models/account-transactions/module.d.ts.map +1 -1
  38. package/dist/document-models/account-transactions/module.js +1 -0
  39. package/dist/document-models/account-transactions/tests/account.test.d.ts +2 -0
  40. package/dist/document-models/account-transactions/tests/account.test.d.ts.map +1 -0
  41. package/dist/document-models/account-transactions/tests/account.test.js +15 -0
  42. package/dist/document-models/account-transactions/tests/budgets.test.d.ts +2 -0
  43. package/dist/document-models/account-transactions/tests/budgets.test.d.ts.map +1 -0
  44. package/dist/document-models/account-transactions/tests/budgets.test.js +35 -0
  45. package/dist/document-models/account-transactions/tests/document-model.test.d.ts +10 -0
  46. package/dist/document-models/account-transactions/tests/document-model.test.d.ts.map +1 -0
  47. package/dist/document-models/account-transactions/tests/document-model.test.js +104 -0
  48. package/dist/document-models/account-transactions/tests/transactions.test.d.ts +2 -0
  49. package/dist/document-models/account-transactions/tests/transactions.test.d.ts.map +1 -0
  50. package/dist/document-models/account-transactions/tests/transactions.test.js +45 -0
  51. package/dist/document-models/accounts/actions.d.ts.map +1 -1
  52. package/dist/document-models/accounts/gen/accounts/actions.d.ts +1 -1
  53. package/dist/document-models/accounts/gen/accounts/actions.d.ts.map +1 -1
  54. package/dist/document-models/accounts/gen/accounts/actions.js +1 -1
  55. package/dist/document-models/accounts/gen/accounts/operations.d.ts +2 -2
  56. package/dist/document-models/accounts/gen/accounts/operations.d.ts.map +1 -1
  57. package/dist/document-models/accounts/gen/accounts/operations.js +0 -2
  58. package/dist/document-models/accounts/gen/document-model.js +2 -2
  59. package/dist/document-models/accounts/gen/document-schema.d.ts +15 -113
  60. package/dist/document-models/accounts/gen/document-schema.d.ts.map +1 -1
  61. package/dist/document-models/accounts/gen/reducer.d.ts.map +1 -1
  62. package/dist/document-models/accounts/gen/reducer.js +8 -4
  63. package/dist/document-models/accounts/gen/schema/types.d.ts +13 -1
  64. package/dist/document-models/accounts/gen/schema/types.d.ts.map +1 -1
  65. package/dist/document-models/accounts/gen/schema/zod.d.ts +25 -7
  66. package/dist/document-models/accounts/gen/schema/zod.d.ts.map +1 -1
  67. package/dist/document-models/accounts/gen/schema/zod.js +12 -12
  68. package/dist/document-models/accounts/gen/types.d.ts.map +1 -1
  69. package/dist/document-models/accounts/hooks.d.ts +5 -2
  70. package/dist/document-models/accounts/hooks.d.ts.map +1 -1
  71. package/dist/document-models/accounts/hooks.js +3 -4
  72. package/dist/document-models/accounts/index.d.ts +0 -4
  73. package/dist/document-models/accounts/index.d.ts.map +1 -1
  74. package/dist/document-models/accounts/index.js +0 -4
  75. package/dist/document-models/accounts/module.d.ts.map +1 -1
  76. package/dist/document-models/accounts/module.js +1 -0
  77. package/dist/document-models/accounts/tests/accounts.test.d.ts +2 -0
  78. package/dist/document-models/accounts/tests/accounts.test.d.ts.map +1 -0
  79. package/dist/document-models/accounts/tests/accounts.test.js +45 -0
  80. package/dist/document-models/accounts/tests/document-model.test.d.ts +10 -0
  81. package/dist/document-models/accounts/tests/document-model.test.d.ts.map +1 -0
  82. package/dist/document-models/accounts/tests/document-model.test.js +104 -0
  83. package/dist/document-models/billing-statement/actions.d.ts.map +1 -1
  84. package/dist/document-models/billing-statement/gen/document-model.js +41 -41
  85. package/dist/document-models/billing-statement/gen/document-schema.d.ts +39 -265
  86. package/dist/document-models/billing-statement/gen/document-schema.d.ts.map +1 -1
  87. package/dist/document-models/billing-statement/gen/general/actions.d.ts +1 -1
  88. package/dist/document-models/billing-statement/gen/general/actions.d.ts.map +1 -1
  89. package/dist/document-models/billing-statement/gen/general/actions.js +1 -1
  90. package/dist/document-models/billing-statement/gen/general/operations.d.ts +2 -2
  91. package/dist/document-models/billing-statement/gen/general/operations.d.ts.map +1 -1
  92. package/dist/document-models/billing-statement/gen/general/operations.js +0 -2
  93. package/dist/document-models/billing-statement/gen/line-items/actions.d.ts +1 -1
  94. package/dist/document-models/billing-statement/gen/line-items/actions.d.ts.map +1 -1
  95. package/dist/document-models/billing-statement/gen/line-items/actions.js +1 -1
  96. package/dist/document-models/billing-statement/gen/line-items/operations.d.ts +2 -2
  97. package/dist/document-models/billing-statement/gen/line-items/operations.d.ts.map +1 -1
  98. package/dist/document-models/billing-statement/gen/line-items/operations.js +0 -2
  99. package/dist/document-models/billing-statement/gen/reducer.d.ts.map +1 -1
  100. package/dist/document-models/billing-statement/gen/reducer.js +14 -7
  101. package/dist/document-models/billing-statement/gen/schema/types.d.ts +13 -1
  102. package/dist/document-models/billing-statement/gen/schema/types.d.ts.map +1 -1
  103. package/dist/document-models/billing-statement/gen/schema/zod.d.ts +29 -7
  104. package/dist/document-models/billing-statement/gen/schema/zod.d.ts.map +1 -1
  105. package/dist/document-models/billing-statement/gen/schema/zod.js +10 -10
  106. package/dist/document-models/billing-statement/gen/tags/actions.d.ts +1 -1
  107. package/dist/document-models/billing-statement/gen/tags/actions.d.ts.map +1 -1
  108. package/dist/document-models/billing-statement/gen/tags/actions.js +1 -1
  109. package/dist/document-models/billing-statement/gen/tags/operations.d.ts +2 -2
  110. package/dist/document-models/billing-statement/gen/tags/operations.d.ts.map +1 -1
  111. package/dist/document-models/billing-statement/gen/tags/operations.js +0 -2
  112. package/dist/document-models/billing-statement/gen/types.d.ts.map +1 -1
  113. package/dist/document-models/billing-statement/hooks.d.ts +5 -2
  114. package/dist/document-models/billing-statement/hooks.d.ts.map +1 -1
  115. package/dist/document-models/billing-statement/hooks.js +3 -4
  116. package/dist/document-models/billing-statement/index.d.ts +0 -4
  117. package/dist/document-models/billing-statement/index.d.ts.map +1 -1
  118. package/dist/document-models/billing-statement/index.js +0 -4
  119. package/dist/document-models/billing-statement/module.d.ts.map +1 -1
  120. package/dist/document-models/billing-statement/module.js +1 -0
  121. package/dist/document-models/billing-statement/tests/document-model.test.d.ts +10 -0
  122. package/dist/document-models/billing-statement/tests/document-model.test.d.ts.map +1 -0
  123. package/dist/document-models/billing-statement/tests/document-model.test.js +104 -0
  124. package/dist/document-models/billing-statement/tests/general.test.d.ts +2 -0
  125. package/dist/document-models/billing-statement/tests/general.test.d.ts.map +1 -0
  126. package/dist/document-models/billing-statement/tests/general.test.js +35 -0
  127. package/dist/document-models/billing-statement/tests/line-items.test.d.ts +2 -0
  128. package/dist/document-models/billing-statement/tests/line-items.test.d.ts.map +1 -0
  129. package/dist/document-models/billing-statement/tests/line-items.test.js +35 -0
  130. package/dist/document-models/billing-statement/tests/tags.test.d.ts +2 -0
  131. package/dist/document-models/billing-statement/tests/tags.test.d.ts.map +1 -0
  132. package/dist/document-models/billing-statement/tests/tags.test.js +15 -0
  133. package/dist/document-models/document-models.d.ts.map +1 -1
  134. package/dist/document-models/document-models.js +5 -3
  135. package/dist/document-models/expense-report/actions.d.ts +1 -0
  136. package/dist/document-models/expense-report/actions.d.ts.map +1 -1
  137. package/dist/document-models/expense-report/gen/document-model.d.ts.map +1 -1
  138. package/dist/document-models/expense-report/gen/document-model.js +14 -3
  139. package/dist/document-models/expense-report/gen/document-schema.d.ts +36 -208
  140. package/dist/document-models/expense-report/gen/document-schema.d.ts.map +1 -1
  141. package/dist/document-models/expense-report/gen/ph-factories.d.ts.map +1 -1
  142. package/dist/document-models/expense-report/gen/ph-factories.js +2 -0
  143. package/dist/document-models/expense-report/gen/reducer.d.ts.map +1 -1
  144. package/dist/document-models/expense-report/gen/reducer.js +40 -18
  145. package/dist/document-models/expense-report/gen/schema/types.d.ts +19 -1
  146. package/dist/document-models/expense-report/gen/schema/types.d.ts.map +1 -1
  147. package/dist/document-models/expense-report/gen/schema/zod.d.ts +15 -6
  148. package/dist/document-models/expense-report/gen/schema/zod.d.ts.map +1 -1
  149. package/dist/document-models/expense-report/gen/schema/zod.js +37 -29
  150. package/dist/document-models/expense-report/gen/types.d.ts.map +1 -1
  151. package/dist/document-models/expense-report/gen/utils.d.ts.map +1 -1
  152. package/dist/document-models/expense-report/gen/utils.js +2 -0
  153. package/dist/document-models/expense-report/gen/wallet/actions.d.ts +7 -3
  154. package/dist/document-models/expense-report/gen/wallet/actions.d.ts.map +1 -1
  155. package/dist/document-models/expense-report/gen/wallet/actions.js +1 -1
  156. package/dist/document-models/expense-report/gen/wallet/creators.d.ts +3 -2
  157. package/dist/document-models/expense-report/gen/wallet/creators.d.ts.map +1 -1
  158. package/dist/document-models/expense-report/gen/wallet/creators.js +2 -1
  159. package/dist/document-models/expense-report/gen/wallet/operations.d.ts +3 -2
  160. package/dist/document-models/expense-report/gen/wallet/operations.d.ts.map +1 -1
  161. package/dist/document-models/expense-report/gen/wallet/operations.js +0 -2
  162. package/dist/document-models/expense-report/hooks.d.ts +5 -2
  163. package/dist/document-models/expense-report/hooks.d.ts.map +1 -1
  164. package/dist/document-models/expense-report/hooks.js +3 -4
  165. package/dist/document-models/expense-report/index.d.ts +0 -4
  166. package/dist/document-models/expense-report/index.d.ts.map +1 -1
  167. package/dist/document-models/expense-report/index.js +0 -4
  168. package/dist/document-models/expense-report/module.d.ts.map +1 -1
  169. package/dist/document-models/expense-report/module.js +1 -0
  170. package/dist/document-models/expense-report/src/reducers/wallet.d.ts.map +1 -1
  171. package/dist/document-models/expense-report/src/reducers/wallet.js +9 -0
  172. package/dist/document-models/expense-report/tests/document-model.test.d.ts +10 -0
  173. package/dist/document-models/expense-report/tests/document-model.test.d.ts.map +1 -0
  174. package/dist/document-models/expense-report/tests/document-model.test.js +104 -0
  175. package/dist/document-models/expense-report/tests/wallet.test.d.ts +2 -0
  176. package/dist/document-models/expense-report/tests/wallet.test.d.ts.map +1 -0
  177. package/dist/document-models/expense-report/tests/wallet.test.js +175 -0
  178. package/dist/document-models/index.d.ts +3 -7
  179. package/dist/document-models/index.d.ts.map +1 -1
  180. package/dist/document-models/index.js +3 -7
  181. package/dist/document-models/invoice/actions.d.ts.map +1 -1
  182. package/dist/document-models/invoice/gen/document-model.js +146 -146
  183. package/dist/document-models/invoice/gen/document-schema.d.ts +66 -436
  184. package/dist/document-models/invoice/gen/document-schema.d.ts.map +1 -1
  185. package/dist/document-models/invoice/gen/general/actions.d.ts +1 -1
  186. package/dist/document-models/invoice/gen/general/actions.d.ts.map +1 -1
  187. package/dist/document-models/invoice/gen/general/actions.js +1 -1
  188. package/dist/document-models/invoice/gen/general/operations.d.ts +2 -2
  189. package/dist/document-models/invoice/gen/general/operations.d.ts.map +1 -1
  190. package/dist/document-models/invoice/gen/general/operations.js +0 -2
  191. package/dist/document-models/invoice/gen/items/actions.d.ts +1 -1
  192. package/dist/document-models/invoice/gen/items/actions.d.ts.map +1 -1
  193. package/dist/document-models/invoice/gen/items/actions.js +1 -1
  194. package/dist/document-models/invoice/gen/items/operations.d.ts +2 -2
  195. package/dist/document-models/invoice/gen/items/operations.d.ts.map +1 -1
  196. package/dist/document-models/invoice/gen/items/operations.js +0 -2
  197. package/dist/document-models/invoice/gen/parties/actions.d.ts +1 -1
  198. package/dist/document-models/invoice/gen/parties/actions.d.ts.map +1 -1
  199. package/dist/document-models/invoice/gen/parties/actions.js +1 -1
  200. package/dist/document-models/invoice/gen/parties/operations.d.ts +2 -2
  201. package/dist/document-models/invoice/gen/parties/operations.d.ts.map +1 -1
  202. package/dist/document-models/invoice/gen/parties/operations.js +0 -2
  203. package/dist/document-models/invoice/gen/reducer.d.ts.map +1 -1
  204. package/dist/document-models/invoice/gen/reducer.js +56 -28
  205. package/dist/document-models/invoice/gen/schema/types.d.ts +9 -1
  206. package/dist/document-models/invoice/gen/schema/types.d.ts.map +1 -1
  207. package/dist/document-models/invoice/gen/schema/zod.d.ts +42 -21
  208. package/dist/document-models/invoice/gen/schema/zod.d.ts.map +1 -1
  209. package/dist/document-models/invoice/gen/schema/zod.js +67 -67
  210. package/dist/document-models/invoice/gen/transitions/actions.d.ts +1 -1
  211. package/dist/document-models/invoice/gen/transitions/actions.d.ts.map +1 -1
  212. package/dist/document-models/invoice/gen/transitions/actions.js +1 -1
  213. package/dist/document-models/invoice/gen/transitions/operations.d.ts +2 -2
  214. package/dist/document-models/invoice/gen/transitions/operations.d.ts.map +1 -1
  215. package/dist/document-models/invoice/gen/transitions/operations.js +0 -2
  216. package/dist/document-models/invoice/gen/types.d.ts.map +1 -1
  217. package/dist/document-models/invoice/hooks.d.ts +5 -2
  218. package/dist/document-models/invoice/hooks.d.ts.map +1 -1
  219. package/dist/document-models/invoice/hooks.js +3 -4
  220. package/dist/document-models/invoice/index.d.ts +0 -4
  221. package/dist/document-models/invoice/index.d.ts.map +1 -1
  222. package/dist/document-models/invoice/index.js +0 -4
  223. package/dist/document-models/invoice/module.d.ts.map +1 -1
  224. package/dist/document-models/invoice/module.js +1 -0
  225. package/dist/document-models/invoice/tests/document-model.test.d.ts +10 -0
  226. package/dist/document-models/invoice/tests/document-model.test.d.ts.map +1 -0
  227. package/dist/document-models/invoice/tests/document-model.test.js +104 -0
  228. package/dist/document-models/invoice/tests/general.test.d.ts +2 -0
  229. package/dist/document-models/invoice/tests/general.test.d.ts.map +1 -0
  230. package/dist/document-models/invoice/tests/general.test.js +55 -0
  231. package/dist/document-models/invoice/tests/items.test.d.ts +2 -0
  232. package/dist/document-models/invoice/tests/items.test.d.ts.map +1 -0
  233. package/dist/document-models/invoice/tests/items.test.js +55 -0
  234. package/dist/document-models/invoice/tests/parties.test.d.ts +2 -0
  235. package/dist/document-models/invoice/tests/parties.test.d.ts.map +1 -0
  236. package/dist/document-models/invoice/tests/parties.test.js +65 -0
  237. package/dist/document-models/invoice/tests/transitions.test.d.ts +2 -0
  238. package/dist/document-models/invoice/tests/transitions.test.d.ts.map +1 -0
  239. package/dist/document-models/invoice/tests/transitions.test.js +125 -0
  240. package/dist/document-models/resource-template/actions.d.ts +3 -0
  241. package/dist/document-models/resource-template/actions.d.ts.map +1 -1
  242. package/dist/document-models/resource-template/gen/audience-management/actions.d.ts +1 -1
  243. package/dist/document-models/resource-template/gen/audience-management/actions.d.ts.map +1 -1
  244. package/dist/document-models/resource-template/gen/audience-management/actions.js +1 -1
  245. package/dist/document-models/resource-template/gen/audience-management/error.d.ts.map +1 -1
  246. package/dist/document-models/resource-template/gen/audience-management/error.js +2 -6
  247. package/dist/document-models/resource-template/gen/audience-management/operations.d.ts +2 -2
  248. package/dist/document-models/resource-template/gen/audience-management/operations.d.ts.map +1 -1
  249. package/dist/document-models/resource-template/gen/audience-management/operations.js +0 -2
  250. package/dist/document-models/resource-template/gen/document-model.d.ts.map +1 -1
  251. package/dist/document-models/resource-template/gen/document-model.js +36 -3
  252. package/dist/document-models/resource-template/gen/document-schema.d.ts +60 -379
  253. package/dist/document-models/resource-template/gen/document-schema.d.ts.map +1 -1
  254. package/dist/document-models/resource-template/gen/facet-targeting/actions.d.ts +1 -1
  255. package/dist/document-models/resource-template/gen/facet-targeting/actions.d.ts.map +1 -1
  256. package/dist/document-models/resource-template/gen/facet-targeting/actions.js +1 -1
  257. package/dist/document-models/resource-template/gen/facet-targeting/error.d.ts.map +1 -1
  258. package/dist/document-models/resource-template/gen/facet-targeting/error.js +3 -9
  259. package/dist/document-models/resource-template/gen/facet-targeting/operations.d.ts +2 -2
  260. package/dist/document-models/resource-template/gen/facet-targeting/operations.d.ts.map +1 -1
  261. package/dist/document-models/resource-template/gen/facet-targeting/operations.js +0 -2
  262. package/dist/document-models/resource-template/gen/option-group-management/actions.d.ts +15 -3
  263. package/dist/document-models/resource-template/gen/option-group-management/actions.d.ts.map +1 -1
  264. package/dist/document-models/resource-template/gen/option-group-management/actions.js +1 -1
  265. package/dist/document-models/resource-template/gen/option-group-management/creators.d.ts +5 -2
  266. package/dist/document-models/resource-template/gen/option-group-management/creators.d.ts.map +1 -1
  267. package/dist/document-models/resource-template/gen/option-group-management/creators.js +4 -1
  268. package/dist/document-models/resource-template/gen/option-group-management/error.d.ts.map +1 -1
  269. package/dist/document-models/resource-template/gen/option-group-management/error.js +3 -9
  270. package/dist/document-models/resource-template/gen/option-group-management/operations.d.ts +5 -2
  271. package/dist/document-models/resource-template/gen/option-group-management/operations.d.ts.map +1 -1
  272. package/dist/document-models/resource-template/gen/option-group-management/operations.js +0 -2
  273. package/dist/document-models/resource-template/gen/ph-factories.d.ts.map +1 -1
  274. package/dist/document-models/resource-template/gen/ph-factories.js +1 -0
  275. package/dist/document-models/resource-template/gen/reducer.d.ts +1 -1
  276. package/dist/document-models/resource-template/gen/reducer.d.ts.map +1 -1
  277. package/dist/document-models/resource-template/gen/reducer.js +56 -21
  278. package/dist/document-models/resource-template/gen/schema/types.d.ts +34 -3
  279. package/dist/document-models/resource-template/gen/schema/types.d.ts.map +1 -1
  280. package/dist/document-models/resource-template/gen/schema/zod.d.ts +14 -5
  281. package/dist/document-models/resource-template/gen/schema/zod.d.ts.map +1 -1
  282. package/dist/document-models/resource-template/gen/schema/zod.js +43 -15
  283. package/dist/document-models/resource-template/gen/service-category-management/actions.d.ts +1 -1
  284. package/dist/document-models/resource-template/gen/service-category-management/actions.d.ts.map +1 -1
  285. package/dist/document-models/resource-template/gen/service-category-management/actions.js +1 -1
  286. package/dist/document-models/resource-template/gen/service-category-management/operations.d.ts +2 -2
  287. package/dist/document-models/resource-template/gen/service-category-management/operations.d.ts.map +1 -1
  288. package/dist/document-models/resource-template/gen/service-category-management/operations.js +0 -2
  289. package/dist/document-models/resource-template/gen/service-management/actions.d.ts +1 -1
  290. package/dist/document-models/resource-template/gen/service-management/actions.d.ts.map +1 -1
  291. package/dist/document-models/resource-template/gen/service-management/actions.js +1 -1
  292. package/dist/document-models/resource-template/gen/service-management/error.d.ts.map +1 -1
  293. package/dist/document-models/resource-template/gen/service-management/error.js +5 -17
  294. package/dist/document-models/resource-template/gen/service-management/operations.d.ts +2 -2
  295. package/dist/document-models/resource-template/gen/service-management/operations.d.ts.map +1 -1
  296. package/dist/document-models/resource-template/gen/service-management/operations.js +0 -2
  297. package/dist/document-models/resource-template/gen/template-management/actions.d.ts +1 -1
  298. package/dist/document-models/resource-template/gen/template-management/actions.d.ts.map +1 -1
  299. package/dist/document-models/resource-template/gen/template-management/actions.js +1 -1
  300. package/dist/document-models/resource-template/gen/template-management/operations.d.ts +2 -2
  301. package/dist/document-models/resource-template/gen/template-management/operations.d.ts.map +1 -1
  302. package/dist/document-models/resource-template/gen/template-management/operations.js +0 -2
  303. package/dist/document-models/resource-template/gen/types.d.ts.map +1 -1
  304. package/dist/document-models/resource-template/gen/utils.d.ts.map +1 -1
  305. package/dist/document-models/resource-template/gen/utils.js +1 -0
  306. package/dist/document-models/resource-template/hooks.d.ts +5 -2
  307. package/dist/document-models/resource-template/hooks.d.ts.map +1 -1
  308. package/dist/document-models/resource-template/hooks.js +3 -4
  309. package/dist/document-models/resource-template/index.d.ts +0 -4
  310. package/dist/document-models/resource-template/index.d.ts.map +1 -1
  311. package/dist/document-models/resource-template/index.js +0 -4
  312. package/dist/document-models/resource-template/module.d.ts +1 -1
  313. package/dist/document-models/resource-template/module.d.ts.map +1 -1
  314. package/dist/document-models/resource-template/module.js +1 -0
  315. package/dist/document-models/resource-template/src/reducers/audience-management.d.ts.map +1 -1
  316. package/dist/document-models/resource-template/src/reducers/audience-management.js +2 -2
  317. package/dist/document-models/resource-template/src/reducers/facet-preset-management.d.ts +59 -0
  318. package/dist/document-models/resource-template/src/reducers/facet-preset-management.d.ts.map +1 -0
  319. package/dist/document-models/resource-template/src/reducers/facet-preset-management.js +52 -0
  320. package/dist/document-models/resource-template/src/reducers/facet-targeting.d.ts.map +1 -1
  321. package/dist/document-models/resource-template/src/reducers/facet-targeting.js +8 -7
  322. package/dist/document-models/resource-template/src/reducers/option-group-management.d.ts.map +1 -1
  323. package/dist/document-models/resource-template/src/reducers/option-group-management.js +32 -6
  324. package/dist/document-models/resource-template/src/reducers/service-management.d.ts.map +1 -1
  325. package/dist/document-models/resource-template/src/reducers/service-management.js +13 -10
  326. package/dist/document-models/resource-template/tests/audience-management.test.d.ts +2 -0
  327. package/dist/document-models/resource-template/tests/audience-management.test.d.ts.map +1 -0
  328. package/dist/document-models/resource-template/tests/audience-management.test.js +25 -0
  329. package/dist/document-models/resource-template/tests/document-model.test.d.ts +10 -0
  330. package/dist/document-models/resource-template/tests/document-model.test.d.ts.map +1 -0
  331. package/dist/document-models/resource-template/tests/document-model.test.js +104 -0
  332. package/dist/document-models/resource-template/tests/facet-targeting.test.d.ts +2 -0
  333. package/dist/document-models/resource-template/tests/facet-targeting.test.d.ts.map +1 -0
  334. package/dist/document-models/resource-template/tests/facet-targeting.test.js +45 -0
  335. package/dist/document-models/resource-template/tests/option-group-management.test.d.ts +2 -0
  336. package/dist/document-models/resource-template/tests/option-group-management.test.d.ts.map +1 -0
  337. package/dist/document-models/resource-template/tests/option-group-management.test.js +65 -0
  338. package/dist/document-models/resource-template/tests/service-category-management.test.d.ts +2 -0
  339. package/dist/document-models/resource-template/tests/service-category-management.test.d.ts.map +1 -0
  340. package/dist/document-models/resource-template/tests/service-category-management.test.js +25 -0
  341. package/dist/document-models/resource-template/tests/service-management.test.d.ts +2 -0
  342. package/dist/document-models/resource-template/tests/service-management.test.d.ts.map +1 -0
  343. package/dist/document-models/resource-template/tests/service-management.test.js +55 -0
  344. package/dist/document-models/resource-template/tests/template-management.test.d.ts +2 -0
  345. package/dist/document-models/resource-template/tests/template-management.test.d.ts.map +1 -0
  346. package/dist/document-models/resource-template/tests/template-management.test.js +45 -0
  347. package/dist/document-models/service-offering/actions.d.ts +3 -0
  348. package/dist/document-models/service-offering/actions.d.ts.map +1 -1
  349. package/dist/document-models/service-offering/gen/document-model.d.ts.map +1 -1
  350. package/dist/document-models/service-offering/gen/document-model.js +104 -26
  351. package/dist/document-models/service-offering/gen/document-schema.d.ts +63 -417
  352. package/dist/document-models/service-offering/gen/document-schema.d.ts.map +1 -1
  353. package/dist/document-models/service-offering/gen/offering-management/actions.d.ts +1 -1
  354. package/dist/document-models/service-offering/gen/offering-management/actions.d.ts.map +1 -1
  355. package/dist/document-models/service-offering/gen/offering-management/actions.js +1 -1
  356. package/dist/document-models/service-offering/gen/offering-management/error.d.ts.map +1 -1
  357. package/dist/document-models/service-offering/gen/offering-management/error.js +6 -19
  358. package/dist/document-models/service-offering/gen/offering-management/operations.d.ts +2 -2
  359. package/dist/document-models/service-offering/gen/offering-management/operations.d.ts.map +1 -1
  360. package/dist/document-models/service-offering/gen/offering-management/operations.js +0 -2
  361. package/dist/document-models/service-offering/gen/option-group-management/actions.d.ts +1 -1
  362. package/dist/document-models/service-offering/gen/option-group-management/actions.d.ts.map +1 -1
  363. package/dist/document-models/service-offering/gen/option-group-management/actions.js +1 -1
  364. package/dist/document-models/service-offering/gen/option-group-management/error.d.ts.map +1 -1
  365. package/dist/document-models/service-offering/gen/option-group-management/error.js +3 -9
  366. package/dist/document-models/service-offering/gen/option-group-management/operations.d.ts +2 -2
  367. package/dist/document-models/service-offering/gen/option-group-management/operations.d.ts.map +1 -1
  368. package/dist/document-models/service-offering/gen/option-group-management/operations.js +0 -2
  369. package/dist/document-models/service-offering/gen/reducer.d.ts +1 -1
  370. package/dist/document-models/service-offering/gen/reducer.d.ts.map +1 -1
  371. package/dist/document-models/service-offering/gen/reducer.js +80 -33
  372. package/dist/document-models/service-offering/gen/schema/types.d.ts +87 -12
  373. package/dist/document-models/service-offering/gen/schema/types.d.ts.map +1 -1
  374. package/dist/document-models/service-offering/gen/schema/zod.d.ts +38 -8
  375. package/dist/document-models/service-offering/gen/schema/zod.d.ts.map +1 -1
  376. package/dist/document-models/service-offering/gen/schema/zod.js +103 -31
  377. package/dist/document-models/service-offering/gen/service-management/actions.d.ts +1 -1
  378. package/dist/document-models/service-offering/gen/service-management/actions.d.ts.map +1 -1
  379. package/dist/document-models/service-offering/gen/service-management/actions.js +1 -1
  380. package/dist/document-models/service-offering/gen/service-management/error.d.ts.map +1 -1
  381. package/dist/document-models/service-offering/gen/service-management/error.js +5 -17
  382. package/dist/document-models/service-offering/gen/service-management/operations.d.ts +2 -2
  383. package/dist/document-models/service-offering/gen/service-management/operations.d.ts.map +1 -1
  384. package/dist/document-models/service-offering/gen/service-management/operations.js +0 -2
  385. package/dist/document-models/service-offering/gen/tier-management/actions.d.ts +15 -3
  386. package/dist/document-models/service-offering/gen/tier-management/actions.d.ts.map +1 -1
  387. package/dist/document-models/service-offering/gen/tier-management/actions.js +1 -1
  388. package/dist/document-models/service-offering/gen/tier-management/creators.d.ts +5 -2
  389. package/dist/document-models/service-offering/gen/tier-management/creators.d.ts.map +1 -1
  390. package/dist/document-models/service-offering/gen/tier-management/creators.js +4 -1
  391. package/dist/document-models/service-offering/gen/tier-management/error.d.ts +37 -1
  392. package/dist/document-models/service-offering/gen/tier-management/error.d.ts.map +1 -1
  393. package/dist/document-models/service-offering/gen/tier-management/error.js +50 -13
  394. package/dist/document-models/service-offering/gen/tier-management/operations.d.ts +5 -2
  395. package/dist/document-models/service-offering/gen/tier-management/operations.d.ts.map +1 -1
  396. package/dist/document-models/service-offering/gen/tier-management/operations.js +0 -2
  397. package/dist/document-models/service-offering/gen/types.d.ts.map +1 -1
  398. package/dist/document-models/service-offering/hooks.d.ts +5 -2
  399. package/dist/document-models/service-offering/hooks.d.ts.map +1 -1
  400. package/dist/document-models/service-offering/hooks.js +3 -4
  401. package/dist/document-models/service-offering/index.d.ts +0 -4
  402. package/dist/document-models/service-offering/index.d.ts.map +1 -1
  403. package/dist/document-models/service-offering/index.js +0 -4
  404. package/dist/document-models/service-offering/module.d.ts.map +1 -1
  405. package/dist/document-models/service-offering/module.js +1 -0
  406. package/dist/document-models/service-offering/src/reducers/option-group-management.d.ts.map +1 -1
  407. package/dist/document-models/service-offering/src/reducers/option-group-management.js +11 -8
  408. package/dist/document-models/service-offering/src/reducers/service-management.d.ts.map +1 -1
  409. package/dist/document-models/service-offering/src/reducers/service-management.js +20 -12
  410. package/dist/document-models/service-offering/src/reducers/tier-management.d.ts.map +1 -1
  411. package/dist/document-models/service-offering/src/reducers/tier-management.js +131 -21
  412. package/dist/document-models/service-offering/tests/document-model.test.d.ts +10 -0
  413. package/dist/document-models/service-offering/tests/document-model.test.d.ts.map +1 -0
  414. package/dist/document-models/service-offering/tests/document-model.test.js +104 -0
  415. package/dist/document-models/service-offering/tests/offering-management.test.d.ts +2 -0
  416. package/dist/document-models/service-offering/tests/offering-management.test.d.ts.map +1 -0
  417. package/dist/document-models/service-offering/tests/offering-management.test.js +145 -0
  418. package/dist/document-models/service-offering/tests/option-group-management.test.d.ts +2 -0
  419. package/dist/document-models/service-offering/tests/option-group-management.test.d.ts.map +1 -0
  420. package/dist/document-models/service-offering/tests/option-group-management.test.js +35 -0
  421. package/dist/document-models/service-offering/tests/service-management.test.d.ts +2 -0
  422. package/dist/document-models/service-offering/tests/service-management.test.d.ts.map +1 -0
  423. package/dist/document-models/service-offering/tests/service-management.test.js +55 -0
  424. package/dist/document-models/service-offering/tests/tier-management.test.d.ts +2 -0
  425. package/dist/document-models/service-offering/tests/tier-management.test.d.ts.map +1 -0
  426. package/dist/document-models/service-offering/tests/tier-management.test.js +135 -0
  427. package/dist/document-models/service-subscriptions/actions.d.ts.map +1 -1
  428. package/dist/document-models/service-subscriptions/gen/categories/actions.d.ts +1 -1
  429. package/dist/document-models/service-subscriptions/gen/categories/actions.d.ts.map +1 -1
  430. package/dist/document-models/service-subscriptions/gen/categories/actions.js +1 -1
  431. package/dist/document-models/service-subscriptions/gen/categories/operations.d.ts +2 -2
  432. package/dist/document-models/service-subscriptions/gen/categories/operations.d.ts.map +1 -1
  433. package/dist/document-models/service-subscriptions/gen/categories/operations.js +0 -2
  434. package/dist/document-models/service-subscriptions/gen/document-model.d.ts.map +1 -1
  435. package/dist/document-models/service-subscriptions/gen/document-model.js +70 -70
  436. package/dist/document-models/service-subscriptions/gen/document-schema.d.ts +21 -151
  437. package/dist/document-models/service-subscriptions/gen/document-schema.d.ts.map +1 -1
  438. package/dist/document-models/service-subscriptions/gen/reducer.d.ts.map +1 -1
  439. package/dist/document-models/service-subscriptions/gen/reducer.js +26 -13
  440. package/dist/document-models/service-subscriptions/gen/schema/types.d.ts +13 -1
  441. package/dist/document-models/service-subscriptions/gen/schema/types.d.ts.map +1 -1
  442. package/dist/document-models/service-subscriptions/gen/schema/zod.d.ts +19 -5
  443. package/dist/document-models/service-subscriptions/gen/schema/zod.d.ts.map +1 -1
  444. package/dist/document-models/service-subscriptions/gen/schema/zod.js +21 -21
  445. package/dist/document-models/service-subscriptions/gen/subscriptions/actions.d.ts +1 -1
  446. package/dist/document-models/service-subscriptions/gen/subscriptions/actions.d.ts.map +1 -1
  447. package/dist/document-models/service-subscriptions/gen/subscriptions/actions.js +1 -1
  448. package/dist/document-models/service-subscriptions/gen/subscriptions/operations.d.ts +2 -2
  449. package/dist/document-models/service-subscriptions/gen/subscriptions/operations.d.ts.map +1 -1
  450. package/dist/document-models/service-subscriptions/gen/subscriptions/operations.js +0 -2
  451. package/dist/document-models/service-subscriptions/gen/types.d.ts.map +1 -1
  452. package/dist/document-models/service-subscriptions/gen/vendors/actions.d.ts +1 -1
  453. package/dist/document-models/service-subscriptions/gen/vendors/actions.d.ts.map +1 -1
  454. package/dist/document-models/service-subscriptions/gen/vendors/actions.js +1 -1
  455. package/dist/document-models/service-subscriptions/gen/vendors/operations.d.ts +2 -2
  456. package/dist/document-models/service-subscriptions/gen/vendors/operations.d.ts.map +1 -1
  457. package/dist/document-models/service-subscriptions/gen/vendors/operations.js +0 -2
  458. package/dist/document-models/service-subscriptions/hooks.d.ts +5 -2
  459. package/dist/document-models/service-subscriptions/hooks.d.ts.map +1 -1
  460. package/dist/document-models/service-subscriptions/hooks.js +3 -4
  461. package/dist/document-models/service-subscriptions/index.d.ts +0 -4
  462. package/dist/document-models/service-subscriptions/index.d.ts.map +1 -1
  463. package/dist/document-models/service-subscriptions/index.js +0 -4
  464. package/dist/document-models/service-subscriptions/module.d.ts.map +1 -1
  465. package/dist/document-models/service-subscriptions/module.js +1 -0
  466. package/dist/document-models/service-subscriptions/tests/categories.test.d.ts +2 -0
  467. package/dist/document-models/service-subscriptions/tests/categories.test.d.ts.map +1 -0
  468. package/dist/document-models/service-subscriptions/tests/categories.test.js +35 -0
  469. package/dist/document-models/service-subscriptions/tests/document-model.test.d.ts +10 -0
  470. package/dist/document-models/service-subscriptions/tests/document-model.test.d.ts.map +1 -0
  471. package/dist/document-models/service-subscriptions/tests/document-model.test.js +104 -0
  472. package/dist/document-models/service-subscriptions/tests/subscriptions.test.d.ts +2 -0
  473. package/dist/document-models/service-subscriptions/tests/subscriptions.test.d.ts.map +1 -0
  474. package/dist/document-models/service-subscriptions/tests/subscriptions.test.js +75 -0
  475. package/dist/document-models/service-subscriptions/tests/vendors.test.d.ts +2 -0
  476. package/dist/document-models/service-subscriptions/tests/vendors.test.d.ts.map +1 -0
  477. package/dist/document-models/service-subscriptions/tests/vendors.test.js +35 -0
  478. package/dist/document-models/snapshot-report/actions.d.ts +2 -1
  479. package/dist/document-models/snapshot-report/actions.d.ts.map +1 -1
  480. package/dist/document-models/snapshot-report/gen/accounts/actions.d.ts +1 -1
  481. package/dist/document-models/snapshot-report/gen/accounts/actions.d.ts.map +1 -1
  482. package/dist/document-models/snapshot-report/gen/accounts/actions.js +1 -1
  483. package/dist/document-models/snapshot-report/gen/accounts/error.d.ts.map +1 -1
  484. package/dist/document-models/snapshot-report/gen/accounts/error.js +3 -9
  485. package/dist/document-models/snapshot-report/gen/accounts/operations.d.ts +2 -2
  486. package/dist/document-models/snapshot-report/gen/accounts/operations.d.ts.map +1 -1
  487. package/dist/document-models/snapshot-report/gen/accounts/operations.js +0 -2
  488. package/dist/document-models/snapshot-report/gen/balances/actions.d.ts +1 -1
  489. package/dist/document-models/snapshot-report/gen/balances/actions.d.ts.map +1 -1
  490. package/dist/document-models/snapshot-report/gen/balances/actions.js +1 -1
  491. package/dist/document-models/snapshot-report/gen/balances/error.d.ts.map +1 -1
  492. package/dist/document-models/snapshot-report/gen/balances/error.js +4 -12
  493. package/dist/document-models/snapshot-report/gen/balances/operations.d.ts +2 -2
  494. package/dist/document-models/snapshot-report/gen/balances/operations.d.ts.map +1 -1
  495. package/dist/document-models/snapshot-report/gen/balances/operations.js +0 -2
  496. package/dist/document-models/snapshot-report/gen/configuration/actions.d.ts +10 -6
  497. package/dist/document-models/snapshot-report/gen/configuration/actions.d.ts.map +1 -1
  498. package/dist/document-models/snapshot-report/gen/configuration/actions.js +1 -1
  499. package/dist/document-models/snapshot-report/gen/configuration/creators.d.ts +4 -3
  500. package/dist/document-models/snapshot-report/gen/configuration/creators.d.ts.map +1 -1
  501. package/dist/document-models/snapshot-report/gen/configuration/creators.js +3 -2
  502. package/dist/document-models/snapshot-report/gen/configuration/operations.d.ts +4 -3
  503. package/dist/document-models/snapshot-report/gen/configuration/operations.d.ts.map +1 -1
  504. package/dist/document-models/snapshot-report/gen/configuration/operations.js +0 -2
  505. package/dist/document-models/snapshot-report/gen/document-model.d.ts.map +1 -1
  506. package/dist/document-models/snapshot-report/gen/document-model.js +22 -11
  507. package/dist/document-models/snapshot-report/gen/document-schema.d.ts +36 -246
  508. package/dist/document-models/snapshot-report/gen/document-schema.d.ts.map +1 -1
  509. package/dist/document-models/snapshot-report/gen/ph-factories.js +1 -1
  510. package/dist/document-models/snapshot-report/gen/reducer.d.ts.map +1 -1
  511. package/dist/document-models/snapshot-report/gen/reducer.js +42 -20
  512. package/dist/document-models/snapshot-report/gen/schema/types.d.ts +22 -8
  513. package/dist/document-models/snapshot-report/gen/schema/types.d.ts.map +1 -1
  514. package/dist/document-models/snapshot-report/gen/schema/zod.d.ts +40 -11
  515. package/dist/document-models/snapshot-report/gen/schema/zod.d.ts.map +1 -1
  516. package/dist/document-models/snapshot-report/gen/schema/zod.js +34 -28
  517. package/dist/document-models/snapshot-report/gen/transactions/actions.d.ts +1 -1
  518. package/dist/document-models/snapshot-report/gen/transactions/actions.d.ts.map +1 -1
  519. package/dist/document-models/snapshot-report/gen/transactions/actions.js +1 -1
  520. package/dist/document-models/snapshot-report/gen/transactions/error.d.ts.map +1 -1
  521. package/dist/document-models/snapshot-report/gen/transactions/error.js +2 -6
  522. package/dist/document-models/snapshot-report/gen/transactions/operations.d.ts +2 -2
  523. package/dist/document-models/snapshot-report/gen/transactions/operations.d.ts.map +1 -1
  524. package/dist/document-models/snapshot-report/gen/transactions/operations.js +0 -2
  525. package/dist/document-models/snapshot-report/gen/types.d.ts.map +1 -1
  526. package/dist/document-models/snapshot-report/gen/utils.js +1 -1
  527. package/dist/document-models/snapshot-report/hooks.d.ts +5 -2
  528. package/dist/document-models/snapshot-report/hooks.d.ts.map +1 -1
  529. package/dist/document-models/snapshot-report/hooks.js +3 -4
  530. package/dist/document-models/snapshot-report/index.d.ts +0 -4
  531. package/dist/document-models/snapshot-report/index.d.ts.map +1 -1
  532. package/dist/document-models/snapshot-report/index.js +0 -4
  533. package/dist/document-models/snapshot-report/module.d.ts.map +1 -1
  534. package/dist/document-models/snapshot-report/module.js +1 -0
  535. package/dist/document-models/snapshot-report/src/reducers/balances.d.ts.map +1 -1
  536. package/dist/document-models/snapshot-report/src/reducers/balances.js +37 -21
  537. package/dist/document-models/snapshot-report/src/reducers/configuration.d.ts.map +1 -1
  538. package/dist/document-models/snapshot-report/src/reducers/configuration.js +11 -3
  539. package/dist/document-models/snapshot-report/tests/accounts.test.d.ts +2 -0
  540. package/dist/document-models/snapshot-report/tests/accounts.test.d.ts.map +1 -0
  541. package/dist/document-models/snapshot-report/tests/accounts.test.js +35 -0
  542. package/dist/document-models/snapshot-report/tests/balances.test.d.ts +2 -0
  543. package/dist/document-models/snapshot-report/tests/balances.test.d.ts.map +1 -0
  544. package/dist/document-models/snapshot-report/tests/balances.test.js +45 -0
  545. package/dist/document-models/snapshot-report/tests/configuration.test.d.ts +2 -0
  546. package/dist/document-models/snapshot-report/tests/configuration.test.d.ts.map +1 -0
  547. package/dist/document-models/snapshot-report/tests/configuration.test.js +75 -0
  548. package/dist/document-models/snapshot-report/tests/document-model.test.d.ts +10 -0
  549. package/dist/document-models/snapshot-report/tests/document-model.test.d.ts.map +1 -0
  550. package/dist/document-models/snapshot-report/tests/document-model.test.js +104 -0
  551. package/dist/document-models/snapshot-report/tests/transactions.test.d.ts +2 -0
  552. package/dist/document-models/snapshot-report/tests/transactions.test.d.ts.map +1 -0
  553. package/dist/document-models/snapshot-report/tests/transactions.test.js +45 -0
  554. package/dist/editors/accounts-editor/editor.d.ts.map +1 -1
  555. package/dist/editors/accounts-editor/editor.js +25 -6
  556. package/dist/editors/billing-statement/components/lineItemsTable.js +8 -8
  557. package/dist/editors/billing-statement/editor.d.ts.map +1 -1
  558. package/dist/editors/billing-statement/editor.js +15 -16
  559. package/dist/editors/billing-statement/lineItemTags/lineItemTags.js +5 -5
  560. package/dist/editors/builder-team-admin/components/ResourcesServices.d.ts.map +1 -1
  561. package/dist/editors/builder-team-admin/components/ResourcesServices.js +3 -1
  562. package/dist/editors/builder-team-admin/components/overview/TeamMembersOverview.d.ts.map +1 -1
  563. package/dist/editors/builder-team-admin/components/overview/TeamMembersOverview.js +20 -3
  564. package/dist/editors/builder-team-admin/components/team-members.d.ts.map +1 -1
  565. package/dist/editors/builder-team-admin/components/team-members.js +20 -5
  566. package/dist/editors/builder-team-admin/hooks/useExpenseReportAutoPlacement.d.ts.map +1 -1
  567. package/dist/editors/builder-team-admin/hooks/useExpenseReportAutoPlacement.js +45 -17
  568. package/dist/editors/builder-team-admin/hooks/useSnapshotReportAutoPlacement.d.ts.map +1 -1
  569. package/dist/editors/builder-team-admin/hooks/useSnapshotReportAutoPlacement.js +45 -17
  570. package/dist/editors/contributor-billing/components/DriveExplorer.d.ts.map +1 -1
  571. package/dist/editors/contributor-billing/components/DriveExplorer.js +2 -1
  572. package/dist/editors/contributor-billing/components/FolderTree.d.ts.map +1 -1
  573. package/dist/editors/contributor-billing/components/FolderTree.js +72 -11
  574. package/dist/editors/contributor-billing/components/FolderTreeErrorBoundary.d.ts +24 -0
  575. package/dist/editors/contributor-billing/components/FolderTreeErrorBoundary.d.ts.map +1 -0
  576. package/dist/editors/contributor-billing/components/FolderTreeErrorBoundary.js +41 -0
  577. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderStats.d.ts.map +1 -1
  578. package/dist/editors/contributor-billing/components/InvoiceTable/HeaderStats.js +10 -3
  579. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.d.ts.map +1 -1
  580. package/dist/editors/contributor-billing/components/InvoiceTable/InvoiceTable.js +65 -28
  581. package/dist/editors/contributor-billing/components/InvoiceTable/NotificationDialog.d.ts +11 -0
  582. package/dist/editors/contributor-billing/components/InvoiceTable/NotificationDialog.d.ts.map +1 -0
  583. package/dist/editors/contributor-billing/components/InvoiceTable/NotificationDialog.js +8 -0
  584. package/dist/editors/expense-report/components/AddReportToRemoteDrive.d.ts +1 -1
  585. package/dist/editors/expense-report/editor.d.ts.map +1 -1
  586. package/dist/editors/expense-report/editor.js +43 -6
  587. package/dist/editors/expense-report/hooks/useSyncWallet.d.ts.map +1 -1
  588. package/dist/editors/expense-report/hooks/useSyncWallet.js +4 -0
  589. package/dist/editors/invoice/exportUBL.js +5 -5
  590. package/dist/editors/resource-template-editor/components/FacetTargeting.d.ts +1 -1
  591. package/dist/editors/resource-template-editor/components/FacetTargeting.d.ts.map +1 -1
  592. package/dist/editors/resource-template-editor/components/FacetTargeting.js +526 -19
  593. package/dist/editors/resource-template-editor/components/TemplateInfo.d.ts +1 -1
  594. package/dist/editors/resource-template-editor/components/TemplateInfo.d.ts.map +1 -1
  595. package/dist/editors/resource-template-editor/components/TemplateInfo.js +604 -9
  596. package/dist/editors/resource-template-editor/editor.d.ts.map +1 -1
  597. package/dist/editors/resource-template-editor/editor.js +2 -2
  598. package/dist/editors/resource-template-editor/module.d.ts +1 -1
  599. package/dist/editors/resource-template-editor/module.d.ts.map +1 -1
  600. package/dist/editors/resource-template-editor/module.js +1 -1
  601. package/dist/editors/service-offering-editor/components/EditName.js +1 -1
  602. package/dist/editors/service-offering-editor/components/OfferingInfo.d.ts +1 -1
  603. package/dist/editors/service-offering-editor/components/OfferingInfo.d.ts.map +1 -1
  604. package/dist/editors/service-offering-editor/components/OfferingProgress.d.ts +10 -0
  605. package/dist/editors/service-offering-editor/components/OfferingProgress.d.ts.map +1 -0
  606. package/dist/editors/service-offering-editor/components/OfferingProgress.js +240 -0
  607. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts +1 -1
  608. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts.map +1 -1
  609. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.js +111 -4
  610. package/dist/editors/service-offering-editor/components/ScopeAndFacets.d.ts +1 -1
  611. package/dist/editors/service-offering-editor/components/ScopeAndFacets.d.ts.map +1 -1
  612. package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts +1 -1
  613. package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts.map +1 -1
  614. package/dist/editors/service-offering-editor/components/ServiceCatalog.js +282 -1
  615. package/dist/editors/service-offering-editor/components/ServicesList.d.ts +1 -1
  616. package/dist/editors/service-offering-editor/components/ServicesList.d.ts.map +1 -1
  617. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts +1 -1
  618. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts.map +1 -1
  619. package/dist/editors/service-offering-editor/components/TheMatrix.js +1012 -134
  620. package/dist/editors/service-offering-editor/components/TierDefinition.d.ts +1 -1
  621. package/dist/editors/service-offering-editor/components/TierDefinition.d.ts.map +1 -1
  622. package/dist/editors/service-offering-editor/components/TierDefinition.js +616 -29
  623. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.d.ts +11 -0
  624. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.d.ts.map +1 -0
  625. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.js +405 -0
  626. package/dist/editors/service-offering-editor/components/TiersList.d.ts +1 -1
  627. package/dist/editors/service-offering-editor/components/TiersList.d.ts.map +1 -1
  628. package/dist/editors/service-offering-editor/components/TiersList.js +1 -1
  629. package/dist/editors/service-offering-editor/components/pricing-utils.d.ts +10 -0
  630. package/dist/editors/service-offering-editor/components/pricing-utils.d.ts.map +1 -0
  631. package/dist/editors/service-offering-editor/components/pricing-utils.js +65 -0
  632. package/dist/editors/service-offering-editor/editor.d.ts.map +1 -1
  633. package/dist/editors/service-offering-editor/editor.js +2 -2
  634. package/dist/editors/service-offering-editor/module.d.ts +1 -1
  635. package/dist/editors/service-offering-editor/module.d.ts.map +1 -1
  636. package/dist/editors/service-offering-editor/module.js +1 -1
  637. package/dist/editors/service-subscriptions-editor/components/SubscriptionsList.js +1 -1
  638. package/dist/editors/snapshot-report-editor/components/AddReportToRemoteDrive.js +1 -1
  639. package/dist/editors/snapshot-report-editor/components/SetOwner.d.ts +4 -4
  640. package/dist/editors/snapshot-report-editor/components/SetOwner.d.ts.map +1 -1
  641. package/dist/editors/snapshot-report-editor/components/SetOwner.js +25 -14
  642. package/dist/editors/snapshot-report-editor/editor.d.ts.map +1 -1
  643. package/dist/editors/snapshot-report-editor/editor.js +14 -7
  644. package/dist/editors/snapshot-report-editor/hooks/useSyncSnapshotAccount.d.ts.map +1 -1
  645. package/dist/editors/snapshot-report-editor/hooks/useSyncSnapshotAccount.js +133 -8
  646. package/dist/editors/snapshot-report-editor/utils/flowTypeCalculations.d.ts +4 -0
  647. package/dist/editors/snapshot-report-editor/utils/flowTypeCalculations.d.ts.map +1 -1
  648. package/dist/editors/snapshot-report-editor/utils/flowTypeCalculations.js +28 -0
  649. package/dist/index.d.ts +1 -1
  650. package/dist/powerhouse.manifest.json +20 -2
  651. package/dist/scripts/alchemy/alchemyEnvironment.d.ts +2 -2
  652. package/dist/scripts/alchemy/alchemyEnvironment.d.ts.map +1 -1
  653. package/dist/scripts/alchemy/alchemyEnvironment.js +31 -10
  654. package/dist/style.css +1327 -1108
  655. package/dist/subgraphs/budget-statements/resolvers.js +2 -2
  656. package/dist/subgraphs/expense-report/resolvers.d.ts.map +1 -1
  657. package/dist/subgraphs/expense-report/resolvers.js +12 -0
  658. package/dist/subgraphs/expense-report/schema.d.ts.map +1 -1
  659. package/dist/subgraphs/expense-report/schema.js +9 -0
  660. package/dist/subgraphs/index.d.ts +2 -8
  661. package/dist/subgraphs/index.d.ts.map +1 -1
  662. package/dist/subgraphs/index.js +2 -8
  663. package/dist/subgraphs/invoice-addon/schema.d.ts.map +1 -1
  664. package/dist/subgraphs/invoice-addon/schema.js +5 -7
  665. package/dist/subgraphs/snapshot-report/resolvers.d.ts.map +1 -1
  666. package/dist/subgraphs/snapshot-report/resolvers.js +15 -3
  667. package/dist/subgraphs/snapshot-report/schema.d.ts.map +1 -1
  668. package/dist/subgraphs/snapshot-report/schema.js +11 -4
  669. package/package.json +26 -21
  670. package/dist/editors/accounts-editor/components/AccountsFilter.d.ts +0 -8
  671. package/dist/editors/accounts-editor/components/AccountsFilter.d.ts.map +0 -1
  672. package/dist/editors/accounts-editor/components/AccountsFilter.js +0 -34
  673. package/dist/editors/billing-statement/components/objectSetTable.d.ts +0 -7
  674. package/dist/editors/billing-statement/components/objectSetTable.d.ts.map +0 -1
  675. package/dist/editors/billing-statement/components/objectSetTable.js +0 -96
  676. package/dist/subgraphs/account-transactions/index.d.ts +0 -11
  677. package/dist/subgraphs/account-transactions/index.d.ts.map +0 -1
  678. package/dist/subgraphs/account-transactions/index.js +0 -11
  679. package/dist/subgraphs/account-transactions/resolvers.d.ts +0 -3
  680. package/dist/subgraphs/account-transactions/resolvers.d.ts.map +0 -1
  681. package/dist/subgraphs/account-transactions/resolvers.js +0 -168
  682. package/dist/subgraphs/account-transactions/schema.d.ts +0 -3
  683. package/dist/subgraphs/account-transactions/schema.d.ts.map +0 -1
  684. package/dist/subgraphs/account-transactions/schema.js +0 -129
  685. package/dist/subgraphs/accounts/index.d.ts +0 -11
  686. package/dist/subgraphs/accounts/index.d.ts.map +0 -1
  687. package/dist/subgraphs/accounts/index.js +0 -11
  688. package/dist/subgraphs/accounts/resolvers.d.ts +0 -3
  689. package/dist/subgraphs/accounts/resolvers.d.ts.map +0 -1
  690. package/dist/subgraphs/accounts/resolvers.js +0 -120
  691. package/dist/subgraphs/accounts/schema.d.ts +0 -3
  692. package/dist/subgraphs/accounts/schema.d.ts.map +0 -1
  693. package/dist/subgraphs/accounts/schema.js +0 -75
  694. package/dist/subgraphs/billing-statement/index.d.ts +0 -11
  695. package/dist/subgraphs/billing-statement/index.d.ts.map +0 -1
  696. package/dist/subgraphs/billing-statement/index.js +0 -11
  697. package/dist/subgraphs/billing-statement/resolvers.d.ts +0 -3
  698. package/dist/subgraphs/billing-statement/resolvers.d.ts.map +0 -1
  699. package/dist/subgraphs/billing-statement/resolvers.js +0 -156
  700. package/dist/subgraphs/billing-statement/schema.d.ts +0 -3
  701. package/dist/subgraphs/billing-statement/schema.d.ts.map +0 -1
  702. package/dist/subgraphs/billing-statement/schema.js +0 -110
  703. package/dist/subgraphs/invoice/index.d.ts +0 -11
  704. package/dist/subgraphs/invoice/index.d.ts.map +0 -1
  705. package/dist/subgraphs/invoice/index.js +0 -11
  706. package/dist/subgraphs/invoice/resolvers.d.ts +0 -3
  707. package/dist/subgraphs/invoice/resolvers.d.ts.map +0 -1
  708. package/dist/subgraphs/invoice/resolvers.js +0 -408
  709. package/dist/subgraphs/invoice/schema.d.ts +0 -3
  710. package/dist/subgraphs/invoice/schema.d.ts.map +0 -1
  711. package/dist/subgraphs/invoice/schema.js +0 -390
  712. package/dist/subgraphs/service-offering/index.d.ts +0 -11
  713. package/dist/subgraphs/service-offering/index.d.ts.map +0 -1
  714. package/dist/subgraphs/service-offering/index.js +0 -11
  715. package/dist/subgraphs/service-offering/resolvers.d.ts +0 -3
  716. package/dist/subgraphs/service-offering/resolvers.d.ts.map +0 -1
  717. package/dist/subgraphs/service-offering/resolvers.js +0 -432
  718. package/dist/subgraphs/service-offering/schema.d.ts +0 -3
  719. package/dist/subgraphs/service-offering/schema.d.ts.map +0 -1
  720. package/dist/subgraphs/service-offering/schema.js +0 -386
  721. package/dist/subgraphs/service-subscriptions/index.d.ts +0 -11
  722. package/dist/subgraphs/service-subscriptions/index.d.ts.map +0 -1
  723. package/dist/subgraphs/service-subscriptions/index.js +0 -11
  724. package/dist/subgraphs/service-subscriptions/resolvers.d.ts +0 -3
  725. package/dist/subgraphs/service-subscriptions/resolvers.d.ts.map +0 -1
  726. package/dist/subgraphs/service-subscriptions/resolvers.js +0 -228
  727. package/dist/subgraphs/service-subscriptions/schema.d.ts +0 -3
  728. package/dist/subgraphs/service-subscriptions/schema.d.ts.map +0 -1
  729. package/dist/subgraphs/service-subscriptions/schema.js +0 -193
@@ -1,7 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useState, useMemo, useEffect, useRef, useCallback } from "react";
3
3
  import { generateId } from "document-model/core";
4
- import { addServiceLevel, updateServiceLevel, addUsageLimit, updateUsageLimit, removeUsageLimit, addService, } from "../../../document-models/service-offering/gen/creators.js";
4
+ import { RECURRING_BILLING_CYCLES, BILLING_CYCLE_SHORT_LABELS, formatPrice, getMonthlyEquivalent, } from "./pricing-utils.js";
5
+ import { addServiceLevel, updateServiceLevel, addUsageLimit, updateUsageLimit, removeUsageLimit, addService, updateService, } from "../../../document-models/service-offering/gen/creators.js";
6
+ import { useResourceTemplateDocumentsInSelectedDrive } from "../../../document-models/resource-template/hooks.js";
5
7
  const SERVICE_LEVELS = [
6
8
  {
7
9
  value: "INCLUDED",
@@ -41,38 +43,6 @@ const SERVICE_LEVELS = [
41
43
  },
42
44
  ];
43
45
  const UNGROUPED_ID = "__ungrouped__";
44
- const FACET_CATEGORIES = {
45
- FUNCTION: {
46
- label: "SNO Function",
47
- options: [
48
- { id: "operational-hub", label: "Operational Hub" },
49
- { id: "embryonic-hub", label: "Embryonic Hub" },
50
- ],
51
- },
52
- LEGAL_ENTITY: {
53
- label: "Legal Entity",
54
- options: [
55
- { id: "swiss-association", label: "Swiss Association" },
56
- { id: "bvi-ltd", label: "BVI Ltd" },
57
- { id: "unaffiliated", label: "Unaffiliated" },
58
- ],
59
- },
60
- TEAM_STRUCTURE: {
61
- label: "Team",
62
- options: [
63
- { id: "remote-team", label: "Remote" },
64
- { id: "on-premise", label: "On-Premise" },
65
- { id: "hybrid", label: "Hybrid" },
66
- ],
67
- },
68
- ANONYMITY: {
69
- label: "Anonymity",
70
- options: [
71
- { id: "high-anonymity", label: "High" },
72
- { id: "highest-anonymity", label: "Highest" },
73
- ],
74
- },
75
- };
76
46
  const matrixStyles = `
77
47
  .matrix {
78
48
  background: var(--so-white);
@@ -268,6 +238,40 @@ const matrixStyles = `
268
238
  color: var(--so-violet-200);
269
239
  }
270
240
 
241
+ /* Billing Cycle Selector in Tier Header */
242
+ .matrix__tier-cycle-select {
243
+ font-family: var(--so-font-sans);
244
+ font-size: 0.625rem;
245
+ color: var(--so-slate-600);
246
+ background: var(--so-white);
247
+ border: 1px solid var(--so-slate-200);
248
+ border-radius: var(--so-radius-sm);
249
+ padding: 0.25rem 0.5rem;
250
+ cursor: pointer;
251
+ outline: none;
252
+ transition: var(--so-transition-fast);
253
+ margin-top: 0.25rem;
254
+ }
255
+
256
+ .matrix__tier-cycle-select:hover {
257
+ border-color: var(--so-slate-300);
258
+ }
259
+
260
+ .matrix__tier-cycle-select:focus {
261
+ border-color: var(--so-violet-400);
262
+ box-shadow: 0 0 0 2px var(--so-violet-100);
263
+ }
264
+
265
+ .matrix__tier-header--selected .matrix__tier-cycle-select {
266
+ background: var(--so-violet-500);
267
+ border-color: var(--so-violet-400);
268
+ color: var(--so-white);
269
+ }
270
+
271
+ .matrix__tier-header--selected .matrix__tier-cycle-select:focus {
272
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
273
+ }
274
+
271
275
  /* Section Header */
272
276
  .matrix__section-header {
273
277
  background: var(--so-slate-100);
@@ -437,6 +441,319 @@ const matrixStyles = `
437
441
  color: var(--so-slate-700);
438
442
  }
439
443
 
444
+ /* Premium Only Badge - Exclusivity Signal (Toggle Button) */
445
+ .matrix__premium-badge {
446
+ display: inline-flex;
447
+ align-items: center;
448
+ gap: 0.25rem;
449
+ padding: 0.125rem 0.5rem;
450
+ margin-left: 0.5rem;
451
+ font-size: 0.5625rem;
452
+ font-weight: 700;
453
+ text-transform: uppercase;
454
+ letter-spacing: 0.04em;
455
+ border-radius: 100px;
456
+ cursor: pointer;
457
+ transition: all var(--so-transition-fast);
458
+ font-family: var(--so-font-sans);
459
+ }
460
+
461
+ .matrix__premium-badge--active {
462
+ color: var(--so-amber-700);
463
+ background: linear-gradient(135deg, var(--so-amber-100) 0%, var(--so-amber-50) 100%);
464
+ border: 1px solid var(--so-amber-200);
465
+ }
466
+
467
+ .matrix__premium-badge--active:hover {
468
+ background: linear-gradient(135deg, var(--so-amber-200) 0%, var(--so-amber-100) 100%);
469
+ border-color: var(--so-amber-300);
470
+ }
471
+
472
+ .matrix__premium-badge--inactive {
473
+ color: var(--so-slate-400);
474
+ background: var(--so-slate-50);
475
+ border: 1px dashed var(--so-slate-200);
476
+ opacity: 0.6;
477
+ }
478
+
479
+ .matrix__premium-badge--inactive:hover {
480
+ opacity: 1;
481
+ color: var(--so-amber-600);
482
+ background: var(--so-amber-50);
483
+ border: 1px dashed var(--so-amber-300);
484
+ }
485
+
486
+ .matrix__premium-badge--active svg {
487
+ width: 0.625rem;
488
+ height: 0.625rem;
489
+ fill: var(--so-amber-500);
490
+ stroke: var(--so-amber-600);
491
+ }
492
+
493
+ .matrix__premium-badge--inactive svg {
494
+ width: 0.625rem;
495
+ height: 0.625rem;
496
+ fill: none;
497
+ stroke: currentColor;
498
+ }
499
+
500
+ /* Incomplete Services Warning */
501
+ .matrix__incomplete-warning {
502
+ display: flex;
503
+ align-items: flex-start;
504
+ gap: 0.875rem;
505
+ padding: 1rem 1.25rem;
506
+ margin-bottom: 1rem;
507
+ background: var(--so-amber-50);
508
+ border: 1px solid var(--so-amber-200);
509
+ border-radius: var(--so-radius-md);
510
+ animation: matrix-warning-pulse 2s ease-in-out infinite;
511
+ }
512
+
513
+ @keyframes matrix-warning-pulse {
514
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
515
+ 50% { box-shadow: 0 0 0 4px rgba(245, 158, 11, 0.1); }
516
+ }
517
+
518
+ .matrix__incomplete-icon {
519
+ flex-shrink: 0;
520
+ width: 1.5rem;
521
+ height: 1.5rem;
522
+ color: var(--so-amber-600);
523
+ }
524
+
525
+ .matrix__incomplete-icon svg {
526
+ width: 100%;
527
+ height: 100%;
528
+ }
529
+
530
+ .matrix__incomplete-content {
531
+ display: flex;
532
+ flex-direction: column;
533
+ gap: 0.25rem;
534
+ }
535
+
536
+ .matrix__incomplete-title {
537
+ font-size: 0.875rem;
538
+ font-weight: 600;
539
+ color: var(--so-amber-800);
540
+ }
541
+
542
+ .matrix__incomplete-text {
543
+ font-size: 0.8125rem;
544
+ color: var(--so-amber-700);
545
+ line-height: 1.5;
546
+ }
547
+
548
+ .matrix__incomplete-text strong {
549
+ font-weight: 600;
550
+ color: var(--so-amber-900);
551
+ }
552
+
553
+ /* Bulk Actions Toolbar */
554
+ .matrix__bulk-actions {
555
+ margin-bottom: 1rem;
556
+ }
557
+
558
+ .matrix__bulk-toggle {
559
+ display: flex;
560
+ align-items: center;
561
+ gap: 0.5rem;
562
+ padding: 0.625rem 1rem;
563
+ font-family: var(--so-font-sans);
564
+ font-size: 0.8125rem;
565
+ font-weight: 600;
566
+ color: var(--so-slate-600);
567
+ background: var(--so-slate-100);
568
+ border: 1px solid var(--so-slate-200);
569
+ border-radius: var(--so-radius-md);
570
+ cursor: pointer;
571
+ transition: all var(--so-transition-fast);
572
+ }
573
+
574
+ .matrix__bulk-toggle:hover {
575
+ background: var(--so-slate-200);
576
+ color: var(--so-slate-700);
577
+ }
578
+
579
+ .matrix__bulk-toggle svg:first-child {
580
+ width: 1rem;
581
+ height: 1rem;
582
+ }
583
+
584
+ .matrix__bulk-toggle-arrow {
585
+ width: 0.875rem;
586
+ height: 0.875rem;
587
+ margin-left: auto;
588
+ transition: transform var(--so-transition-fast);
589
+ }
590
+
591
+ .matrix__bulk-toggle-arrow--open {
592
+ transform: rotate(180deg);
593
+ }
594
+
595
+ .matrix__bulk-panel {
596
+ margin-top: 0.75rem;
597
+ padding: 1rem;
598
+ background: var(--so-slate-50);
599
+ border: 1px solid var(--so-slate-200);
600
+ border-radius: var(--so-radius-md);
601
+ display: flex;
602
+ flex-direction: column;
603
+ gap: 1rem;
604
+ animation: so-scale-in var(--so-transition-fast) ease-out;
605
+ }
606
+
607
+ .matrix__bulk-section {
608
+ display: flex;
609
+ flex-direction: column;
610
+ gap: 0.5rem;
611
+ }
612
+
613
+ .matrix__bulk-label {
614
+ font-size: 0.6875rem;
615
+ font-weight: 600;
616
+ text-transform: uppercase;
617
+ letter-spacing: 0.05em;
618
+ color: var(--so-slate-500);
619
+ }
620
+
621
+ .matrix__bulk-buttons,
622
+ .matrix__bulk-copy {
623
+ display: flex;
624
+ flex-wrap: wrap;
625
+ gap: 0.5rem;
626
+ }
627
+
628
+ .matrix__bulk-btn {
629
+ display: flex;
630
+ align-items: center;
631
+ gap: 0.375rem;
632
+ padding: 0.5rem 0.875rem;
633
+ font-family: var(--so-font-sans);
634
+ font-size: 0.75rem;
635
+ font-weight: 500;
636
+ border-radius: var(--so-radius-sm);
637
+ border: 1px solid;
638
+ cursor: pointer;
639
+ transition: all var(--so-transition-fast);
640
+ }
641
+
642
+ .matrix__bulk-btn svg {
643
+ width: 0.875rem;
644
+ height: 0.875rem;
645
+ }
646
+
647
+ .matrix__bulk-btn--include {
648
+ background: var(--so-emerald-50);
649
+ border-color: var(--so-emerald-200);
650
+ color: var(--so-emerald-700);
651
+ }
652
+
653
+ .matrix__bulk-btn--include:hover {
654
+ background: var(--so-emerald-100);
655
+ border-color: var(--so-emerald-300);
656
+ }
657
+
658
+ .matrix__bulk-btn--clear {
659
+ background: var(--so-rose-50);
660
+ border-color: var(--so-rose-200);
661
+ color: var(--so-rose-700);
662
+ }
663
+
664
+ .matrix__bulk-btn--clear:hover {
665
+ background: var(--so-rose-100);
666
+ border-color: var(--so-rose-300);
667
+ }
668
+
669
+ .matrix__bulk-btn--copy {
670
+ background: var(--so-sky-50);
671
+ border-color: var(--so-sky-200);
672
+ color: var(--so-sky-700);
673
+ }
674
+
675
+ .matrix__bulk-btn--copy:hover {
676
+ background: var(--so-sky-100);
677
+ border-color: var(--so-sky-300);
678
+ }
679
+
680
+ /* Pattern Presets Section */
681
+ .matrix__bulk-patterns {
682
+ border-top: 1px dashed var(--so-slate-200);
683
+ padding-top: 1rem;
684
+ margin-top: 0.5rem;
685
+ }
686
+
687
+ .matrix__bulk-label-icon {
688
+ width: 1rem;
689
+ height: 1rem;
690
+ vertical-align: middle;
691
+ margin-right: 0.25rem;
692
+ }
693
+
694
+ .matrix__pattern-grid {
695
+ display: grid;
696
+ grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
697
+ gap: 0.75rem;
698
+ margin-top: 0.5rem;
699
+ }
700
+
701
+ .matrix__pattern-btn {
702
+ display: flex;
703
+ flex-direction: column;
704
+ align-items: center;
705
+ gap: 0.25rem;
706
+ padding: 0.875rem 0.75rem;
707
+ background: linear-gradient(135deg, var(--so-white) 0%, var(--so-slate-50) 100%);
708
+ border: 1px solid var(--so-slate-200);
709
+ border-radius: var(--so-radius-md);
710
+ cursor: pointer;
711
+ transition: all var(--so-transition-fast);
712
+ text-align: center;
713
+ }
714
+
715
+ .matrix__pattern-btn:hover {
716
+ transform: translateY(-2px);
717
+ box-shadow: var(--so-shadow-md);
718
+ border-color: var(--so-violet-300);
719
+ background: linear-gradient(135deg, var(--so-violet-50) 0%, var(--so-white) 100%);
720
+ }
721
+
722
+ .matrix__pattern-btn:active {
723
+ transform: translateY(0);
724
+ }
725
+
726
+ .matrix__pattern-icon {
727
+ font-size: 1.5rem;
728
+ line-height: 1;
729
+ }
730
+
731
+ .matrix__pattern-name {
732
+ font-size: 0.8125rem;
733
+ font-weight: 600;
734
+ color: var(--so-slate-700);
735
+ }
736
+
737
+ .matrix__pattern-desc {
738
+ font-size: 0.6875rem;
739
+ color: var(--so-slate-500);
740
+ line-height: 1.3;
741
+ }
742
+
743
+ .matrix__pattern-btn--simple {
744
+ padding: 0.625rem 0.75rem;
745
+ flex-direction: row;
746
+ gap: 0.5rem;
747
+ }
748
+
749
+ .matrix__pattern-btn--simple .matrix__pattern-icon {
750
+ font-size: 1rem;
751
+ }
752
+
753
+ .matrix__pattern-btn--simple .matrix__pattern-name {
754
+ font-size: 0.75rem;
755
+ }
756
+
440
757
  .matrix__level-cell {
441
758
  padding: 0.625rem 1rem;
442
759
  text-align: center;
@@ -462,6 +779,41 @@ const matrixStyles = `
462
779
  font-weight: 500;
463
780
  }
464
781
 
782
+ /* Loss Aversion Styling for NOT_INCLUDED */
783
+ .matrix__level-cell--not-included {
784
+ position: relative;
785
+ background: repeating-linear-gradient(
786
+ 135deg,
787
+ transparent,
788
+ transparent 8px,
789
+ rgba(148, 163, 184, 0.08) 8px,
790
+ rgba(148, 163, 184, 0.08) 16px
791
+ );
792
+ }
793
+
794
+ .matrix__level-cell--not-included:hover .matrix__upgrade-hint {
795
+ opacity: 1;
796
+ transform: translateY(0);
797
+ }
798
+
799
+ .matrix__upgrade-hint {
800
+ position: absolute;
801
+ bottom: 2px;
802
+ left: 50%;
803
+ transform: translateX(-50%) translateY(4px);
804
+ font-size: 0.5625rem;
805
+ font-weight: 500;
806
+ color: var(--so-violet-600);
807
+ white-space: nowrap;
808
+ opacity: 0;
809
+ transition: all 0.15s ease-out;
810
+ pointer-events: none;
811
+ }
812
+
813
+ .matrix__level-value--not-included {
814
+ opacity: 0.6;
815
+ }
816
+
465
817
  /* Metric Row */
466
818
  .matrix__metric-row {
467
819
  background: inherit;
@@ -542,11 +894,26 @@ const matrixStyles = `
542
894
  border-bottom: 1px solid var(--so-slate-100);
543
895
  }
544
896
 
897
+ .matrix__metric-value-container {
898
+ display: flex;
899
+ flex-direction: column;
900
+ align-items: center;
901
+ gap: 0.125rem;
902
+ }
903
+
545
904
  .matrix__metric-value {
546
905
  font-size: 0.6875rem;
547
906
  color: var(--so-slate-500);
548
907
  }
549
908
 
909
+ .matrix__metric-overage {
910
+ font-family: var(--so-font-mono);
911
+ font-size: 0.5625rem;
912
+ font-weight: 500;
913
+ color: #059669;
914
+ white-space: nowrap;
915
+ }
916
+
550
917
  /* Add Metric Button on Service Row */
551
918
  .matrix__service-cell-wrapper {
552
919
  display: flex;
@@ -579,6 +946,54 @@ const matrixStyles = `
579
946
  color: var(--so-violet-700);
580
947
  }
581
948
 
949
+ /* Service Reorder Buttons */
950
+ .matrix__reorder-btns {
951
+ display: flex;
952
+ flex-direction: column;
953
+ gap: 2px;
954
+ margin-right: 0.5rem;
955
+ opacity: 0;
956
+ transition: opacity 0.15s ease;
957
+ }
958
+
959
+ .matrix__service-row:hover .matrix__reorder-btns {
960
+ opacity: 1;
961
+ }
962
+
963
+ .matrix__reorder-btn {
964
+ display: flex;
965
+ align-items: center;
966
+ justify-content: center;
967
+ width: 18px;
968
+ height: 14px;
969
+ padding: 0;
970
+ background: var(--so-slate-100);
971
+ border: 1px solid var(--so-slate-200);
972
+ border-radius: 3px;
973
+ cursor: pointer;
974
+ transition: all 0.1s ease;
975
+ }
976
+
977
+ .matrix__reorder-btn:hover:not(:disabled) {
978
+ background: var(--so-violet-100);
979
+ border-color: var(--so-violet-300);
980
+ }
981
+
982
+ .matrix__reorder-btn:disabled {
983
+ opacity: 0.3;
984
+ cursor: not-allowed;
985
+ }
986
+
987
+ .matrix__reorder-btn svg {
988
+ width: 10px;
989
+ height: 10px;
990
+ color: var(--so-slate-500);
991
+ }
992
+
993
+ .matrix__reorder-btn:hover:not(:disabled) svg {
994
+ color: var(--so-violet-600);
995
+ }
996
+
582
997
  /* Add Service Row */
583
998
  .matrix__add-service-row td {
584
999
  padding: 0.5rem 1rem;
@@ -919,6 +1334,89 @@ const matrixStyles = `
919
1334
  color: #64748b;
920
1335
  }
921
1336
 
1337
+ .matrix__panel-limit-value-group {
1338
+ display: flex;
1339
+ flex-direction: column;
1340
+ gap: 0.125rem;
1341
+ }
1342
+
1343
+ .matrix__panel-limit-overage {
1344
+ font-family: var(--so-font-mono);
1345
+ font-size: 0.6875rem;
1346
+ color: #059669;
1347
+ font-weight: 500;
1348
+ }
1349
+
1350
+ /* Overage Pricing Section */
1351
+ .matrix__panel-overage-section {
1352
+ margin-top: 0.5rem;
1353
+ padding-top: 0.75rem;
1354
+ border-top: 1px dashed #cbd5e1;
1355
+ }
1356
+
1357
+ .matrix__panel-overage-row {
1358
+ display: flex;
1359
+ align-items: center;
1360
+ gap: 0.375rem;
1361
+ flex-wrap: wrap;
1362
+ }
1363
+
1364
+ .matrix__panel-overage-price {
1365
+ display: flex;
1366
+ align-items: center;
1367
+ gap: 0.25rem;
1368
+ }
1369
+
1370
+ .matrix__panel-overage-currency {
1371
+ font-family: var(--so-font-mono);
1372
+ font-size: 0.875rem;
1373
+ color: #64748b;
1374
+ }
1375
+
1376
+ .matrix__panel-overage-input {
1377
+ width: 4.5rem;
1378
+ font-family: var(--so-font-mono);
1379
+ font-size: 0.875rem;
1380
+ font-weight: 500;
1381
+ color: #0f172a;
1382
+ background: #ffffff;
1383
+ border: 1px solid #cbd5e1;
1384
+ border-radius: var(--so-radius-sm);
1385
+ padding: 0.375rem 0.5rem;
1386
+ outline: none;
1387
+ transition: border-color 0.15s ease;
1388
+ }
1389
+
1390
+ .matrix__panel-overage-input:focus {
1391
+ border-color: #7c3aed;
1392
+ }
1393
+
1394
+ .matrix__panel-overage-separator {
1395
+ font-size: 0.875rem;
1396
+ color: #94a3b8;
1397
+ }
1398
+
1399
+ .matrix__panel-overage-select {
1400
+ font-family: var(--so-font-sans);
1401
+ font-size: 0.8125rem;
1402
+ color: #334155;
1403
+ background: #ffffff;
1404
+ border: 1px solid #cbd5e1;
1405
+ border-radius: var(--so-radius-sm);
1406
+ padding: 0.375rem 0.5rem;
1407
+ cursor: pointer;
1408
+ outline: none;
1409
+ }
1410
+
1411
+ .matrix__panel-overage-select:focus {
1412
+ border-color: #7c3aed;
1413
+ }
1414
+
1415
+ .matrix__panel-overage-label {
1416
+ font-size: 0.75rem;
1417
+ color: #64748b;
1418
+ }
1419
+
922
1420
  .matrix__panel-limit-actions {
923
1421
  display: flex;
924
1422
  gap: 0.25rem;
@@ -1340,6 +1838,26 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1340
1838
  const services = state.global.services ?? [];
1341
1839
  const tiers = state.global.tiers ?? [];
1342
1840
  const optionGroups = state.global.optionGroups ?? [];
1841
+ const resourceTemplateId = state.global.resourceTemplateId;
1842
+ // Get resource templates to find the selected one
1843
+ const templates = useResourceTemplateDocumentsInSelectedDrive();
1844
+ // Get selected facets from the offering document's facetTargets
1845
+ const offeringFacetTargets = state.global.facetTargets ?? [];
1846
+ // Build facet categories from the SERVICE OFFERING's selected facet targets
1847
+ // This ensures only the options selected in the offering's facet targeting appear in the Matrix
1848
+ const facetCategories = useMemo(() => {
1849
+ const categories = {};
1850
+ offeringFacetTargets.forEach((facet) => {
1851
+ categories[facet.categoryKey] = {
1852
+ label: facet.categoryLabel,
1853
+ options: facet.selectedOptions.map((option) => ({
1854
+ id: option.toLowerCase().replace(/\s+/g, "-"),
1855
+ label: option,
1856
+ })),
1857
+ };
1858
+ });
1859
+ return categories;
1860
+ }, [offeringFacetTargets]);
1343
1861
  const [enabledOptionalGroups, setEnabledOptionalGroups] = useState(new Set(optionGroups.filter((g) => g.defaultSelected).map((g) => g.id)));
1344
1862
  const [selectedCell, setSelectedCell] = useState(null);
1345
1863
  const [addServiceModal, setAddServiceModal] = useState(null);
@@ -1347,17 +1865,32 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1347
1865
  const [newServiceDescription, setNewServiceDescription] = useState("");
1348
1866
  const [newServiceSelectedTiers, setNewServiceSelectedTiers] = useState(new Set());
1349
1867
  const [selectedTierIdx, setSelectedTierIdx] = useState(0);
1350
- const [selectedFacets, setSelectedFacets] = useState({
1351
- FUNCTION: "operational-hub",
1352
- LEGAL_ENTITY: "swiss-association",
1353
- TEAM_STRUCTURE: "remote-team",
1354
- ANONYMITY: "high-anonymity",
1868
+ // Selected billing cycle per tier (for tiers with multiple pricing options)
1869
+ const [selectedBillingCycles, setSelectedBillingCycles] = useState({});
1870
+ // Initialize selected facets from offering's facet targets
1871
+ const [selectedFacets, setSelectedFacets] = useState(() => {
1872
+ const initial = {};
1873
+ offeringFacetTargets.forEach((facet) => {
1874
+ if (facet.selectedOptions.length > 0) {
1875
+ initial[facet.categoryKey] = facet.selectedOptions[0]
1876
+ .toLowerCase()
1877
+ .replace(/\s+/g, "-");
1878
+ }
1879
+ });
1880
+ return initial;
1355
1881
  });
1356
1882
  // Metric editing modal state
1357
1883
  const [metricModal, setMetricModal] = useState(null);
1358
1884
  const [metricName, setMetricName] = useState("");
1359
1885
  const [metricLimits, setMetricLimits] = useState({});
1360
1886
  const [metricEnabledTiers, setMetricEnabledTiers] = useState(new Set());
1887
+ // Per-tier overage pricing for metric modal
1888
+ const [metricOveragePrices, setMetricOveragePrices] = useState({});
1889
+ const [metricOverageCycles, setMetricOverageCycles] = useState({});
1890
+ // Unit name for the metric (e.g., "entity", "user", "API call")
1891
+ const [metricUnitName, setMetricUnitName] = useState("");
1892
+ // Bulk actions state
1893
+ const [showBulkActions, setShowBulkActions] = useState(false);
1361
1894
  const getServiceGroup = (service) => {
1362
1895
  // Services now have optionGroupId directly on them
1363
1896
  return service.optionGroupId || null;
@@ -1404,6 +1937,16 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1404
1937
  });
1405
1938
  return Array.from(metricsSet);
1406
1939
  };
1940
+ // Incomplete services detection - services not assigned to any tier
1941
+ const incompleteServices = useMemo(() => {
1942
+ if (tiers.length === 0)
1943
+ return [];
1944
+ return services.filter((service) => {
1945
+ // Check if service is included in at least one tier
1946
+ const isIncludedAnywhere = tiers.some((tier) => tier.serviceLevels.some((sl) => sl.serviceId === service.id && sl.level === "INCLUDED"));
1947
+ return !isIncludedAnywhere;
1948
+ });
1949
+ }, [services, tiers]);
1407
1950
  const getUsageLimitForMetric = (serviceId, metric, tier) => {
1408
1951
  return tier.usageLimits.find((ul) => ul.serviceId === serviceId && ul.metric === metric);
1409
1952
  };
@@ -1439,6 +1982,150 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1439
1982
  return next;
1440
1983
  });
1441
1984
  };
1985
+ // Bulk action handlers
1986
+ const handleBulkIncludeAllInTier = (tierId) => {
1987
+ const now = new Date().toISOString();
1988
+ const tier = tiers.find((t) => t.id === tierId);
1989
+ if (!tier)
1990
+ return;
1991
+ services.forEach((service) => {
1992
+ const existingLevel = tier.serviceLevels.find((sl) => sl.serviceId === service.id);
1993
+ if (!existingLevel) {
1994
+ dispatch(addServiceLevel({
1995
+ tierId,
1996
+ serviceLevelId: generateId(),
1997
+ serviceId: service.id,
1998
+ level: "INCLUDED",
1999
+ optionGroupId: service.optionGroupId || undefined,
2000
+ lastModified: now,
2001
+ }));
2002
+ }
2003
+ else if (existingLevel.level !== "INCLUDED") {
2004
+ dispatch(updateServiceLevel({
2005
+ tierId,
2006
+ serviceLevelId: existingLevel.id,
2007
+ level: "INCLUDED",
2008
+ lastModified: now,
2009
+ }));
2010
+ }
2011
+ });
2012
+ };
2013
+ const handleBulkClearTier = (tierId) => {
2014
+ const now = new Date().toISOString();
2015
+ const tier = tiers.find((t) => t.id === tierId);
2016
+ if (!tier)
2017
+ return;
2018
+ tier.serviceLevels.forEach((sl) => {
2019
+ dispatch(updateServiceLevel({
2020
+ tierId,
2021
+ serviceLevelId: sl.id,
2022
+ level: "NOT_INCLUDED",
2023
+ lastModified: now,
2024
+ }));
2025
+ });
2026
+ };
2027
+ const handleBulkCopyFromTier = (sourceTierId, targetTierId) => {
2028
+ const now = new Date().toISOString();
2029
+ const sourceTier = tiers.find((t) => t.id === sourceTierId);
2030
+ const targetTier = tiers.find((t) => t.id === targetTierId);
2031
+ if (!sourceTier || !targetTier)
2032
+ return;
2033
+ services.forEach((service) => {
2034
+ const sourceLevel = sourceTier.serviceLevels.find((sl) => sl.serviceId === service.id);
2035
+ const targetLevel = targetTier.serviceLevels.find((sl) => sl.serviceId === service.id);
2036
+ const newLevel = sourceLevel?.level || "NOT_INCLUDED";
2037
+ if (!targetLevel) {
2038
+ dispatch(addServiceLevel({
2039
+ tierId: targetTierId,
2040
+ serviceLevelId: generateId(),
2041
+ serviceId: service.id,
2042
+ level: newLevel,
2043
+ optionGroupId: service.optionGroupId || undefined,
2044
+ lastModified: now,
2045
+ }));
2046
+ }
2047
+ else if (targetLevel.level !== newLevel) {
2048
+ dispatch(updateServiceLevel({
2049
+ tierId: targetTierId,
2050
+ serviceLevelId: targetLevel.id,
2051
+ level: newLevel,
2052
+ lastModified: now,
2053
+ }));
2054
+ }
2055
+ });
2056
+ };
2057
+ // Common Pattern Presets - apply marketing psychology patterns across all tiers
2058
+ const handleApplyPattern = (patternId) => {
2059
+ const now = new Date().toISOString();
2060
+ const tierCount = tiers.length;
2061
+ if (tierCount === 0)
2062
+ return;
2063
+ // Pattern definitions
2064
+ const patterns = {
2065
+ // Good-Better-Best: Progressive inclusion (50% → 75% → 100%)
2066
+ "good-better-best": (serviceIdx, tierIdx, totalServices, totalTiers) => {
2067
+ const servicePosition = serviceIdx / totalServices;
2068
+ const tierPosition = tierIdx / (totalTiers - 1 || 1);
2069
+ // Lower tiers get fewer services
2070
+ const threshold = 0.5 + tierPosition * 0.5;
2071
+ return servicePosition < threshold ? "INCLUDED" : "NOT_INCLUDED";
2072
+ },
2073
+ // Premium Only: Top services only in top tier
2074
+ "premium-only": (serviceIdx, tierIdx, totalServices, totalTiers) => {
2075
+ const isTopTier = tierIdx === totalTiers - 1;
2076
+ const isPremiumService = serviceIdx < Math.ceil(totalServices * 0.3);
2077
+ if (isPremiumService) {
2078
+ return isTopTier ? "INCLUDED" : "NOT_INCLUDED";
2079
+ }
2080
+ return "INCLUDED";
2081
+ },
2082
+ // Core + Upgrades: Core included everywhere, extras are optional
2083
+ "core-upgrades": (serviceIdx, tierIdx, totalServices) => {
2084
+ const isCoreService = serviceIdx < Math.ceil(totalServices * 0.5);
2085
+ if (isCoreService) {
2086
+ return "INCLUDED";
2087
+ }
2088
+ return "OPTIONAL";
2089
+ },
2090
+ // Ascending: Each tier adds more services
2091
+ ascending: (serviceIdx, tierIdx, totalServices, totalTiers) => {
2092
+ const servicesPerTier = Math.ceil(totalServices / totalTiers);
2093
+ const includedUpTo = (tierIdx + 1) * servicesPerTier;
2094
+ return serviceIdx < includedUpTo ? "INCLUDED" : "NOT_INCLUDED";
2095
+ },
2096
+ // All Included: Everything included in all tiers
2097
+ "all-included": () => "INCLUDED",
2098
+ // All Optional: Everything optional in all tiers
2099
+ "all-optional": () => "OPTIONAL",
2100
+ };
2101
+ const pattern = patterns[patternId];
2102
+ if (!pattern)
2103
+ return;
2104
+ services.forEach((service, serviceIdx) => {
2105
+ tiers.forEach((tier, tierIdx) => {
2106
+ const newLevel = pattern(serviceIdx, tierIdx, services.length, tierCount);
2107
+ const existingLevel = tier.serviceLevels.find((sl) => sl.serviceId === service.id);
2108
+ if (!existingLevel) {
2109
+ dispatch(addServiceLevel({
2110
+ tierId: tier.id,
2111
+ serviceLevelId: generateId(),
2112
+ serviceId: service.id,
2113
+ level: newLevel,
2114
+ optionGroupId: service.optionGroupId || undefined,
2115
+ lastModified: now,
2116
+ }));
2117
+ }
2118
+ else if (existingLevel.level !== newLevel) {
2119
+ dispatch(updateServiceLevel({
2120
+ tierId: tier.id,
2121
+ serviceLevelId: existingLevel.id,
2122
+ level: newLevel,
2123
+ lastModified: now,
2124
+ }));
2125
+ }
2126
+ });
2127
+ });
2128
+ };
1442
2129
  const handleAddService = () => {
1443
2130
  if (!addServiceModal || !newServiceName.trim())
1444
2131
  return;
@@ -1485,32 +2172,53 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1485
2172
  setMetricName("");
1486
2173
  // Initialize limits for all tiers to empty string
1487
2174
  const initialLimits = {};
2175
+ const initialOveragePrices = {};
2176
+ const initialOverageCycles = {};
1488
2177
  // For new metrics, enable all tiers by default
1489
2178
  const allTierIds = new Set();
1490
2179
  tiers.forEach((tier) => {
1491
2180
  initialLimits[tier.id] = "";
2181
+ initialOveragePrices[tier.id] = "";
2182
+ initialOverageCycles[tier.id] = "";
1492
2183
  allTierIds.add(tier.id);
1493
2184
  });
1494
2185
  setMetricLimits(initialLimits);
1495
2186
  setMetricEnabledTiers(allTierIds);
2187
+ // Reset per-tier overage pricing and unit name
2188
+ setMetricOveragePrices(initialOveragePrices);
2189
+ setMetricOverageCycles(initialOverageCycles);
2190
+ setMetricUnitName("");
1496
2191
  };
1497
2192
  const handleEditMetric = (serviceId, metric) => {
1498
2193
  setMetricModal({ serviceId, metric });
1499
2194
  setMetricName(metric);
1500
2195
  // Initialize limits with existing values and track which tiers have this metric
1501
2196
  const existingLimits = {};
2197
+ const existingOveragePrices = {};
2198
+ const existingOverageCycles = {};
1502
2199
  const enabledTiers = new Set();
2200
+ let existingUnitName = "";
1503
2201
  tiers.forEach((tier) => {
1504
2202
  const usageLimit = tier.usageLimits.find((ul) => ul.serviceId === serviceId && ul.metric === metric);
1505
2203
  // Load value from either limit (numeric) or notes (string)
1506
2204
  existingLimits[tier.id] =
1507
2205
  usageLimit?.limit?.toString() || usageLimit?.notes || "";
2206
+ // Load per-tier overage pricing
2207
+ existingOveragePrices[tier.id] = usageLimit?.unitPrice?.toString() || "";
2208
+ existingOverageCycles[tier.id] = usageLimit?.unitPriceBillingCycle || "";
1508
2209
  if (usageLimit) {
1509
2210
  enabledTiers.add(tier.id);
2211
+ // Get unit name from first tier that has it
2212
+ if (!existingUnitName && usageLimit.unitName) {
2213
+ existingUnitName = usageLimit.unitName;
2214
+ }
1510
2215
  }
1511
2216
  });
1512
2217
  setMetricLimits(existingLimits);
1513
2218
  setMetricEnabledTiers(enabledTiers);
2219
+ setMetricOveragePrices(existingOveragePrices);
2220
+ setMetricOverageCycles(existingOverageCycles);
2221
+ setMetricUnitName(existingUnitName);
1514
2222
  };
1515
2223
  const handleRemoveMetric = (serviceId, metric) => {
1516
2224
  // Remove this metric from all tiers
@@ -1525,6 +2233,45 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1525
2233
  }
1526
2234
  });
1527
2235
  };
2236
+ const handleTogglePremiumExclusive = (serviceId) => {
2237
+ const service = services.find((s) => s.id === serviceId);
2238
+ if (!service)
2239
+ return;
2240
+ dispatch(updateService({
2241
+ id: serviceId,
2242
+ isPremiumExclusive: !service.isPremiumExclusive,
2243
+ lastModified: new Date().toISOString(),
2244
+ }));
2245
+ };
2246
+ // Service reordering - swap display order with adjacent service
2247
+ const handleReorderService = (serviceId, direction, groupServices) => {
2248
+ // Sort services by displayOrder for consistent ordering
2249
+ const sortedServices = [...groupServices].sort((a, b) => {
2250
+ const orderA = a.displayOrder ?? 999;
2251
+ const orderB = b.displayOrder ?? 999;
2252
+ return orderA - orderB;
2253
+ });
2254
+ const currentIndex = sortedServices.findIndex((s) => s.id === serviceId);
2255
+ if (currentIndex === -1)
2256
+ return;
2257
+ const targetIndex = direction === "up" ? currentIndex - 1 : currentIndex + 1;
2258
+ if (targetIndex < 0 || targetIndex >= sortedServices.length)
2259
+ return;
2260
+ const currentService = sortedServices[currentIndex];
2261
+ const targetService = sortedServices[targetIndex];
2262
+ const now = new Date().toISOString();
2263
+ // Swap display orders
2264
+ dispatch(updateService({
2265
+ id: currentService.id,
2266
+ displayOrder: targetIndex,
2267
+ lastModified: now,
2268
+ }));
2269
+ dispatch(updateService({
2270
+ id: targetService.id,
2271
+ displayOrder: currentIndex,
2272
+ lastModified: now,
2273
+ }));
2274
+ };
1528
2275
  const handleSaveMetric = () => {
1529
2276
  if (!metricModal || !metricName.trim())
1530
2277
  return;
@@ -1539,6 +2286,13 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1539
2286
  // Check if value is numeric or string
1540
2287
  const parsedLimit = limitValue ? parseInt(limitValue, 10) : null;
1541
2288
  const isNumeric = parsedLimit !== null && !isNaN(parsedLimit);
2289
+ // Get per-tier overage pricing
2290
+ const tierOveragePrice = metricOveragePrices[tier.id];
2291
+ const tierOverageCycle = metricOverageCycles[tier.id];
2292
+ const parsedOveragePrice = tierOveragePrice
2293
+ ? parseFloat(tierOveragePrice)
2294
+ : null;
2295
+ const hasOveragePricing = parsedOveragePrice && tierOverageCycle;
1542
2296
  if (existingLimit && !isEnabled) {
1543
2297
  // Remove limit - tier was disabled
1544
2298
  dispatch(removeUsageLimit({
@@ -1553,8 +2307,14 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1553
2307
  tierId: tier.id,
1554
2308
  limitId: existingLimit.id,
1555
2309
  metric: metricName.trim(),
2310
+ unitName: metricUnitName.trim() || undefined,
1556
2311
  limit: isNumeric ? parsedLimit : null,
1557
2312
  notes: !isNumeric && limitValue ? limitValue.trim() : null,
2313
+ unitPrice: hasOveragePricing ? parsedOveragePrice : null,
2314
+ unitPriceCurrency: hasOveragePricing ? "USD" : undefined,
2315
+ unitPriceBillingCycle: hasOveragePricing
2316
+ ? tierOverageCycle
2317
+ : undefined,
1558
2318
  lastModified: now,
1559
2319
  }));
1560
2320
  }
@@ -1565,9 +2325,15 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1565
2325
  limitId: generateId(),
1566
2326
  serviceId,
1567
2327
  metric: metricName.trim(),
2328
+ unitName: metricUnitName.trim() || undefined,
1568
2329
  limit: isNumeric ? parsedLimit : null,
1569
2330
  notes: !isNumeric && limitValue ? limitValue.trim() : null,
1570
2331
  resetPeriod: "MONTHLY",
2332
+ unitPrice: hasOveragePricing ? parsedOveragePrice : undefined,
2333
+ unitPriceCurrency: hasOveragePricing ? "USD" : undefined,
2334
+ unitPriceBillingCycle: hasOveragePricing
2335
+ ? tierOverageCycle
2336
+ : undefined,
1571
2337
  lastModified: now,
1572
2338
  }));
1573
2339
  }
@@ -1576,6 +2342,9 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1576
2342
  setMetricName("");
1577
2343
  setMetricLimits({});
1578
2344
  setMetricEnabledTiers(new Set());
2345
+ setMetricOveragePrices({});
2346
+ setMetricOverageCycles({});
2347
+ setMetricUnitName("");
1579
2348
  };
1580
2349
  const getLevelDisplay = (serviceLevel) => {
1581
2350
  if (!serviceLevel)
@@ -1600,35 +2369,72 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1600
2369
  ? "Add services in the Service Catalog to configure the matrix."
1601
2370
  : "Add tiers in Tier Definition to configure the matrix." })] }) })] }));
1602
2371
  }
1603
- return (_jsxs(_Fragment, { children: [_jsx("style", { children: matrixStyles }), _jsxs("div", { className: "matrix", children: [_jsxs("div", { className: "matrix__facets", children: [_jsx("div", { className: "matrix__facets-row", children: Object.entries(FACET_CATEGORIES).map(([key, category]) => (_jsxs("div", { className: "matrix__facet-group", children: [_jsx("span", { className: "matrix__facet-label", children: category.label }), key === "ANONYMITY" ? (_jsx("div", { className: "matrix__toggle-group", children: category.options.map((option) => (_jsx("button", { onClick: () => setSelectedFacets((prev) => ({
1604
- ...prev,
1605
- [key]: option.id,
1606
- })), className: `matrix__toggle-btn ${selectedFacets[key] === option.id
1607
- ? "matrix__toggle-btn--active"
1608
- : ""}`, children: option.label }, option.id))) })) : (_jsx("select", { value: selectedFacets[key] || "", onChange: (e) => setSelectedFacets((prev) => ({
2372
+ return (_jsxs(_Fragment, { children: [_jsx("style", { children: matrixStyles }), _jsxs("div", { className: "matrix", children: [Object.keys(facetCategories).length > 0 && (_jsx("div", { className: "matrix__facets", children: _jsx("div", { className: "matrix__facets-row", children: Object.entries(facetCategories).map(([key, category]) => (_jsxs("div", { className: "matrix__facet-group", children: [_jsx("span", { className: "matrix__facet-label", children: category.label }), category.options.length <= 3 ? (_jsx("div", { className: "matrix__toggle-group", children: category.options.map((option) => (_jsx("button", { type: "button", onClick: () => setSelectedFacets((prev) => ({
1609
2373
  ...prev,
1610
- [key]: e.target.value,
1611
- })), className: "matrix__facet-select", children: category.options.map((option) => (_jsx("option", { value: option.id, children: option.label }, option.id))) }))] }, key))) }), selectedFacets.ANONYMITY === "highest-anonymity" && (_jsx("div", { className: "matrix__facet-notice", children: _jsxs("p", { className: "matrix__facet-notice-text", children: [_jsx("strong", { children: "Highest Anonymity:" }), " Additional setup services may be required for enhanced privacy configurations."] }) }))] }), _jsx("div", { className: "matrix__table-wrap", children: _jsxs("table", { className: "matrix__table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "matrix__corner-cell" }), tiers.map((tier, idx) => (_jsx("th", { onClick: () => setSelectedTierIdx(idx), className: `matrix__tier-header ${idx === selectedTierIdx
1612
- ? "matrix__tier-header--selected"
1613
- : ""}`, children: _jsxs("div", { className: "matrix__tier-header-inner", children: [_jsx("div", { className: "matrix__tier-radio" }), _jsx("span", { className: "matrix__tier-name", children: tier.name }), _jsx("span", { className: "matrix__tier-price", children: tier.isCustomPricing
1614
- ? "Custom"
1615
- : `$${tier.pricing.amount}/mo` })] }) }, tier.id)))] }) }), _jsxs("tbody", { children: [_jsx("tr", { children: _jsx("td", { colSpan: tiers.length + 1, className: "matrix__section-header", children: "Service Catalog" }) }), (setupGroups.length > 0 ||
1616
- ungroupedSetupServices.length > 0) && (_jsx("tr", { children: _jsxs("td", { colSpan: tiers.length + 1, className: "matrix__category-header", children: [_jsx("span", { className: "matrix__category-icon", children: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", children: [_jsx("path", { d: "M19 21V5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v16" }), _jsx("path", { d: "M9 21v-6h6v6" }), _jsx("path", { d: "M9 7h.01M9 11h.01M15 7h.01M15 11h.01" })] }) }), "Setup & Formation"] }) })), setupGroups.map((group) => (_jsx(ServiceGroupSection, { group: group, services: groupedServices.get(group.id) || [], tiers: tiers, isSetupFormation: true, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, setupFee: groupSetupFees[group.id], onAddService: openAddServiceModal, selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric }, group.id))), ungroupedSetupServices.length > 0 && (_jsx(ServiceGroupSection, { group: {
2374
+ [key]: option.id,
2375
+ })), className: `matrix__toggle-btn ${selectedFacets[key] === option.id
2376
+ ? "matrix__toggle-btn--active"
2377
+ : ""}`, children: option.label }, option.id))) })) : (_jsx("select", { value: selectedFacets[key] || category.options[0]?.id || "", onChange: (e) => setSelectedFacets((prev) => ({
2378
+ ...prev,
2379
+ [key]: e.target.value,
2380
+ })), className: "matrix__facet-select", children: category.options.map((option) => (_jsx("option", { value: option.id, children: option.label }, option.id))) }))] }, key))) }) })), services.length > 0 && tiers.length > 0 && (_jsxs("div", { className: "matrix__bulk-actions", children: [_jsxs("button", { type: "button", onClick: () => setShowBulkActions(!showBulkActions), className: "matrix__bulk-toggle", children: [_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M4 6h16M4 12h16M4 18h7" }) }), "Bulk Actions", _jsx("svg", { className: `matrix__bulk-toggle-arrow ${showBulkActions ? "matrix__bulk-toggle-arrow--open" : ""}`, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M19 9l-7 7-7-7" }) })] }), showBulkActions && (_jsxs("div", { className: "matrix__bulk-panel", children: [_jsxs("div", { className: "matrix__bulk-section", children: [_jsx("span", { className: "matrix__bulk-label", children: "Include all services in:" }), _jsx("div", { className: "matrix__bulk-buttons", children: tiers.map((tier) => (_jsxs("button", { type: "button", onClick: () => handleBulkIncludeAllInTier(tier.id), className: "matrix__bulk-btn matrix__bulk-btn--include", children: [_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M5 12l5 5L20 7" }) }), tier.name] }, tier.id))) })] }), _jsxs("div", { className: "matrix__bulk-section", children: [_jsx("span", { className: "matrix__bulk-label", children: "Clear all from:" }), _jsx("div", { className: "matrix__bulk-buttons", children: tiers.map((tier) => (_jsxs("button", { type: "button", onClick: () => handleBulkClearTier(tier.id), className: "matrix__bulk-btn matrix__bulk-btn--clear", children: [_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M6 18L18 6M6 6l12 12" }) }), tier.name] }, tier.id))) })] }), tiers.length >= 2 && (_jsxs("div", { className: "matrix__bulk-section", children: [_jsx("span", { className: "matrix__bulk-label", children: "Copy configuration:" }), _jsx("div", { className: "matrix__bulk-copy", children: tiers.map((sourceTier, idx) => tiers
2381
+ .filter((_, i) => i !== idx)
2382
+ .map((targetTier) => (_jsxs("button", { type: "button", onClick: () => handleBulkCopyFromTier(sourceTier.id, targetTier.id), className: "matrix__bulk-btn matrix__bulk-btn--copy", children: [sourceTier.name, " \u2192 ", targetTier.name] }, `${sourceTier.id}-${targetTier.id}`)))) })] })), _jsxs("div", { className: "matrix__bulk-section matrix__bulk-patterns", children: [_jsxs("span", { className: "matrix__bulk-label", children: [_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "matrix__bulk-label-icon", children: _jsx("path", { d: "M13 10V3L4 14h7v7l9-11h-7z" }) }), "Apply Pattern Preset:"] }), _jsxs("div", { className: "matrix__pattern-grid", children: [_jsxs("button", { type: "button", onClick: () => handleApplyPattern("good-better-best"), className: "matrix__pattern-btn", title: "Progressive inclusion: Basic tier gets 50%, mid-tier 75%, top tier 100%", children: [_jsx("span", { className: "matrix__pattern-icon", children: "\uD83D\uDCC8" }), _jsx("span", { className: "matrix__pattern-name", children: "Good-Better-Best" }), _jsx("span", { className: "matrix__pattern-desc", children: "Progressive inclusion" })] }), _jsxs("button", { type: "button", onClick: () => handleApplyPattern("premium-only"), className: "matrix__pattern-btn", title: "Top 30% services exclusive to premium tier, rest included everywhere", children: [_jsx("span", { className: "matrix__pattern-icon", children: "\u2B50" }), _jsx("span", { className: "matrix__pattern-name", children: "Premium Exclusives" }), _jsx("span", { className: "matrix__pattern-desc", children: "Top services in top tier only" })] }), _jsxs("button", { type: "button", onClick: () => handleApplyPattern("core-upgrades"), className: "matrix__pattern-btn", title: "Core services included, extras as optional add-ons", children: [_jsx("span", { className: "matrix__pattern-icon", children: "\uD83C\uDFAF" }), _jsx("span", { className: "matrix__pattern-name", children: "Core + Add-ons" }), _jsx("span", { className: "matrix__pattern-desc", children: "Half included, half optional" })] }), _jsxs("button", { type: "button", onClick: () => handleApplyPattern("ascending"), className: "matrix__pattern-btn", title: "Each tier unlocks more services progressively", children: [_jsx("span", { className: "matrix__pattern-icon", children: "\uD83E\uDE9C" }), _jsx("span", { className: "matrix__pattern-name", children: "Ascending Tiers" }), _jsx("span", { className: "matrix__pattern-desc", children: "Each tier unlocks more" })] }), _jsxs("button", { type: "button", onClick: () => handleApplyPattern("all-included"), className: "matrix__pattern-btn matrix__pattern-btn--simple", title: "Everything included in all tiers", children: [_jsx("span", { className: "matrix__pattern-icon", children: "\u2713" }), _jsx("span", { className: "matrix__pattern-name", children: "All Included" })] }), _jsxs("button", { type: "button", onClick: () => handleApplyPattern("all-optional"), className: "matrix__pattern-btn matrix__pattern-btn--simple", title: "Everything optional in all tiers", children: [_jsx("span", { className: "matrix__pattern-icon", children: "\u25D0" }), _jsx("span", { className: "matrix__pattern-name", children: "All Optional" })] })] })] })] }))] })), incompleteServices.length > 0 && (_jsxs("div", { className: "matrix__incomplete-warning", children: [_jsx("div", { className: "matrix__incomplete-icon", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }) }), _jsxs("div", { className: "matrix__incomplete-content", children: [_jsxs("span", { className: "matrix__incomplete-title", children: [incompleteServices.length, " service", incompleteServices.length !== 1 ? "s" : "", " not configured"] }), _jsxs("span", { className: "matrix__incomplete-text", children: ["The following services are not included in any tier:", " ", _jsx("strong", { children: incompleteServices
2383
+ .slice(0, 3)
2384
+ .map((s) => s.title)
2385
+ .join(", ") }), incompleteServices.length > 3 &&
2386
+ ` and ${incompleteServices.length - 3} more`] })] })] })), _jsx("div", { className: "matrix__table-wrap", children: _jsxs("table", { className: "matrix__table", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "matrix__corner-cell" }), tiers.map((tier, idx) => {
2387
+ const hasPricingOptions = tier.pricingOptions && tier.pricingOptions.length > 0;
2388
+ const selectedCycleId = selectedBillingCycles[tier.id];
2389
+ const activePricingOption = hasPricingOptions
2390
+ ? tier.pricingOptions.find((po) => po.id === selectedCycleId) ||
2391
+ tier.pricingOptions.find((po) => po.isDefault) ||
2392
+ tier.pricingOptions[0]
2393
+ : null;
2394
+ const displayAmount = activePricingOption
2395
+ ? activePricingOption.amount
2396
+ : tier.pricing.amount;
2397
+ const displayCycle = activePricingOption
2398
+ ? activePricingOption.billingCycle
2399
+ : tier.pricing.billingCycle;
2400
+ const monthlyEquivalent = displayAmount &&
2401
+ displayCycle !== "MONTHLY" &&
2402
+ displayCycle !== "ONE_TIME"
2403
+ ? getMonthlyEquivalent(displayAmount, displayCycle)
2404
+ : null;
2405
+ return (_jsx("th", { onClick: () => setSelectedTierIdx(idx), className: `matrix__tier-header ${idx === selectedTierIdx
2406
+ ? "matrix__tier-header--selected"
2407
+ : ""}`, children: _jsxs("div", { className: "matrix__tier-header-inner", children: [_jsx("div", { className: "matrix__tier-radio" }), _jsx("span", { className: "matrix__tier-name", children: tier.name }), _jsx("span", { className: "matrix__tier-price", children: tier.isCustomPricing
2408
+ ? "Custom"
2409
+ : monthlyEquivalent
2410
+ ? `$${monthlyEquivalent.toFixed(0)}/mo`
2411
+ : displayAmount !== null
2412
+ ? `$${displayAmount}/mo`
2413
+ : "$null/mo" }), hasPricingOptions &&
2414
+ tier.pricingOptions.length > 1 && (_jsx("select", { value: selectedCycleId || activePricingOption?.id || "", onClick: (e) => e.stopPropagation(), onChange: (e) => {
2415
+ e.stopPropagation();
2416
+ setSelectedBillingCycles((prev) => ({
2417
+ ...prev,
2418
+ [tier.id]: e.target.value,
2419
+ }));
2420
+ }, className: "matrix__tier-cycle-select", children: tier.pricingOptions.map((po) => (_jsxs("option", { value: po.id, children: [BILLING_CYCLE_SHORT_LABELS[po.billingCycle], " ", "- $", po.amount] }, po.id))) }))] }) }, tier.id));
2421
+ })] }) }), _jsxs("tbody", { children: [_jsx("tr", { children: _jsx("td", { colSpan: tiers.length + 1, className: "matrix__section-header", children: "Service Catalog" }) }), (setupGroups.length > 0 ||
2422
+ ungroupedSetupServices.length > 0) && (_jsx("tr", { children: _jsxs("td", { colSpan: tiers.length + 1, className: "matrix__category-header", children: [_jsx("span", { className: "matrix__category-icon", children: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", children: [_jsx("path", { d: "M19 21V5a2 2 0 0 0-2-2H7a2 2 0 0 0-2 2v16" }), _jsx("path", { d: "M9 21v-6h6v6" }), _jsx("path", { d: "M9 7h.01M9 11h.01M15 7h.01M15 11h.01" })] }) }), "Setup & Formation"] }) })), setupGroups.map((group) => (_jsx(ServiceGroupSection, { group: group, services: groupedServices.get(group.id) || [], tiers: tiers, isSetupFormation: true, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, setupFee: groupSetupFees[group.id], onAddService: openAddServiceModal, selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric, onTogglePremiumExclusive: handleTogglePremiumExclusive, onReorderService: handleReorderService }, group.id))), ungroupedSetupServices.length > 0 && (_jsx(ServiceGroupSection, { group: {
1617
2423
  id: UNGROUPED_ID,
1618
2424
  name: "Setup & Formation",
1619
2425
  description: null,
1620
2426
  isAddOn: false,
1621
2427
  defaultSelected: true,
1622
- }, services: ungroupedSetupServices, tiers: tiers, isSetupFormation: true, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, setupFee: groupSetupFees[UNGROUPED_ID], selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric }, "ungrouped-setup")), (regularGroups.length > 0 ||
1623
- ungroupedRegularServices.length > 0) && (_jsx("tr", { children: _jsxs("td", { colSpan: tiers.length + 1, className: "matrix__category-header", children: [_jsx("span", { className: "matrix__category-icon", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", children: _jsx("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }) }), "Recurring Services"] }) })), regularGroups.map((group) => (_jsx(ServiceGroupSection, { group: group, services: groupedServices.get(group.id) || [], tiers: tiers, isSetupFormation: false, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, onAddService: openAddServiceModal, selectedTierIdx: selectedTierIdx, dispatch: dispatch, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric }, group.id))), ungroupedRegularServices.length > 0 && (_jsx(ServiceGroupSection, { group: {
2428
+ }, services: ungroupedSetupServices, tiers: tiers, isSetupFormation: true, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, setupFee: groupSetupFees[UNGROUPED_ID], selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric, onTogglePremiumExclusive: handleTogglePremiumExclusive, onReorderService: handleReorderService }, "ungrouped-setup")), (regularGroups.length > 0 ||
2429
+ ungroupedRegularServices.length > 0) && (_jsx("tr", { children: _jsxs("td", { colSpan: tiers.length + 1, className: "matrix__category-header", children: [_jsx("span", { className: "matrix__category-icon", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", children: _jsx("path", { d: "M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83" }) }) }), "Recurring Services"] }) })), regularGroups.map((group) => (_jsx(ServiceGroupSection, { group: group, services: groupedServices.get(group.id) || [], tiers: tiers, isSetupFormation: false, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, onAddService: openAddServiceModal, selectedTierIdx: selectedTierIdx, dispatch: dispatch, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric, onTogglePremiumExclusive: handleTogglePremiumExclusive, onReorderService: handleReorderService }, group.id))), ungroupedRegularServices.length > 0 && (_jsx(ServiceGroupSection, { group: {
1624
2430
  id: UNGROUPED_ID,
1625
2431
  name: "Recurring Services",
1626
2432
  description: null,
1627
2433
  isAddOn: false,
1628
2434
  defaultSelected: true,
1629
- }, services: ungroupedRegularServices, tiers: tiers, isSetupFormation: false, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric }, "ungrouped-regular")), _jsxs("tr", { className: "matrix__total-row", children: [_jsx("td", { children: "SUBTOTAL" }), tiers.map((tier) => (_jsx("td", { style: { textAlign: "center" }, children: tier.isCustomPricing
2435
+ }, services: ungroupedRegularServices, tiers: tiers, isSetupFormation: false, isOptional: false, isEnabled: true, onToggle: () => { }, getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric, onTogglePremiumExclusive: handleTogglePremiumExclusive, onReorderService: handleReorderService }, "ungrouped-regular")), _jsxs("tr", { className: "matrix__total-row", children: [_jsx("td", { children: "SUBTOTAL" }), tiers.map((tier) => (_jsx("td", { style: { textAlign: "center" }, children: tier.isCustomPricing
1630
2436
  ? "Custom"
1631
- : `$${tier.pricing.amount}` }, tier.id)))] }), addonGroups.map((group) => (_jsx(ServiceGroupSection, { group: group, services: groupedServices.get(group.id) || [], tiers: tiers, isSetupFormation: false, isOptional: true, isEnabled: enabledOptionalGroups.has(group.id), onToggle: () => toggleOptionalGroup(group.id), getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, onAddService: openAddServiceModal, selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric }, group.id))), _jsxs("tr", { className: "matrix__grand-total-row", children: [_jsx("td", { children: "Grand Total (Recurring)" }), tiers.map((tier, idx) => {
2437
+ : `$${tier.pricing.amount}` }, tier.id)))] }), addonGroups.map((group) => (_jsx(ServiceGroupSection, { group: group, services: groupedServices.get(group.id) || [], tiers: tiers, isSetupFormation: false, isOptional: true, isEnabled: enabledOptionalGroups.has(group.id), onToggle: () => toggleOptionalGroup(group.id), getServiceLevelForTier: getServiceLevelForTier, getUniqueMetricsForService: getUniqueMetricsForService, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, handleSetServiceLevel: handleSetServiceLevel, dispatch: dispatch, onAddService: openAddServiceModal, selectedTierIdx: selectedTierIdx, onAddMetric: handleAddMetric, onEditMetric: handleEditMetric, onRemoveMetric: handleRemoveMetric, onTogglePremiumExclusive: handleTogglePremiumExclusive, onReorderService: handleReorderService }, group.id))), _jsxs("tr", { className: "matrix__grand-total-row", children: [_jsx("td", { children: "Grand Total (Recurring)" }), tiers.map((tier, idx) => {
1632
2438
  const tierPrice = tier.pricing.amount || 0;
1633
2439
  const grandTotal = tierPrice;
1634
2440
  return (_jsx("td", { className: idx === selectedTierIdx
@@ -1656,17 +2462,19 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1656
2462
  setNewServiceName("");
1657
2463
  setNewServiceDescription("");
1658
2464
  setNewServiceSelectedTiers(new Set());
1659
- }, className: "matrix__modal-btn matrix__modal-btn--cancel", children: "Cancel" }), _jsx("button", { onClick: handleAddService, disabled: !newServiceName.trim() || newServiceSelectedTiers.size === 0, className: "matrix__modal-btn matrix__modal-btn--primary", children: "Add Service" })] })] }) })), metricModal && (_jsx("div", { className: "matrix__modal-overlay", children: _jsxs("div", { className: "matrix__modal matrix__modal--wide", children: [_jsx("h3", { className: "matrix__modal-title", children: metricModal.metric ? "Edit Metric" : "Add Metric" }), _jsxs("div", { className: "matrix__modal-field", children: [_jsx("label", { className: "matrix__modal-label", children: "Metric Name" }), _jsx("input", { type: "text", value: metricName, onChange: (e) => setMetricName(e.target.value), placeholder: "e.g., API Calls, Storage, Users", className: "matrix__modal-input", autoFocus: true })] }), _jsxs("div", { className: "matrix__modal-field", children: [_jsx("label", { className: "matrix__modal-label", children: "Pricing Tiers & Values" }), _jsx("p", { className: "matrix__modal-hint", style: { marginBottom: "0.75rem" }, children: "Enable the metric for each tier and set values." }), _jsx("div", { style: {
2465
+ }, className: "matrix__modal-btn matrix__modal-btn--cancel", children: "Cancel" }), _jsx("button", { onClick: handleAddService, disabled: !newServiceName.trim() || newServiceSelectedTiers.size === 0, className: "matrix__modal-btn matrix__modal-btn--primary", children: "Add Service" })] })] }) })), metricModal && (_jsx("div", { className: "matrix__modal-overlay", children: _jsxs("div", { className: "matrix__modal matrix__modal--wide", children: [_jsx("h3", { className: "matrix__modal-title", children: metricModal.metric ? "Edit Metric" : "Add Metric" }), _jsxs("div", { className: "matrix__modal-field", children: [_jsx("label", { className: "matrix__modal-label", children: "Metric Name" }), _jsx("input", { type: "text", value: metricName, onChange: (e) => setMetricName(e.target.value), placeholder: "e.g., Number of Entities, API Calls, Storage", className: "matrix__modal-input", autoFocus: true })] }), _jsxs("div", { className: "matrix__modal-field", children: [_jsx("label", { className: "matrix__modal-label", children: "Unit Name (Optional)" }), _jsx("input", { type: "text", value: metricUnitName, onChange: (e) => setMetricUnitName(e.target.value), placeholder: "e.g., entity, user, API call, GB", className: "matrix__modal-input" }), _jsx("p", { className: "matrix__modal-hint", style: { marginTop: "0.375rem" }, children: "Used for overage pricing display (e.g., \"$50 per entity per month\")" })] }), _jsxs("div", { className: "matrix__modal-field", children: [_jsx("label", { className: "matrix__modal-label", children: "Pricing Tiers & Values" }), _jsx("p", { className: "matrix__modal-hint", style: { marginBottom: "0.75rem" }, children: "Enable the metric for each tier and set values." }), _jsx("div", { style: {
1660
2466
  display: "flex",
1661
2467
  flexDirection: "column",
1662
2468
  gap: "0.5rem",
1663
2469
  }, children: tiers.map((tier) => {
1664
2470
  const isEnabled = metricEnabledTiers.has(tier.id);
2471
+ const tierOveragePrice = metricOveragePrices[tier.id] || "";
2472
+ const tierOverageCycle = metricOverageCycles[tier.id] || "";
1665
2473
  return (_jsxs("div", { style: {
1666
2474
  display: "flex",
1667
- alignItems: "center",
1668
- gap: "0.75rem",
1669
- padding: "0.5rem",
2475
+ flexDirection: "column",
2476
+ gap: "0.5rem",
2477
+ padding: "0.75rem",
1670
2478
  borderRadius: "6px",
1671
2479
  background: isEnabled
1672
2480
  ? "rgba(124, 58, 237, 0.05)"
@@ -1675,48 +2483,101 @@ export function TheMatrix({ document, dispatch, groupSetupFees = {}, }) {
1675
2483
  ? "1px solid rgba(124, 58, 237, 0.2)"
1676
2484
  : "1px solid #e2e8f0",
1677
2485
  transition: "all 0.15s ease",
1678
- }, children: [_jsxs("label", { style: {
2486
+ }, children: [_jsxs("div", { style: {
2487
+ display: "flex",
2488
+ alignItems: "center",
2489
+ gap: "0.75rem",
2490
+ }, children: [_jsxs("label", { style: {
2491
+ display: "flex",
2492
+ alignItems: "center",
2493
+ gap: "0.5rem",
2494
+ cursor: "pointer",
2495
+ minWidth: "120px",
2496
+ }, children: [_jsx("input", { type: "checkbox", checked: isEnabled, onChange: (e) => {
2497
+ setMetricEnabledTiers((prev) => {
2498
+ const next = new Set(prev);
2499
+ if (e.target.checked) {
2500
+ next.add(tier.id);
2501
+ }
2502
+ else {
2503
+ next.delete(tier.id);
2504
+ }
2505
+ return next;
2506
+ });
2507
+ }, style: {
2508
+ width: "16px",
2509
+ height: "16px",
2510
+ accentColor: "#7c3aed",
2511
+ cursor: "pointer",
2512
+ } }), _jsx("span", { style: {
2513
+ fontWeight: 600,
2514
+ color: isEnabled ? "#334155" : "#94a3b8",
2515
+ fontSize: "0.875rem",
2516
+ }, children: tier.name })] }), _jsx("input", { type: "text", value: metricLimits[tier.id] || "", onChange: (e) => setMetricLimits((prev) => ({
2517
+ ...prev,
2518
+ [tier.id]: e.target.value,
2519
+ })), placeholder: isEnabled ? "Limit value" : "—", className: "matrix__modal-input", disabled: !isEnabled, style: {
2520
+ flex: 1,
2521
+ opacity: isEnabled ? 1 : 0.5,
2522
+ cursor: isEnabled ? "text" : "not-allowed",
2523
+ } })] }), isEnabled && (_jsxs("div", { style: {
1679
2524
  display: "flex",
1680
2525
  alignItems: "center",
1681
2526
  gap: "0.5rem",
1682
- cursor: "pointer",
1683
- minWidth: "120px",
1684
- }, children: [_jsx("input", { type: "checkbox", checked: isEnabled, onChange: (e) => {
1685
- setMetricEnabledTiers((prev) => {
1686
- const next = new Set(prev);
1687
- if (e.target.checked) {
1688
- next.add(tier.id);
1689
- }
1690
- else {
1691
- next.delete(tier.id);
1692
- }
1693
- return next;
1694
- });
1695
- }, style: {
1696
- width: "16px",
1697
- height: "16px",
1698
- accentColor: "#7c3aed",
2527
+ marginLeft: "1.75rem",
2528
+ padding: "0.5rem 0.75rem",
2529
+ background: "rgba(255,255,255,0.6)",
2530
+ borderRadius: "4px",
2531
+ }, children: [_jsx("span", { style: {
2532
+ fontSize: "0.75rem",
2533
+ color: "#64748b",
2534
+ whiteSpace: "nowrap",
2535
+ }, children: "Overage:" }), _jsx("span", { style: {
2536
+ fontFamily: "var(--so-font-mono)",
2537
+ fontSize: "0.8125rem",
2538
+ color: "#64748b",
2539
+ }, children: "$" }), _jsx("input", { type: "number", value: tierOveragePrice, onChange: (e) => setMetricOveragePrices((prev) => ({
2540
+ ...prev,
2541
+ [tier.id]: e.target.value,
2542
+ })), placeholder: "0.00", step: "0.01", style: {
2543
+ width: "4rem",
2544
+ fontFamily: "var(--so-font-mono)",
2545
+ fontSize: "0.8125rem",
2546
+ fontWeight: 500,
2547
+ color: "#0f172a",
2548
+ background: "#ffffff",
2549
+ border: "1px solid #cbd5e1",
2550
+ borderRadius: "4px",
2551
+ padding: "0.25rem 0.375rem",
2552
+ outline: "none",
2553
+ } }), _jsx("span", { style: { fontSize: "0.75rem", color: "#94a3b8" }, children: "/" }), _jsxs("select", { value: tierOverageCycle, onChange: (e) => setMetricOverageCycles((prev) => ({
2554
+ ...prev,
2555
+ [tier.id]: e.target.value || "",
2556
+ })), style: {
2557
+ fontFamily: "var(--so-font-sans)",
2558
+ fontSize: "0.75rem",
2559
+ color: "#334155",
2560
+ background: "#ffffff",
2561
+ border: "1px solid #cbd5e1",
2562
+ borderRadius: "4px",
2563
+ padding: "0.25rem 0.375rem",
1699
2564
  cursor: "pointer",
1700
- } }), _jsx("span", { style: {
1701
- fontWeight: 600,
1702
- color: isEnabled ? "#334155" : "#94a3b8",
1703
- fontSize: "0.875rem",
1704
- }, children: tier.name })] }), _jsx("input", { type: "text", value: metricLimits[tier.id] || "", onChange: (e) => setMetricLimits((prev) => ({
1705
- ...prev,
1706
- [tier.id]: e.target.value,
1707
- })), placeholder: isEnabled ? "Enter value" : "—", className: "matrix__modal-input", disabled: !isEnabled, style: {
1708
- flex: 1,
1709
- opacity: isEnabled ? 1 : 0.5,
1710
- cursor: isEnabled ? "text" : "not-allowed",
1711
- } })] }, tier.id));
2565
+ outline: "none",
2566
+ }, children: [_jsx("option", { value: "", children: "None" }), RECURRING_BILLING_CYCLES.map((cycle) => (_jsx("option", { value: cycle, children: BILLING_CYCLE_SHORT_LABELS[cycle] }, cycle)))] }), _jsxs("span", { style: {
2567
+ fontSize: "0.6875rem",
2568
+ color: "#64748b",
2569
+ }, children: ["per extra ", metricUnitName || "unit"] })] }))] }, tier.id));
1712
2570
  }) })] }), _jsxs("div", { className: "matrix__modal-actions", children: [_jsx("button", { onClick: () => {
1713
2571
  setMetricModal(null);
1714
2572
  setMetricName("");
2573
+ setMetricUnitName("");
1715
2574
  setMetricLimits({});
1716
2575
  setMetricEnabledTiers(new Set());
2576
+ setMetricOveragePrices({});
2577
+ setMetricOverageCycles({});
1717
2578
  }, className: "matrix__modal-btn matrix__modal-btn--cancel", children: "Cancel" }), _jsx("button", { onClick: handleSaveMetric, disabled: !metricName.trim() || metricEnabledTiers.size === 0, className: "matrix__modal-btn matrix__modal-btn--primary", children: metricModal.metric ? "Save Changes" : "Add Metric" })] })] }) }))] })] }));
1718
2579
  }
1719
- function ServiceGroupSection({ group, services, tiers, isSetupFormation, isOptional, isEnabled, onToggle, getServiceLevelForTier, getUniqueMetricsForService, getUsageLimitForMetric, getLevelDisplay, selectedCell, setSelectedCell, setupFee, onAddService, selectedTierIdx, onAddMetric, onEditMetric, onRemoveMetric, }) {
2580
+ function ServiceGroupSection({ group, services, tiers, isSetupFormation, isOptional, isEnabled, onToggle, getServiceLevelForTier, getUniqueMetricsForService, getUsageLimitForMetric, getLevelDisplay, selectedCell, setSelectedCell, setupFee, onAddService, selectedTierIdx, onAddMetric, onEditMetric, onRemoveMetric, onTogglePremiumExclusive, onReorderService, }) {
1720
2581
  const showGroup = services.length > 0 || onAddService;
1721
2582
  if (!showGroup)
1722
2583
  return null;
@@ -1736,9 +2597,9 @@ function ServiceGroupSection({ group, services, tiers, isSetupFormation, isOptio
1736
2597
  ? "INCLUDED"
1737
2598
  : isOptional
1738
2599
  ? "OPTIONAL"
1739
- : "INCLUDED" }) })] }), services.map((service) => {
2600
+ : "INCLUDED" }) })] }), services.map((service, serviceIndex) => {
1740
2601
  const metrics = getUniqueMetricsForService(service.id);
1741
- return (_jsx(ServiceRowWithMetrics, { service: service, metrics: metrics, tiers: tiers, rowClass: rowClass, getServiceLevelForTier: getServiceLevelForTier, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, selectedTierIdx: selectedTierIdx, onAddMetric: onAddMetric, onEditMetric: onEditMetric, onRemoveMetric: onRemoveMetric }, service.id));
2602
+ return (_jsx(ServiceRowWithMetrics, { service: service, metrics: metrics, tiers: tiers, rowClass: rowClass, getServiceLevelForTier: getServiceLevelForTier, getUsageLimitForMetric: getUsageLimitForMetric, getLevelDisplay: getLevelDisplay, selectedCell: selectedCell, setSelectedCell: setSelectedCell, selectedTierIdx: selectedTierIdx, onAddMetric: onAddMetric, onEditMetric: onEditMetric, onRemoveMetric: onRemoveMetric, onTogglePremiumExclusive: onTogglePremiumExclusive, onReorderService: onReorderService, groupServices: services, serviceIndex: serviceIndex }, service.id));
1742
2603
  }), onAddService && group.id !== "__ungrouped__" && (_jsxs("tr", { className: `matrix__add-service-row ${rowClass}`, children: [_jsx("td", { className: rowClass, children: _jsxs("button", { onClick: () => onAddService(group.id, isSetupFormation), className: "matrix__add-service-btn", children: [_jsx("svg", { className: "matrix__add-service-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) }), "+ Add a Service"] }) }), _jsx("td", { colSpan: tiers.length, className: rowClass })] })), isSetupFormation && (_jsxs("tr", { className: "matrix__setup-total-row", children: [_jsx("td", { children: "TOTAL SETUP FEE" }), _jsx("td", { colSpan: tiers.length, style: { textAlign: "center" }, children: setupFee
1743
2604
  ? `$${setupFee} flat fee (applied to all tiers)`
1744
2605
  : "No setup fee configured" })] })), isOptional && (_jsxs("tr", { className: `matrix__total-row ${headerClass}`, children: [_jsx("td", { className: headerClass, children: "SUBTOTAL" }), tiers.map((tier, tierIdx) => {
@@ -1754,8 +2615,21 @@ function ServiceGroupSection({ group, services, tiers, isSetupFormation, isOptio
1754
2615
  }, children: isEnabled ? priceDisplay : "$0" }, tier.id));
1755
2616
  })] }))] }));
1756
2617
  }
1757
- function ServiceRowWithMetrics({ service, metrics, tiers, rowClass, getServiceLevelForTier, getUsageLimitForMetric, getLevelDisplay, selectedCell, setSelectedCell, selectedTierIdx, onAddMetric, onEditMetric, onRemoveMetric, }) {
1758
- return (_jsxs(_Fragment, { children: [_jsxs("tr", { className: `matrix__service-row ${rowClass}`, children: [_jsx("td", { className: `matrix__service-cell ${rowClass}`, children: _jsxs("div", { className: "matrix__service-cell-wrapper", children: [_jsx("span", { className: "matrix__service-title", children: service.title }), _jsx("button", { onClick: (e) => {
2618
+ function ServiceRowWithMetrics({ service, metrics, tiers, rowClass, getServiceLevelForTier, getUsageLimitForMetric, getLevelDisplay, selectedCell, setSelectedCell, selectedTierIdx, onAddMetric, onEditMetric, onRemoveMetric, onTogglePremiumExclusive, onReorderService, groupServices, serviceIndex, }) {
2619
+ // Use persisted isPremiumExclusive field from document state
2620
+ const isPremiumExclusive = service.isPremiumExclusive;
2621
+ return (_jsxs(_Fragment, { children: [_jsxs("tr", { className: `matrix__service-row ${rowClass}`, children: [_jsx("td", { className: `matrix__service-cell ${rowClass}`, children: _jsxs("div", { className: "matrix__service-cell-wrapper", children: [_jsxs("div", { className: "matrix__reorder-btns", children: [_jsx("button", { className: "matrix__reorder-btn", onClick: (e) => {
2622
+ e.stopPropagation();
2623
+ onReorderService(service.id, "up", groupServices);
2624
+ }, disabled: serviceIndex === 0, title: "Move up", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 15l-6-6-6 6" }) }) }), _jsx("button", { className: "matrix__reorder-btn", onClick: (e) => {
2625
+ e.stopPropagation();
2626
+ onReorderService(service.id, "down", groupServices);
2627
+ }, disabled: serviceIndex === groupServices.length - 1, title: "Move down", children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M6 9l6 6 6-6" }) }) })] }), _jsx("span", { className: "matrix__service-title", children: service.title }), _jsxs("button", { onClick: (e) => {
2628
+ e.stopPropagation();
2629
+ onTogglePremiumExclusive(service.id);
2630
+ }, className: `matrix__premium-badge ${isPremiumExclusive ? "matrix__premium-badge--active" : "matrix__premium-badge--inactive"}`, title: isPremiumExclusive
2631
+ ? "Click to remove premium exclusive status"
2632
+ : "Click to mark as premium exclusive", children: [_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" }) }), "Premium"] }), _jsx("button", { onClick: (e) => {
1759
2633
  e.stopPropagation();
1760
2634
  onAddMetric(service.id);
1761
2635
  }, className: "matrix__add-metric-btn", title: "Add metric to this service", children: "+ Metric" })] }) }), tiers.map((tier, tierIdx) => {
@@ -1763,9 +2637,17 @@ function ServiceRowWithMetrics({ service, metrics, tiers, rowClass, getServiceLe
1763
2637
  const display = getLevelDisplay(serviceLevel);
1764
2638
  const isSelected = selectedCell?.serviceId === service.id &&
1765
2639
  selectedCell?.tierId === tier.id;
1766
- return (_jsx("td", { className: `matrix__level-cell ${isSelected ? "matrix__level-cell--selected" : ""} ${tierIdx === selectedTierIdx ? "matrix__level-cell--highlight" : ""}`, onClick: () => setSelectedCell(isSelected
2640
+ const isNotIncluded = !serviceLevel || serviceLevel.level === "NOT_INCLUDED";
2641
+ // Find next tier that has this service included (for upgrade hint)
2642
+ const nextTierWithService = isNotIncluded
2643
+ ? tiers.slice(tierIdx + 1).find((t) => {
2644
+ const sl = getServiceLevelForTier(service.id, t);
2645
+ return sl && sl.level === "INCLUDED";
2646
+ })
2647
+ : null;
2648
+ return (_jsxs("td", { className: `matrix__level-cell ${isSelected ? "matrix__level-cell--selected" : ""} ${tierIdx === selectedTierIdx ? "matrix__level-cell--highlight" : ""} ${isNotIncluded ? "matrix__level-cell--not-included" : ""}`, onClick: () => setSelectedCell(isSelected
1767
2649
  ? null
1768
- : { serviceId: service.id, tierId: tier.id }), children: _jsx("span", { className: "matrix__level-value", style: { color: display.color }, children: display.label }) }, tier.id));
2650
+ : { serviceId: service.id, tierId: tier.id }), children: [_jsx("span", { className: `matrix__level-value ${isNotIncluded ? "matrix__level-value--not-included" : ""}`, style: { color: display.color }, children: display.label }), isNotIncluded && nextTierWithService && (_jsxs("span", { className: "matrix__upgrade-hint", children: ["In ", nextTierWithService.name, " \u2192"] }))] }, tier.id));
1769
2651
  })] }), metrics.map((metric) => (_jsxs("tr", { className: `matrix__metric-row ${rowClass}`, onClick: () => onEditMetric(service.id, metric), children: [_jsx("td", { className: `matrix__metric-cell ${rowClass}`, children: _jsxs("div", { className: "matrix__metric-name-wrapper", children: [_jsx("span", { className: "matrix__metric-name", children: metric }), _jsxs("div", { className: "matrix__metric-actions", children: [_jsx("button", { onClick: (e) => {
1770
2652
  e.stopPropagation();
1771
2653
  onEditMetric(service.id, metric);
@@ -1776,11 +2658,12 @@ function ServiceRowWithMetrics({ service, metrics, tiers, rowClass, getServiceLe
1776
2658
  const usageLimit = getUsageLimitForMetric(service.id, metric, tier);
1777
2659
  return (_jsx("td", { className: `matrix__metric-value-cell ${tierIdx === selectedTierIdx
1778
2660
  ? "matrix__level-cell--highlight"
1779
- : ""}`, children: _jsx("span", { className: "matrix__metric-value", children: usageLimit
1780
- ? usageLimit.limit
1781
- ? `Up to ${usageLimit.limit}`
1782
- : usageLimit.notes || "Unlimited"
1783
- : "—" }) }, tier.id));
2661
+ : ""}`, children: _jsxs("div", { className: "matrix__metric-value-container", children: [_jsx("span", { className: "matrix__metric-value", children: usageLimit
2662
+ ? usageLimit.limit
2663
+ ? `Up to ${usageLimit.limit}`
2664
+ : usageLimit.notes || "Unlimited"
2665
+ : "—" }), usageLimit?.unitPrice &&
2666
+ usageLimit?.unitPriceBillingCycle && (_jsxs("span", { className: "matrix__metric-overage", children: ["+", formatPrice(usageLimit.unitPrice, usageLimit.unitPriceCurrency || "USD"), "/", BILLING_CYCLE_SHORT_LABELS[usageLimit.unitPriceBillingCycle].toLowerCase()] }))] }) }, tier.id));
1784
2667
  })] }, `${service.id}-${metric}`)))] }));
1785
2668
  }
1786
2669
  function ServiceLevelDetailPanel({ serviceId, tierId, services, tiers, optionGroups: _optionGroups, dispatch, onClose, }) {
@@ -1879,37 +2762,6 @@ function ServiceLevelDetailPanel({ serviceId, tierId, services, tiers, optionGro
1879
2762
  lastModified: new Date().toISOString(),
1880
2763
  }));
1881
2764
  };
1882
- const handleSetLevel = (level) => {
1883
- if (serviceLevel) {
1884
- dispatch(updateServiceLevel({
1885
- tierId: tier.id,
1886
- serviceLevelId: serviceLevel.id,
1887
- level,
1888
- customValue: level === "CUSTOM" ? customValue : undefined,
1889
- lastModified: new Date().toISOString(),
1890
- }));
1891
- }
1892
- else {
1893
- dispatch(addServiceLevel({
1894
- tierId: tier.id,
1895
- serviceLevelId: generateId(),
1896
- serviceId: service.id,
1897
- level,
1898
- customValue: level === "CUSTOM" ? customValue : undefined,
1899
- lastModified: new Date().toISOString(),
1900
- }));
1901
- }
1902
- };
1903
- const handleUpdateCustomValue = () => {
1904
- if (serviceLevel && serviceLevel.level === "CUSTOM") {
1905
- dispatch(updateServiceLevel({
1906
- tierId: tier.id,
1907
- serviceLevelId: serviceLevel.id,
1908
- customValue,
1909
- lastModified: new Date().toISOString(),
1910
- }));
1911
- }
1912
- };
1913
2765
  return (_jsx("div", { ref: overlayRef, className: "matrix__panel-overlay", onClick: handleOverlayClick, role: "dialog", "aria-modal": "true", "aria-labelledby": "panel-title", children: _jsxs("div", { ref: panelRef, className: "matrix__panel", children: [_jsxs("div", { className: "matrix__panel-header", children: [_jsxs("div", { className: "matrix__panel-header-top", children: [_jsxs("span", { className: "matrix__panel-tier", children: [tier.name, " Tier"] }), _jsx("button", { onClick: onClose, className: "matrix__panel-close", children: _jsx("svg", { className: "matrix__panel-close-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] }), _jsx("h3", { id: "panel-title", className: "matrix__panel-title", children: service.title })] }), _jsx("div", { className: "matrix__panel-body", children: _jsxs("div", { children: [_jsxs("div", { className: "matrix__panel-limits-header", children: [_jsx("label", { className: "matrix__panel-section-label", style: { marginBottom: 0 }, children: "Metrics" }), _jsx("button", { onClick: () => setIsAddingMetric(true), className: "matrix__panel-add-btn", children: "+ Add Metric" })] }), usageLimits.map((limit) => (_jsx(MetricLimitItem, { limit: limit, tierId: tier.id, dispatch: dispatch, onRemove: () => handleRemoveLimit(limit.id) }, limit.id))), usageLimits.length === 0 && !isAddingMetric && (_jsx("p", { className: "matrix__panel-empty-text", children: "No metrics added yet. Metrics will appear as nested rows under this service in the matrix." })), isAddingMetric && (_jsxs("div", { className: "matrix__panel-edit-form", children: [_jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Metric Name" }), _jsx("input", { type: "text", value: newMetric, onChange: (e) => setNewMetric(e.target.value), placeholder: "e.g., API Calls, Storage, Users", className: "matrix__panel-input", autoFocus: true })] }), _jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Value" }), _jsx("input", { type: "text", value: newLimit, onChange: (e) => setNewLimit(e.target.value), placeholder: "e.g., 100, Unlimited, Custom", className: "matrix__panel-input" }), _jsx("p", { className: "matrix__panel-edit-hint", children: "Enter a value or leave empty" })] }), _jsxs("div", { className: "matrix__panel-edit-actions", children: [_jsx("button", { onClick: handleAddLimit, disabled: !newMetric.trim(), className: "matrix__panel-edit-btn matrix__panel-edit-btn--primary", children: "Add Metric" }), _jsx("button", { onClick: () => {
1914
2766
  setNewMetric("");
1915
2767
  setNewLimit("");
@@ -1919,27 +2771,53 @@ function ServiceLevelDetailPanel({ serviceId, tierId, services, tiers, optionGro
1919
2771
  function MetricLimitItem({ limit, tierId, dispatch, onRemove, }) {
1920
2772
  const [isEditing, setIsEditing] = useState(false);
1921
2773
  const [editMetric, setEditMetric] = useState(limit.metric);
2774
+ const [editUnitName, setEditUnitName] = useState(limit.unitName || "");
1922
2775
  const [editLimit, setEditLimit] = useState(limit.limit?.toString() || limit.notes || "");
2776
+ // Overage pricing state
2777
+ const [editUnitPrice, setEditUnitPrice] = useState(limit.unitPrice?.toString() || "");
2778
+ const [editUnitPriceCurrency] = useState(limit.unitPriceCurrency || "USD");
2779
+ const [editUnitPriceBillingCycle, setEditUnitPriceBillingCycle] = useState(limit.unitPriceBillingCycle || "");
1923
2780
  const handleSave = () => {
1924
2781
  const parsedLimit = editLimit ? parseInt(editLimit, 10) : null;
1925
2782
  const isNumeric = parsedLimit !== null && !isNaN(parsedLimit);
2783
+ const parsedUnitPrice = editUnitPrice ? parseFloat(editUnitPrice) : null;
1926
2784
  dispatch(updateUsageLimit({
1927
2785
  tierId,
1928
2786
  limitId: limit.id,
1929
2787
  metric: editMetric.trim() || limit.metric,
2788
+ unitName: editUnitName.trim() || undefined,
1930
2789
  limit: isNumeric ? parsedLimit : undefined,
1931
2790
  notes: !isNumeric && editLimit ? editLimit.trim() : undefined,
2791
+ unitPrice: parsedUnitPrice,
2792
+ unitPriceCurrency: parsedUnitPrice && editUnitPriceBillingCycle
2793
+ ? editUnitPriceCurrency
2794
+ : undefined,
2795
+ unitPriceBillingCycle: parsedUnitPrice && editUnitPriceBillingCycle
2796
+ ? editUnitPriceBillingCycle
2797
+ : undefined,
1932
2798
  lastModified: new Date().toISOString(),
1933
2799
  }));
1934
2800
  setIsEditing(false);
1935
2801
  };
1936
2802
  const handleCancel = () => {
1937
2803
  setEditMetric(limit.metric);
2804
+ setEditUnitName(limit.unitName || "");
1938
2805
  setEditLimit(limit.limit?.toString() || limit.notes || "");
2806
+ setEditUnitPrice(limit.unitPrice?.toString() || "");
2807
+ setEditUnitPriceBillingCycle(limit.unitPriceBillingCycle || "");
1939
2808
  setIsEditing(false);
1940
2809
  };
2810
+ // Format overage display string
2811
+ const getOverageDisplay = () => {
2812
+ if (!limit.unitPrice || !limit.unitPriceBillingCycle)
2813
+ return null;
2814
+ const cycleLabel = BILLING_CYCLE_SHORT_LABELS[limit.unitPriceBillingCycle].toLowerCase();
2815
+ const unitLabel = limit.unitName || "unit";
2816
+ return `+${formatPrice(limit.unitPrice, limit.unitPriceCurrency || "USD")} per ${unitLabel}/${cycleLabel}`;
2817
+ };
2818
+ const overageDisplay = getOverageDisplay();
1941
2819
  if (isEditing) {
1942
- return (_jsxs("div", { className: "matrix__panel-edit-form", children: [_jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Metric Name" }), _jsx("input", { type: "text", value: editMetric, onChange: (e) => setEditMetric(e.target.value), placeholder: "Metric name", className: "matrix__panel-input", autoFocus: true })] }), _jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Value" }), _jsx("input", { type: "text", value: editLimit, onChange: (e) => setEditLimit(e.target.value), placeholder: "e.g., 100, Unlimited, Custom", className: "matrix__panel-input" }), _jsx("p", { className: "matrix__panel-edit-hint", children: "Enter a value or leave empty" })] }), _jsxs("div", { className: "matrix__panel-edit-actions", children: [_jsx("button", { onClick: handleSave, className: "matrix__panel-edit-btn matrix__panel-edit-btn--primary", children: "Save" }), _jsx("button", { onClick: handleCancel, className: "matrix__panel-edit-btn matrix__panel-edit-btn--secondary", children: "Cancel" })] })] }));
2820
+ return (_jsxs("div", { className: "matrix__panel-edit-form", children: [_jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Metric Name" }), _jsx("input", { type: "text", value: editMetric, onChange: (e) => setEditMetric(e.target.value), placeholder: "e.g., Number of Entities", className: "matrix__panel-input", autoFocus: true })] }), _jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Unit Name" }), _jsx("input", { type: "text", value: editUnitName, onChange: (e) => setEditUnitName(e.target.value), placeholder: "e.g., entity, credit card, contractor", className: "matrix__panel-input" }), _jsx("p", { className: "matrix__panel-edit-hint", children: "Used for overage pricing display (e.g., \"$50 per entity\")" })] }), _jsxs("div", { children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Included Value" }), _jsx("input", { type: "text", value: editLimit, onChange: (e) => setEditLimit(e.target.value), placeholder: "e.g., 100, Unlimited, Custom", className: "matrix__panel-input" }), _jsx("p", { className: "matrix__panel-edit-hint", children: "Enter limit included in tier or leave empty" })] }), _jsxs("div", { className: "matrix__panel-overage-section", children: [_jsx("label", { className: "matrix__panel-edit-label", children: "Overage Pricing (Optional)" }), _jsx("p", { className: "matrix__panel-edit-hint", style: { marginBottom: "0.5rem" }, children: "Set a price for usage beyond the included limit" }), _jsxs("div", { className: "matrix__panel-overage-row", children: [_jsxs("div", { className: "matrix__panel-overage-price", children: [_jsx("span", { className: "matrix__panel-overage-currency", children: "$" }), _jsx("input", { type: "number", value: editUnitPrice, onChange: (e) => setEditUnitPrice(e.target.value), placeholder: "0.00", step: "0.01", className: "matrix__panel-overage-input" })] }), _jsx("span", { className: "matrix__panel-overage-separator", children: "/" }), _jsxs("select", { value: editUnitPriceBillingCycle, onChange: (e) => setEditUnitPriceBillingCycle(e.target.value || ""), className: "matrix__panel-overage-select", children: [_jsx("option", { value: "", children: "No overage" }), RECURRING_BILLING_CYCLES.map((cycle) => (_jsx("option", { value: cycle, children: BILLING_CYCLE_SHORT_LABELS[cycle] }, cycle)))] }), _jsxs("span", { className: "matrix__panel-overage-label", children: ["per ", editUnitName || "unit"] })] })] }), _jsxs("div", { className: "matrix__panel-edit-actions", children: [_jsx("button", { onClick: handleSave, className: "matrix__panel-edit-btn matrix__panel-edit-btn--primary", children: "Save" }), _jsx("button", { onClick: handleCancel, className: "matrix__panel-edit-btn matrix__panel-edit-btn--secondary", children: "Cancel" })] })] }));
1943
2821
  }
1944
- return (_jsxs("div", { className: "matrix__panel-limit-item", children: [_jsxs("div", { className: "matrix__panel-limit-content", onClick: () => setIsEditing(true), children: [_jsx("div", { className: "matrix__panel-limit-metric", children: limit.metric }), _jsx("div", { className: "matrix__panel-limit-value", children: limit.limit ?? limit.notes ?? "—" })] }), _jsxs("div", { className: "matrix__panel-limit-actions", children: [_jsx("button", { onClick: () => setIsEditing(true), className: "matrix__panel-limit-btn matrix__panel-limit-btn--edit", title: "Edit metric", children: _jsx("svg", { className: "matrix__panel-limit-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" }) }) }), _jsx("button", { onClick: onRemove, className: "matrix__panel-limit-btn matrix__panel-limit-btn--remove", title: "Remove metric", children: _jsx("svg", { className: "matrix__panel-limit-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] })] }));
2822
+ return (_jsxs("div", { className: "matrix__panel-limit-item", children: [_jsxs("div", { className: "matrix__panel-limit-content", onClick: () => setIsEditing(true), children: [_jsx("div", { className: "matrix__panel-limit-metric", children: limit.metric }), _jsxs("div", { className: "matrix__panel-limit-value-group", children: [_jsx("div", { className: "matrix__panel-limit-value", children: limit.limit ?? limit.notes ?? "—" }), overageDisplay && (_jsx("div", { className: "matrix__panel-limit-overage", children: overageDisplay }))] })] }), _jsxs("div", { className: "matrix__panel-limit-actions", children: [_jsx("button", { onClick: () => setIsEditing(true), className: "matrix__panel-limit-btn matrix__panel-limit-btn--edit", title: "Edit metric", children: _jsx("svg", { className: "matrix__panel-limit-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" }) }) }), _jsx("button", { onClick: onRemove, className: "matrix__panel-limit-btn matrix__panel-limit-btn--remove", title: "Remove metric", children: _jsx("svg", { className: "matrix__panel-limit-icon", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })] })] }));
1945
2823
  }