generator-pninja 1.1.1 → 1.2.1

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 (264) hide show
  1. package/README.md +117 -9
  2. package/generators/app/index.js +1 -19
  3. package/generators/client/react.inc.js +39 -10
  4. package/generators/client/templates/react/index.html.ejs +4 -1
  5. package/generators/client/templates/react/package-lock.json.ejs +373 -12
  6. package/generators/client/templates/react/package.json.ejs +1 -1
  7. package/generators/client/templates/react/public/fonts/material-symbols-outlined.woff2 +0 -0
  8. package/generators/client/templates/react/public/fonts/material-symbols-rounded.woff2 +0 -0
  9. package/generators/client/templates/react/public/fonts/material-symbols-sharp.woff2 +0 -0
  10. package/generators/client/templates/react/public/locales/audit/am.json +109 -0
  11. package/generators/client/templates/react/public/locales/audit/ar.json +109 -0
  12. package/generators/client/templates/react/public/locales/audit/az.json +109 -0
  13. package/generators/client/templates/react/public/locales/audit/bg.json +109 -0
  14. package/generators/client/templates/react/public/locales/audit/bn.json +109 -0
  15. package/generators/client/templates/react/public/locales/audit/ca.json +109 -0
  16. package/generators/client/templates/react/public/locales/audit/cs.json +109 -0
  17. package/generators/client/templates/react/public/locales/audit/cy.json +109 -0
  18. package/generators/client/templates/react/public/locales/audit/da.json +109 -0
  19. package/generators/client/templates/react/public/locales/audit/de.json +109 -0
  20. package/generators/client/templates/react/public/locales/audit/el.json +109 -0
  21. package/generators/client/templates/react/public/locales/audit/en.json +109 -0
  22. package/generators/client/templates/react/public/locales/audit/es.json +109 -0
  23. package/generators/client/templates/react/public/locales/audit/et.json +109 -0
  24. package/generators/client/templates/react/public/locales/audit/eu.json +109 -0
  25. package/generators/client/templates/react/public/locales/audit/fa.json +109 -0
  26. package/generators/client/templates/react/public/locales/audit/fi.json +109 -0
  27. package/generators/client/templates/react/public/locales/audit/fr.json +109 -0
  28. package/generators/client/templates/react/public/locales/audit/fy.json +109 -0
  29. package/generators/client/templates/react/public/locales/audit/ga.json +109 -0
  30. package/generators/client/templates/react/public/locales/audit/gl.json +109 -0
  31. package/generators/client/templates/react/public/locales/audit/gu.json +109 -0
  32. package/generators/client/templates/react/public/locales/audit/ha.json +109 -0
  33. package/generators/client/templates/react/public/locales/audit/he.json +109 -0
  34. package/generators/client/templates/react/public/locales/audit/hi.json +109 -0
  35. package/generators/client/templates/react/public/locales/audit/hr.json +109 -0
  36. package/generators/client/templates/react/public/locales/audit/ht.json +109 -0
  37. package/generators/client/templates/react/public/locales/audit/hu.json +109 -0
  38. package/generators/client/templates/react/public/locales/audit/hy.json +109 -0
  39. package/generators/client/templates/react/public/locales/audit/id.json +109 -0
  40. package/generators/client/templates/react/public/locales/audit/is.json +109 -0
  41. package/generators/client/templates/react/public/locales/audit/it.json +109 -0
  42. package/generators/client/templates/react/public/locales/audit/ja.json +109 -0
  43. package/generators/client/templates/react/public/locales/audit/kk.json +109 -0
  44. package/generators/client/templates/react/public/locales/audit/ko.json +109 -0
  45. package/generators/client/templates/react/public/locales/audit/lt.json +109 -0
  46. package/generators/client/templates/react/public/locales/audit/lv.json +109 -0
  47. package/generators/client/templates/react/public/locales/audit/mi.json +109 -0
  48. package/generators/client/templates/react/public/locales/audit/ms.json +109 -0
  49. package/generators/client/templates/react/public/locales/audit/mt.json +109 -0
  50. package/generators/client/templates/react/public/locales/audit/nl.json +109 -0
  51. package/generators/client/templates/react/public/locales/audit/no.json +109 -0
  52. package/generators/client/templates/react/public/locales/audit/om.json +109 -0
  53. package/generators/client/templates/react/public/locales/audit/pl.json +109 -0
  54. package/generators/client/templates/react/public/locales/audit/pt.json +109 -0
  55. package/generators/client/templates/react/public/locales/audit/ro.json +109 -0
  56. package/generators/client/templates/react/public/locales/audit/ru.json +109 -0
  57. package/generators/client/templates/react/public/locales/audit/rw.json +109 -0
  58. package/generators/client/templates/react/public/locales/audit/sk.json +109 -0
  59. package/generators/client/templates/react/public/locales/audit/sl.json +109 -0
  60. package/generators/client/templates/react/public/locales/audit/sq.json +109 -0
  61. package/generators/client/templates/react/public/locales/audit/sr.json +109 -0
  62. package/generators/client/templates/react/public/locales/audit/sv.json +109 -0
  63. package/generators/client/templates/react/public/locales/audit/sw.json +109 -0
  64. package/generators/client/templates/react/public/locales/audit/ta.json +109 -0
  65. package/generators/client/templates/react/public/locales/audit/tr.json +109 -0
  66. package/generators/client/templates/react/public/locales/audit/uk.json +109 -0
  67. package/generators/client/templates/react/public/locales/audit/ur.json +109 -0
  68. package/generators/client/templates/react/public/locales/audit/uz.json +109 -0
  69. package/generators/client/templates/react/public/locales/audit/vi.json +109 -0
  70. package/generators/client/templates/react/public/locales/audit/yo.json +109 -0
  71. package/generators/client/templates/react/public/locales/audit/zh.json +109 -0
  72. package/generators/client/templates/react/public/locales/audit/zu.json +109 -0
  73. package/generators/client/templates/react/public/locales/{am.json.ejs → common/am.json.ejs} +25 -4
  74. package/generators/client/templates/react/public/locales/{ar.json.ejs → common/ar.json.ejs} +25 -4
  75. package/generators/client/templates/react/public/locales/{az.json.ejs → common/az.json.ejs} +25 -4
  76. package/generators/client/templates/react/public/locales/{bg.json.ejs → common/bg.json.ejs} +25 -4
  77. package/generators/client/templates/react/public/locales/{bn.json.ejs → common/bn.json.ejs} +25 -4
  78. package/generators/client/templates/react/public/locales/{ca.json.ejs → common/ca.json.ejs} +25 -4
  79. package/generators/client/templates/react/public/locales/{cs.json.ejs → common/cs.json.ejs} +25 -4
  80. package/generators/client/templates/react/public/locales/{cy.json.ejs → common/cy.json.ejs} +25 -4
  81. package/generators/client/templates/react/public/locales/{da.json.ejs → common/da.json.ejs} +25 -4
  82. package/generators/client/templates/react/public/locales/{de.json.ejs → common/de.json.ejs} +25 -4
  83. package/generators/client/templates/react/public/locales/{el.json.ejs → common/el.json.ejs} +25 -4
  84. package/generators/client/templates/react/public/locales/{en.json.ejs → common/en.json.ejs} +25 -4
  85. package/generators/client/templates/react/public/locales/{es.json.ejs → common/es.json.ejs} +25 -4
  86. package/generators/client/templates/react/public/locales/{et.json.ejs → common/et.json.ejs} +25 -4
  87. package/generators/client/templates/react/public/locales/{eu.json.ejs → common/eu.json.ejs} +25 -4
  88. package/generators/client/templates/react/public/locales/{fa.json.ejs → common/fa.json.ejs} +25 -4
  89. package/generators/client/templates/react/public/locales/{fi.json.ejs → common/fi.json.ejs} +25 -4
  90. package/generators/client/templates/react/public/locales/{fr.json.ejs → common/fr.json.ejs} +25 -4
  91. package/generators/client/templates/react/public/locales/{fy.json.ejs → common/fy.json.ejs} +25 -4
  92. package/generators/client/templates/react/public/locales/{ga.json.ejs → common/ga.json.ejs} +25 -4
  93. package/generators/client/templates/react/public/locales/{gl.json.ejs → common/gl.json.ejs} +25 -4
  94. package/generators/client/templates/react/public/locales/{gu.json.ejs → common/gu.json.ejs} +25 -4
  95. package/generators/client/templates/react/public/locales/{ha.json.ejs → common/ha.json.ejs} +25 -4
  96. package/generators/client/templates/react/public/locales/{he.json.ejs → common/he.json.ejs} +25 -4
  97. package/generators/client/templates/react/public/locales/{hi.json.ejs → common/hi.json.ejs} +25 -4
  98. package/generators/client/templates/react/public/locales/{hr.json.ejs → common/hr.json.ejs} +25 -4
  99. package/generators/client/templates/react/public/locales/{ht.json.ejs → common/ht.json.ejs} +25 -4
  100. package/generators/client/templates/react/public/locales/{hu.json.ejs → common/hu.json.ejs} +25 -4
  101. package/generators/client/templates/react/public/locales/{hy.json.ejs → common/hy.json.ejs} +25 -4
  102. package/generators/client/templates/react/public/locales/{id.json.ejs → common/id.json.ejs} +25 -4
  103. package/generators/client/templates/react/public/locales/{is.json.ejs → common/is.json.ejs} +25 -4
  104. package/generators/client/templates/react/public/locales/{it.json.ejs → common/it.json.ejs} +25 -4
  105. package/generators/client/templates/react/public/locales/{ja.json.ejs → common/ja.json.ejs} +25 -4
  106. package/generators/client/templates/react/public/locales/{kk.json.ejs → common/kk.json.ejs} +25 -4
  107. package/generators/client/templates/react/public/locales/{ko.json.ejs → common/ko.json.ejs} +25 -4
  108. package/generators/client/templates/react/public/locales/{lt.json.ejs → common/lt.json.ejs} +25 -4
  109. package/generators/client/templates/react/public/locales/{lv.json.ejs → common/lv.json.ejs} +25 -4
  110. package/generators/client/templates/react/public/locales/{mi.json.ejs → common/mi.json.ejs} +25 -4
  111. package/generators/client/templates/react/public/locales/{ms.json.ejs → common/ms.json.ejs} +25 -4
  112. package/generators/client/templates/react/public/locales/{mt.json.ejs → common/mt.json.ejs} +25 -4
  113. package/generators/client/templates/react/public/locales/{nl.json.ejs → common/nl.json.ejs} +25 -4
  114. package/generators/client/templates/react/public/locales/{no.json.ejs → common/no.json.ejs} +25 -4
  115. package/generators/client/templates/react/public/locales/{om.json.ejs → common/om.json.ejs} +25 -4
  116. package/generators/client/templates/react/public/locales/{pl.json.ejs → common/pl.json.ejs} +25 -4
  117. package/generators/client/templates/react/public/locales/{pt.json.ejs → common/pt.json.ejs} +25 -4
  118. package/generators/client/templates/react/public/locales/{ro.json.ejs → common/ro.json.ejs} +25 -4
  119. package/generators/client/templates/react/public/locales/{ru.json.ejs → common/ru.json.ejs} +25 -4
  120. package/generators/client/templates/react/public/locales/{rw.json.ejs → common/rw.json.ejs} +25 -4
  121. package/generators/client/templates/react/public/locales/{sk.json.ejs → common/sk.json.ejs} +25 -4
  122. package/generators/client/templates/react/public/locales/{sl.json.ejs → common/sl.json.ejs} +25 -4
  123. package/generators/client/templates/react/public/locales/{sq.json.ejs → common/sq.json.ejs} +25 -4
  124. package/generators/client/templates/react/public/locales/{sr.json.ejs → common/sr.json.ejs} +25 -4
  125. package/generators/client/templates/react/public/locales/{sv.json.ejs → common/sv.json.ejs} +25 -4
  126. package/generators/client/templates/react/public/locales/{sw.json.ejs → common/sw.json.ejs} +25 -4
  127. package/generators/client/templates/react/public/locales/{ta.json.ejs → common/ta.json.ejs} +25 -4
  128. package/generators/client/templates/react/public/locales/{tr.json.ejs → common/tr.json.ejs} +25 -4
  129. package/generators/client/templates/react/public/locales/{uk.json.ejs → common/uk.json.ejs} +25 -4
  130. package/generators/client/templates/react/public/locales/{ur.json.ejs → common/ur.json.ejs} +25 -4
  131. package/generators/client/templates/react/public/locales/{uz.json.ejs → common/uz.json.ejs} +25 -4
  132. package/generators/client/templates/react/public/locales/{vi.json.ejs → common/vi.json.ejs} +25 -4
  133. package/generators/client/templates/react/public/locales/{yo.json.ejs → common/yo.json.ejs} +25 -4
  134. package/generators/client/templates/react/public/locales/{zh.json.ejs → common/zh.json.ejs} +25 -4
  135. package/generators/client/templates/react/public/locales/{zu.json.ejs → common/zu.json.ejs} +25 -4
  136. package/generators/client/templates/react/public/locales/{entities.json.ejs → entities/entities.json.ejs} +0 -12
  137. package/generators/client/templates/react/public/locales/log/am.json +28 -0
  138. package/generators/client/templates/react/public/locales/log/ar.json +28 -0
  139. package/generators/client/templates/react/public/locales/log/az.json +28 -0
  140. package/generators/client/templates/react/public/locales/log/bg.json +28 -0
  141. package/generators/client/templates/react/public/locales/log/bn.json +28 -0
  142. package/generators/client/templates/react/public/locales/log/ca.json +28 -0
  143. package/generators/client/templates/react/public/locales/log/cs.json +28 -0
  144. package/generators/client/templates/react/public/locales/log/cy.json +28 -0
  145. package/generators/client/templates/react/public/locales/log/da.json +28 -0
  146. package/generators/client/templates/react/public/locales/log/de.json +28 -0
  147. package/generators/client/templates/react/public/locales/log/el.json +28 -0
  148. package/generators/client/templates/react/public/locales/log/en.json +28 -0
  149. package/generators/client/templates/react/public/locales/log/es.json +28 -0
  150. package/generators/client/templates/react/public/locales/log/et.json +28 -0
  151. package/generators/client/templates/react/public/locales/log/eu.json +28 -0
  152. package/generators/client/templates/react/public/locales/log/fa.json +28 -0
  153. package/generators/client/templates/react/public/locales/log/fi.json +28 -0
  154. package/generators/client/templates/react/public/locales/log/fr.json +28 -0
  155. package/generators/client/templates/react/public/locales/log/fy.json +28 -0
  156. package/generators/client/templates/react/public/locales/log/ga.json +28 -0
  157. package/generators/client/templates/react/public/locales/log/gl.json +28 -0
  158. package/generators/client/templates/react/public/locales/log/gu.json +28 -0
  159. package/generators/client/templates/react/public/locales/log/ha.json +28 -0
  160. package/generators/client/templates/react/public/locales/log/he.json +28 -0
  161. package/generators/client/templates/react/public/locales/log/hi.json +28 -0
  162. package/generators/client/templates/react/public/locales/log/hr.json +28 -0
  163. package/generators/client/templates/react/public/locales/log/ht.json +28 -0
  164. package/generators/client/templates/react/public/locales/log/hu.json +28 -0
  165. package/generators/client/templates/react/public/locales/log/hy.json +28 -0
  166. package/generators/client/templates/react/public/locales/log/id.json +28 -0
  167. package/generators/client/templates/react/public/locales/log/is.json +28 -0
  168. package/generators/client/templates/react/public/locales/log/it.json +28 -0
  169. package/generators/client/templates/react/public/locales/log/ja.json +28 -0
  170. package/generators/client/templates/react/public/locales/log/kk.json +28 -0
  171. package/generators/client/templates/react/public/locales/log/ko.json +28 -0
  172. package/generators/client/templates/react/public/locales/log/lt.json +28 -0
  173. package/generators/client/templates/react/public/locales/log/lv.json +28 -0
  174. package/generators/client/templates/react/public/locales/log/mi.json +28 -0
  175. package/generators/client/templates/react/public/locales/log/ms.json +28 -0
  176. package/generators/client/templates/react/public/locales/log/mt.json +28 -0
  177. package/generators/client/templates/react/public/locales/log/nl.json +28 -0
  178. package/generators/client/templates/react/public/locales/log/no.json +28 -0
  179. package/generators/client/templates/react/public/locales/log/om.json +28 -0
  180. package/generators/client/templates/react/public/locales/log/pl.json +28 -0
  181. package/generators/client/templates/react/public/locales/log/pt.json +28 -0
  182. package/generators/client/templates/react/public/locales/log/ro.json +28 -0
  183. package/generators/client/templates/react/public/locales/log/ru.json +28 -0
  184. package/generators/client/templates/react/public/locales/log/rw.json +28 -0
  185. package/generators/client/templates/react/public/locales/log/sk.json +28 -0
  186. package/generators/client/templates/react/public/locales/log/sl.json +28 -0
  187. package/generators/client/templates/react/public/locales/log/sq.json +28 -0
  188. package/generators/client/templates/react/public/locales/log/sr.json +28 -0
  189. package/generators/client/templates/react/public/locales/log/sv.json +28 -0
  190. package/generators/client/templates/react/public/locales/log/sw.json +28 -0
  191. package/generators/client/templates/react/public/locales/log/ta.json +28 -0
  192. package/generators/client/templates/react/public/locales/log/tr.json +28 -0
  193. package/generators/client/templates/react/public/locales/log/uk.json +28 -0
  194. package/generators/client/templates/react/public/locales/log/ur.json +28 -0
  195. package/generators/client/templates/react/public/locales/log/uz.json +28 -0
  196. package/generators/client/templates/react/public/locales/log/vi.json +28 -0
  197. package/generators/client/templates/react/public/locales/log/yo.json +28 -0
  198. package/generators/client/templates/react/public/locales/log/zh.json +28 -0
  199. package/generators/client/templates/react/public/locales/log/zu.json +28 -0
  200. package/generators/client/templates/react/src/App.tsx.ejs +46 -17
  201. package/generators/client/templates/react/src/components/ApiResponsePagination.tsx.ejs +3 -3
  202. package/generators/client/templates/react/src/components/ConfirmButton.tsx.ejs +43 -8
  203. package/generators/client/templates/react/src/components/DarkModeToggle.tsx.ejs +16 -3
  204. package/generators/client/templates/react/src/components/Footer.tsx.ejs +1 -1
  205. package/generators/client/templates/react/src/components/HtmlViewer.tsx.ejs +15 -13
  206. package/generators/client/templates/react/src/components/Icon.tsx.ejs +104 -0
  207. package/generators/client/templates/react/src/components/LangSelect.tsx.ejs +8 -4
  208. package/generators/client/templates/react/src/components/LoginButton.tsx.ejs +4 -4
  209. package/generators/client/templates/react/src/components/LogoutButton.tsx.ejs +11 -3
  210. package/generators/client/templates/react/src/components/Menu.tsx.ejs +105 -42
  211. package/generators/client/templates/react/src/components/SearchInput.tsx.ejs +5 -5
  212. package/generators/client/templates/react/src/components/SimpleLoader.tsx.ejs +4 -3
  213. package/generators/client/templates/react/src/components/Toast.tsx.ejs +30 -32
  214. package/generators/client/templates/react/src/components/entities/EntityDeleteButton.tsx.ejs +12 -2
  215. package/generators/client/templates/react/src/components/entities/EntityForm.tsx.ejs +15 -5
  216. package/generators/client/templates/react/src/components/formElements/Checkbox.tsx.ejs +5 -8
  217. package/generators/client/templates/react/src/components/formElements/ColorField.tsx.ejs +2 -2
  218. package/generators/client/templates/react/src/components/formElements/DurationField.tsx.ejs +1 -1
  219. package/generators/client/templates/react/src/components/formElements/FileField.tsx.ejs +32 -20
  220. package/generators/client/templates/react/src/components/formElements/FormLabel.tsx.ejs +2 -4
  221. package/generators/client/templates/react/src/components/formElements/InfoValidations.tsx.ejs +0 -98
  222. package/generators/client/templates/react/src/components/formElements/PasswordField.tsx.ejs +104 -34
  223. package/generators/client/templates/react/src/components/formElements/RadioGroup.tsx.ejs +5 -19
  224. package/generators/client/templates/react/src/components/formElements/RangeField.tsx.ejs +1 -1
  225. package/generators/client/templates/react/src/components/formElements/SelectField.tsx.ejs +22 -12
  226. package/generators/client/templates/react/src/components/formElements/UuidField.tsx.ejs +3 -3
  227. package/generators/client/templates/react/src/i18n.js.ejs +1 -1
  228. package/generators/client/templates/react/src/index.css.ejs +46 -7
  229. package/generators/client/templates/react/src/pages/audit/AuditHistory.tsx.ejs +147 -0
  230. package/generators/client/templates/react/src/pages/audit/AuditList.tsx.ejs +396 -0
  231. package/generators/client/templates/react/src/pages/audit/AuditStatistics.tsx.ejs +508 -0
  232. package/generators/client/templates/react/src/pages/audit/AuditUserActivity.tsx.ejs +585 -0
  233. package/generators/client/templates/react/src/pages/audit/AuditView.tsx.ejs +300 -0
  234. package/generators/client/templates/react/src/pages/audit/Audits.tsx.ejs +53 -0
  235. package/generators/client/templates/react/src/pages/entities/EntityList.tsx.ejs +8 -18
  236. package/generators/client/templates/react/src/pages/entities/EntityTrash.tsx.ejs +446 -0
  237. package/generators/client/templates/react/src/pages/entities/EntityView.tsx.ejs +2 -2
  238. package/generators/client/templates/react/src/pages/server-logs/LogViewer.tsx.ejs +282 -0
  239. package/generators/client/templates/react/src/shared/entitiesIcons.tsx.ejs +14 -0
  240. package/generators/entities/index.js +11 -1
  241. package/generators/entities/templates/DatabaseSeeder.php.ejs +53 -6
  242. package/generators/entities/templates/app/Http/Controllers/AuditController.php.ejs +702 -0
  243. package/generators/entities/templates/app/Http/Controllers/LogController.php.ejs +119 -0
  244. package/generators/entities/templates/app/Http/Controllers/TrashedEntityController.php.ejs +63 -0
  245. package/generators/entities/templates/app/Models/Entity.php.ejs +9 -1
  246. package/generators/entities/templates/app/Resolvers/Keycloak__UserResolver.php.ejs +34 -0
  247. package/generators/entities/templates/config/audit.php.ejs +202 -0
  248. package/generators/entities/templates/database/migrations/create_audits_table.php.ejs +52 -0
  249. package/generators/entities/templates/migration_create_table.php.ejs +3 -0
  250. package/generators/entities/templates/routes/api.php.ejs +21 -2
  251. package/generators/entities/templates/routes/console.php.ejs +6 -0
  252. package/generators/entities/utils/controllers-generator.js +27 -2
  253. package/generators/entities/utils/factories-generator.js +2 -1
  254. package/generators/entities/utils/migrations-generator.js +9 -2
  255. package/generators/entities/utils/models-generator.js +9 -2
  256. package/generators/entities/utils/routers-generator.js +19 -3
  257. package/generators/final/index.js +5 -3
  258. package/generators/{app → final}/templates/README.md.ejs +57 -1
  259. package/generators/search/index.js +5 -5
  260. package/generators/utils/AcRule.js +47 -0
  261. package/package.json +1 -1
  262. package/generators/client/templates/react/src/pages/entities/AcRuleEdit.tsx.ejs +0 -87
  263. package/generators/client/templates/react/src/pages/entities/AcRuleList.tsx.ejs +0 -222
  264. package/generators/client/templates/react/src/pages/entities/AcRuleView.tsx.ejs +0 -127
package/README.md CHANGED
@@ -60,15 +60,73 @@ yo pninja
60
60
 
61
61
  ```
62
62
  my-app/
63
- ├── client/ # React + Vite app
64
- ├── docker/ # Docker compose
65
- ├── server/ # Laravel project
66
- ├── package.json # With commands
63
+ ├── client/ # React + Vite app
64
+ ├── docker/ # Docker compose
65
+ ├── server/ # Laravel project
66
+ ├── package.json # With commands
67
67
  └── README.md
68
68
  ```
69
69
 
70
70
  Fully wired together: auth, routing, forms, CRUD, migrations.
71
71
 
72
+ ## Core Features
73
+
74
+ ### Authentication & Authorization
75
+
76
+ - **Keycloak Integration** - Enterprise-grade authentication
77
+ - **ACL System (Casbin)** - Fine-grained access control with policies and roles
78
+ - **Role-based Permissions** - Manage user permissions across entities
79
+
80
+ ### Data Management
81
+
82
+ - **Soft Delete Support** - Logical deletion with `deleted_at` timestamps (use `@softDelete` annotation in JDL)
83
+ ```jdl
84
+ @softDelete
85
+ entity MyEntity {
86
+ name String required
87
+ description String
88
+ }
89
+ ```
90
+ - **CSV Database Seeding** - Populate your database from CSV files
91
+ - **Audit Logging** - Complete change tracking for all entity modifications
92
+
93
+ ### Search & Indexing
94
+
95
+ - **Multiple Search Engines** - Choose from Database, Algolia, Elasticsearch, Meilisearch, Typesense, or Solr
96
+ - **Laravel Scout Integration** - Seamless search engine configuration
97
+
98
+ ### Accessibility & UX
99
+
100
+ - **WCAG 2.1 Level AA Compliance** - Built-in accessibility standards
101
+ - **React Aria Components** - Accessible form components out-of-the-box
102
+ - **Keyboard Navigation** - Full keyboard support for all interactions
103
+ - **Screen Reader Support** - Optimized for assistive technologies
104
+
105
+ ### Internationalization
106
+
107
+ - **i18next Integration** - Multi-language support ready to use
108
+ - **RTL Support** - Right-to-left language compatibility
109
+
110
+ ### Modern UI/UX
111
+
112
+ - **Responsive Design** - Mobile-first approach
113
+ - **Tailwind CSS** - Utility-first styling
114
+ - **Material Symbols Icons** - Associate icons to entities using `@icon` annotation in JDL
115
+ ```jdl
116
+ @icon("star")
117
+ entity MyEntity {
118
+ name String required
119
+ description String
120
+ }
121
+ ```
122
+ - **Component Library** - Pre-built accessible components
123
+
124
+ ### DevOps Ready
125
+
126
+ - **Docker Compose** - Full containerization support
127
+ - **Environment Configuration** - Easy setup for different environments
128
+ - **Database Migrations** - Version-controlled schema changes
129
+
72
130
  ## Supported Technologies and Limitations
73
131
 
74
132
  ### Server Framework (PHP)
@@ -87,16 +145,53 @@ Fully wired together: auth, routing, forms, CRUD, migrations.
87
145
 
88
146
  - [Keycloak][keycloak-url]
89
147
 
148
+ ### Authorization
149
+
150
+ - [Casbin][casbin-url] - Policy-based access control
151
+
90
152
  ### Search Engines
91
153
 
92
154
  - [Algolia][algolia-url], [Elasticsearch][elasticsearch-url], [Meilisearch][meilisearch-url], [Typesense][typesense-url], [Solr][solr-url], Database
93
155
 
94
- ### Roadmap
156
+ ### Frontend Libraries
95
157
 
96
- - [Vue][vue-url] & [Angular][angular-url] support
97
- - [SQL Server][sqlserver-url] & [Oracle][oracle-url] support
98
- - Authentication improvements ([Laravel Sanctum][sanctum-url] / [OAuth2][oauth2-url])
99
- - GitHub CI
158
+ - [Tailwind CSS][tailwind-url]
159
+ - [React Aria][react-aria-url] - Accessible component primitives
160
+ - [Material Symbols][material-symbols-url] - Icon library
161
+
162
+ ### Internationalization
163
+
164
+ - [i18next][i18next-url]
165
+
166
+ ## Roadmap
167
+
168
+ ### Frontend Frameworks
169
+
170
+ - [Vue][vue-url] support
171
+ - [Angular][angular-url] support
172
+
173
+ ### Database Support
174
+
175
+ - [SQL Server][sqlserver-url] support
176
+ - [Oracle][oracle-url] support
177
+
178
+ ### Features
179
+
180
+ - **Multi-tenancy Support** - Isolated data per tenant
181
+ - **API Versioning** - Version management for APIs
182
+ - **Real-time Features** - WebSockets/Pusher integration
183
+ - **GraphQL Support** - Alternative API layer
184
+ - **Advanced Caching** - Redis integration with cache strategies
185
+
186
+ ### DevOps
187
+
188
+ - **GitHub Actions CI/CD** - Automated testing and deployment
189
+ - **Kubernetes Support** - Container orchestration configs
190
+
191
+ ### Authentication Enhancements
192
+
193
+ - [Laravel Sanctum][sanctum-url] - SPA authentication option
194
+ - Social Login (Google, GitHub, Facebook)
100
195
 
101
196
  ## GitHub Repository
102
197
 
@@ -104,6 +199,14 @@ The source code for **generator-pninja** is hosted on GitHub. You can access the
104
199
 
105
200
  [Generator PNinja GitHub Repository](https://github.com/consiglionazionaledellericerche/generator-pninja)
106
201
 
202
+ ## Contributing
203
+
204
+ Contributions are welcome! Feel free to open issues or pull requests on the [GitHub repository](https://github.com/consiglionazionaledellericerche/generator-pninja).
205
+
206
+ ## Support
207
+
208
+ For issues, questions, or feature requests, please use the [GitHub Issues](https://github.com/consiglionazionaledellericerche/generator-pninja/issues) page.
209
+
107
210
  [laravel-url]: https://laravel.com/
108
211
  [sqlite-url]: https://www.sqlite.org/
109
212
  [mysql-url]: https://www.mysql.com/
@@ -114,6 +217,7 @@ The source code for **generator-pninja** is hosted on GitHub. You can access the
114
217
  [npm-url]: https://www.npmjs.com/
115
218
  [yarn-url]: https://yarnpkg.com/
116
219
  [keycloak-url]: https://www.keycloak.org/
220
+ [casbin-url]: https://casbin.org/
117
221
  [session-auth-url]: https://laravel.com/docs/session
118
222
  [sanctum-url]: https://laravel.com/docs/sanctum
119
223
  [oauth2-url]: https://oauth.net/2/
@@ -129,6 +233,10 @@ The source code for **generator-pninja** is hosted on GitHub. You can access the
129
233
  [typesense-url]: https://typesense.org/
130
234
  [solr-url]: https://solr.apache.org/
131
235
  [docker-compose-url]: https://docs.docker.com/compose/
236
+ [tailwind-url]: https://tailwindcss.com/
237
+ [react-aria-url]: https://react-spectrum.adobe.com/react-aria/
238
+ [material-symbols-url]: https://fonts.google.com/icons
239
+ [i18next-url]: https://www.i18next.com/
132
240
  [license-badge]: https://img.shields.io/badge/License-Apache_2.0-blue.svg
133
241
  [license-url]: https://opensource.org/licenses/Apache-2.0
134
242
  [npm-version-badge]: https://badge.fury.io/js/generator-pninja.svg
@@ -145,23 +145,6 @@ export default class extends Generator {
145
145
  disabled: "Not implemented yet"
146
146
  }
147
147
  ]
148
- }, {
149
- store: true,
150
- type: "list",
151
- name: "packageManager",
152
- message: "Your package manager",
153
- default: "npm",
154
- choices: [
155
- {
156
- name: "Npm",
157
- value: "npm"
158
- },
159
- {
160
- name: "Yarn",
161
- value: "yarn",
162
- disabled: "Not implemented yet"
163
- }
164
- ]
165
148
  },
166
149
  ]);
167
150
  }
@@ -174,12 +157,11 @@ export default class extends Generator {
174
157
  }
175
158
 
176
159
  async writing() {
177
- const { entities, relationships } = this.fs.readJSON(this.destinationPath(`.pninja/Entities.json`));
178
- this.fs.copyTpl(this.templatePath(`README.md.ejs`), this.destinationPath(`README.md`), { appName: this.config.get('name'), entities, relationships, searchEngine: this.config.get('searchEngine') });
179
160
  await this.spawn('composer', ['create-project', '--prefer-dist', 'laravel/laravel=~11.6.1', 'server']);
180
161
  await this.spawn('composer', ['require', '--dev', 'beyondcode/laravel-dump-server'], { cwd: 'server' });
181
162
  await this.spawn('php', ['artisan', 'install:api', '--without-migration-prompt'], { cwd: 'server' });
182
163
  await this.spawn('composer', ['require', 'casbin/laravel-authz'], { cwd: 'server' });
164
+ await this.spawn('composer', ['require', 'owen-it/laravel-auditing'], { cwd: 'server' });
183
165
  let envFileContents = fs.readFileSync(`${this.destinationPath('server')}/.env`, { encoding: 'utf8', flag: 'r' });
184
166
  envFileContents = envFileContents.replace(/^APP_NAME=.*$/m, `APP_NAME=${to.constant(this.answers.name)}`);
185
167
  envFileContents = envFileContents.replace(/^APP_KEY=.*$/m, `APP_KEY=${randomstring.generate()}`);
@@ -3,7 +3,7 @@ import pluralize from 'pluralize';
3
3
  import { getModelRelatedEntities } from './utils/getModelRelatedEntities.js';
4
4
  import { getModelForeignIds } from './utils/getModelForeignIds.js';
5
5
  import { getLanguageData } from './config/languages.js';
6
-
6
+ import { AcRule } from '../utils/AcRule.js';
7
7
  const colors = [
8
8
  "lime",
9
9
  "green",
@@ -43,15 +43,20 @@ export async function createReactClient(that, parsedJDL) {
43
43
  that.fs.copyTpl(that.templatePath('react/vite.config.ts.ejs'), that.destinationPath('client/vite.config.ts'), {});
44
44
 
45
45
  for (const lang of languages) {
46
- that.fs.copyTpl(that.templatePath(`react/public/locales/${lang}.json.ejs`), that.destinationPath(`client/public/locales/${lang}/common.json`), { appName });
47
- that.fs.copyTpl(that.templatePath(`react/public/locales/entities.json.ejs`), that.destinationPath(`client/public/locales/${lang}/entities.json`), { entities, relationships, to, pluralize, getModelForeignIds, getModelRelatedEntities });
46
+ that.fs.copyTpl(that.templatePath(`react/public/locales/log/${lang}.json`), that.destinationPath(`client/public/locales/${lang}/log.json`), { appName });
47
+ that.fs.copyTpl(that.templatePath(`react/public/locales/audit/${lang}.json`), that.destinationPath(`client/public/locales/${lang}/audit.json`), { appName });
48
+ that.fs.copyTpl(that.templatePath(`react/public/locales/common/${lang}.json.ejs`), that.destinationPath(`client/public/locales/${lang}/common.json`), { appName });
49
+ that.fs.copyTpl(that.templatePath(`react/public/locales/entities/entities.json.ejs`), that.destinationPath(`client/public/locales/${lang}/entities.json`), { entities: [AcRule, ...entities], relationships, to, pluralize, getModelForeignIds, getModelRelatedEntities });
48
50
  };
51
+ that.fs.copyTpl(that.templatePath("react/public/fonts/material-symbols-outlined.woff2"), that.destinationPath(`client/public/fonts/material-symbols-outlined.woff2`));
52
+ that.fs.copyTpl(that.templatePath("react/public/fonts/material-symbols-rounded.woff2"), that.destinationPath(`client/public/fonts/material-symbols-rounded.woff2`));
53
+ that.fs.copyTpl(that.templatePath("react/public/fonts/material-symbols-sharp.woff2"), that.destinationPath(`client/public/fonts/material-symbols-sharp.woff2`));
49
54
  that.fs.copyTpl(that.templatePath("react/public/fonts/IBMPlexMono-Regular.ttf"), that.destinationPath(`client/public/fonts/IBMPlexMono-Regular.ttf`));
50
55
  that.fs.copyTpl(that.templatePath("react/public/fonts/InterVariable-Italic.woff2"), that.destinationPath(`client/public/fonts/InterVariable-Italic.woff2`));
51
56
  that.fs.copyTpl(that.templatePath("react/public/fonts/InterVariable.woff2"), that.destinationPath(`client/public/fonts/InterVariable.woff2`));
52
57
 
53
58
  that.fs.copyTpl(that.templatePath("react/src/App.css.ejs"), that.destinationPath(`client/src/App.css`), {});
54
- that.fs.copyTpl(that.templatePath("react/src/App.tsx.ejs"), that.destinationPath(`client/src/App.tsx`), { entities, to, pluralize });
59
+ that.fs.copyTpl(that.templatePath("react/src/App.tsx.ejs"), that.destinationPath(`client/src/App.tsx`), { entities: [...entities, AcRule], to, pluralize });
55
60
  that.fs.copyTpl(that.templatePath("react/src/i18n.js.ejs"), that.destinationPath(`client/src/i18n.js`), {
56
61
  supportedLngs: JSON.stringify(languages).replaceAll(`"`, `'`),
57
62
  fallbackLng: nativeLanguage
@@ -108,6 +113,7 @@ export async function createReactClient(that, parsedJDL) {
108
113
  that.fs.copyTpl(that.templatePath("react/src/components/formElements/UrlField.tsx.ejs"), that.destinationPath(`client/src/components/formElements/UrlField.tsx`), {});
109
114
  that.fs.copyTpl(that.templatePath("react/src/components/formElements/UuidField.tsx.ejs"), that.destinationPath(`client/src/components/formElements/UuidField.tsx`), {});
110
115
  that.fs.copyTpl(that.templatePath("react/src/components/HtmlViewer.tsx.ejs"), that.destinationPath(`client/src/components/HtmlViewer.tsx`), {});
116
+ that.fs.copyTpl(that.templatePath("react/src/components/Icon.tsx.ejs"), that.destinationPath(`client/src/components/Icon.tsx`), {});
111
117
  that.fs.copyTpl(that.templatePath("react/src/components/JsonPrint.tsx.ejs"), that.destinationPath(`client/src/components/JsonPrint.tsx`), {});
112
118
  that.fs.copyTpl(that.templatePath("react/src/components/LangSelect.tsx.ejs"), that.destinationPath(`client/src/components/LangSelect.tsx`), { to });
113
119
  that.fs.copyTpl(that.templatePath("react/src/components/LoginButton.tsx.ejs"), that.destinationPath(`client/src/components/LoginButton.tsx`), {});
@@ -140,12 +146,15 @@ export async function createReactClient(that, parsedJDL) {
140
146
  that.fs.copyTpl(that.templatePath("react/src/pages/errors/Err403.tsx.ejs"), that.destinationPath(`client/src/pages/errors/Err403.tsx`), {});
141
147
  that.fs.copyTpl(that.templatePath("react/src/pages/errors/Err404.tsx.ejs"), that.destinationPath(`client/src/pages/errors/Err404.tsx`), {});
142
148
 
149
+ that.fs.copyTpl(that.templatePath("react/src/pages/server-logs/LogViewer.tsx.ejs"), that.destinationPath(`client/src/pages/server-logs/LogViewer.tsx`), {});
150
+
143
151
  that.fs.copyTpl(that.templatePath("react/src/hooks/useAuthState.ts.ejs"), that.destinationPath(`client/src/hooks/useAuthState.ts`), {});
144
152
  that.fs.copyTpl(that.templatePath("react/src/hooks/useAutoShortcuts.tsx.ejs"), that.destinationPath(`client/src/hooks/useAutoShortcuts.tsx`), {});
145
153
  that.fs.copyTpl(that.templatePath("react/src/hooks/useRoles.ts.ejs"), that.destinationPath(`client/src/hooks/useRoles.ts`), {});
146
154
 
147
155
  that.fs.copyTpl(that.templatePath("react/src/shared/axiosInstance.ts.ejs"), that.destinationPath(`client/src/shared/axiosInstance.ts`));
148
156
  that.fs.copyTpl(that.templatePath("react/src/shared/axiosInterceptors.ts.ejs"), that.destinationPath(`client/src/shared/axiosInterceptors.ts`));
157
+ that.fs.copyTpl(that.templatePath("react/src/shared/entitiesIcons.tsx.ejs"), that.destinationPath(`client/src/shared/entitiesIcons.tsx`), { entities });
149
158
  that.fs.copyTpl(that.templatePath("react/src/shared/model/ac-rule.model.ts.ejs"), that.destinationPath(`client/src/shared/model/ac-rule.model.ts`));
150
159
 
151
160
  for (const entity of entities) {
@@ -166,13 +175,17 @@ export async function createReactClient(that, parsedJDL) {
166
175
  that.fs.copyTpl(that.templatePath("react/src/shared/model/enumerations/enumeration.model.ts.ejs"), that.destinationPath(`client/src/shared/model/enumerations/${to.slug(enumeration.name)}.model.ts`), { enumeration });
167
176
  }
168
177
 
169
- that.fs.copyTpl(that.templatePath("react/src/pages/entities/AcRuleList.tsx.ejs"), that.destinationPath(`client/src/pages/entities/AcRuleList.tsx`));
170
- that.fs.copyTpl(that.templatePath("react/src/pages/entities/AcRuleView.tsx.ejs"), that.destinationPath(`client/src/pages/entities/AcRuleView.tsx`));
171
- that.fs.copyTpl(that.templatePath("react/src/pages/entities/AcRuleEdit.tsx.ejs"), that.destinationPath(`client/src/pages/entities/AcRuleEdit.tsx`));
172
- that.fs.copyTpl(that.templatePath("react/src/components/entities/AcRuleForm.tsx.ejs"), that.destinationPath(`client/src/components/entities/AcRuleForm.tsx`));
173
- that.fs.copyTpl(that.templatePath("react/src/components/entities/AcRuleDeleteButton.tsx.ejs"), that.destinationPath(`client/src/components/entities/AcRuleDeleteButton.tsx`));
178
+ that.fs.copyTpl(that.templatePath("react/src/pages/audit/Audits.tsx.ejs"), that.destinationPath(`client/src/pages/audit/Audits.tsx`));
179
+ that.fs.copyTpl(that.templatePath("react/src/pages/audit/AuditHistory.tsx.ejs"), that.destinationPath(`client/src/pages/audit/AuditHistory.tsx`));
180
+ that.fs.copyTpl(that.templatePath("react/src/pages/audit/AuditList.tsx.ejs"), that.destinationPath(`client/src/pages/audit/AuditList.tsx`));
181
+ that.fs.copyTpl(that.templatePath("react/src/pages/audit/AuditStatistics.tsx.ejs"), that.destinationPath(`client/src/pages/audit/AuditStatistics.tsx`));
182
+ that.fs.copyTpl(that.templatePath("react/src/pages/audit/AuditUserActivity.tsx.ejs"), that.destinationPath(`client/src/pages/audit/AuditUserActivity.tsx`));
183
+ that.fs.copyTpl(that.templatePath("react/src/pages/audit/AuditView.tsx.ejs"), that.destinationPath(`client/src/pages/audit/AuditView.tsx`));
174
184
 
175
- for (const entity of entities) {
185
+ for (const entity of [AcRule, ...entities]) {
186
+ const hasSoftDelete = entity.annotations?.some(
187
+ ann => ann.optionName === 'softDelete' && ann.type === 'UNARY'
188
+ );
176
189
  that.fs.copyTpl(
177
190
  that.templatePath("react/src/pages/entities/EntityList.tsx.ejs"),
178
191
  that.destinationPath(`client/src/pages/entities/${entity.name}List.tsx`),
@@ -187,6 +200,22 @@ export async function createReactClient(that, parsedJDL) {
187
200
  relatedEntities: getModelRelatedEntities(entity, relationships),
188
201
  searchEngine,
189
202
  });
203
+ if (hasSoftDelete) {
204
+ that.fs.copyTpl(
205
+ that.templatePath("react/src/pages/entities/EntityTrash.tsx.ejs"),
206
+ that.destinationPath(`client/src/pages/entities/${entity.name}Trash.tsx`),
207
+ {
208
+ entity,
209
+ to,
210
+ pluralize,
211
+ columns: entity.body.map(c => to.snake(c.name)),
212
+ durationColumns: entity.body.filter(c => c.type === 'Duration').map(c => to.snake(c.name)),
213
+ fileColumns: entity.body.filter(c => c.type === 'Blob' || c.type === 'AnyBlob' || c.type === 'ImageBlob').map(c => to.snake(c.name)),
214
+ foreignIds: getModelForeignIds(entity, relationships),
215
+ relatedEntities: getModelRelatedEntities(entity, relationships),
216
+ searchEngine,
217
+ });
218
+ }
190
219
  that.fs.copyTpl(
191
220
  that.templatePath("react/src/pages/entities/EntityView.tsx.ejs"),
192
221
  that.destinationPath(`client/src/pages/entities/${entity.name}View.tsx`),
@@ -2,9 +2,12 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
5
6
  <link rel="icon" type="image/svg+xml" href="/icon.svg">
6
7
  <link rel="icon" type="image/png" href="/icon.png">
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <link rel="preload" href="/fonts/material-symbols-outlined.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
9
+ <link rel="preload" href="/fonts/material-symbols-rounded.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
10
+ <link rel="preload" href="/fonts/material-symbols-sharp.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
8
11
  <title><%= appName %></title>
9
12
  <script>
10
13
  if (!localStorage.getItem('dark-mode')) {