easy-admin-rails 0.2.4 → 0.2.6

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/builds/easy_admin.base.js +100 -27
  3. data/app/assets/builds/easy_admin.base.js.map +4 -4
  4. data/app/assets/builds/easy_admin.css +59 -0
  5. data/app/components/easy_admin/navbar_component.rb +19 -4
  6. data/app/components/easy_admin/permissions/user_role_assignment_component.rb +43 -16
  7. data/app/components/easy_admin/profile/change_password_modal_component.rb +75 -0
  8. data/app/components/easy_admin/profile/profile_tab_component.rb +92 -0
  9. data/app/components/easy_admin/profile/security_tab_component.rb +53 -0
  10. data/app/components/easy_admin/profile/settings_component.rb +103 -0
  11. data/app/components/easy_admin/two_factor/backup_codes_component.rb +118 -0
  12. data/app/components/easy_admin/two_factor/setup_component.rb +124 -0
  13. data/app/components/easy_admin/two_factor/status_component.rb +92 -0
  14. data/app/controllers/concerns/easy_admin/two_factor.rb +110 -0
  15. data/app/controllers/easy_admin/application_controller.rb +10 -0
  16. data/app/controllers/easy_admin/profile_controller.rb +25 -0
  17. data/app/controllers/easy_admin/sessions_controller.rb +107 -1
  18. data/app/javascript/easy_admin/controllers/collapsible_filters_controller.js +14 -7
  19. data/app/javascript/easy_admin/controllers/permission_toggle_controller.js +2 -33
  20. data/app/javascript/easy_admin/controllers/vertical_tabs_controller.js +112 -0
  21. data/app/javascript/easy_admin/controllers.js +3 -1
  22. data/app/models/easy_admin/admin_user.rb +3 -0
  23. data/app/views/easy_admin/profile/backup_codes_regenerated.turbo_stream.erb +12 -0
  24. data/app/views/easy_admin/profile/change_password.html.erb +24 -0
  25. data/app/views/easy_admin/profile/index.html.erb +1 -0
  26. data/app/views/easy_admin/profile/password_error.turbo_stream.erb +6 -0
  27. data/app/views/easy_admin/profile/password_invalid_current.turbo_stream.erb +6 -0
  28. data/app/views/easy_admin/profile/password_updated.turbo_stream.erb +9 -0
  29. data/app/views/easy_admin/profile/two_factor_backup_codes.html.erb +24 -0
  30. data/app/views/easy_admin/profile/two_factor_enabled.turbo_stream.erb +12 -0
  31. data/app/views/easy_admin/profile/two_factor_invalid_code.turbo_stream.erb +6 -0
  32. data/app/views/easy_admin/profile/two_factor_not_enabled.turbo_stream.erb +6 -0
  33. data/app/views/easy_admin/profile/two_factor_setup.html.erb +24 -0
  34. data/app/views/easy_admin/profile/two_factor_unavailable.turbo_stream.erb +6 -0
  35. data/app/views/easy_admin/sessions/two_factor_verification.html.erb +48 -0
  36. data/app/views/easy_admin/sessions/verify_2fa_error.turbo_stream.erb +13 -0
  37. data/config/routes.rb +20 -1
  38. data/lib/easy-admin-rails.rb +1 -0
  39. data/lib/easy_admin/two_factor_authentication.rb +156 -0
  40. data/lib/easy_admin/version.rb +1 -1
  41. data/lib/generators/easy_admin/two_factor/templates/README +29 -0
  42. data/lib/generators/easy_admin/two_factor/templates/migration.rb +10 -0
  43. data/lib/generators/easy_admin/two_factor/two_factor_generator.rb +22 -0
  44. metadata +30 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 200c3fe21e8f5566d71ebdb3a33e3323f13a306b854d3b40eb1b0ae49967b7d5
4
- data.tar.gz: be99b25d0ae753a87e3d3c8a1c660d4ee03174080f5aa80139c52650ea538353
3
+ metadata.gz: 5e90957dc32728330bda3441bc02e107bfc373904b190cce9e355fa4c2072a1e
4
+ data.tar.gz: c1c820f50d74a7894ba43ba9aa8d90925fdaa747466673b2145eeee52e4546f4
5
5
  SHA512:
6
- metadata.gz: eb4f2033bc990a07e5b92a93823637841b8de9b1c7bbfc7341ef626efbb483235aafbae6c0ebae6aec545f7172a41177ef6dd064d8ead0355b23f83663e77ff5
7
- data.tar.gz: 158d1b41f51cd695ad7c034eae47e847a910a9eacb70c7f51a8260067f01d6732cb56547ccce545f01547b5dc4b3b7855bebc7462980ee12800a3a35abdfd9b7
6
+ metadata.gz: 40cdbf9df46b9982287bcd510c01b17f198e7b74459c68736328315a012dbb4b708b915f58c469f98da8d0f40eba96d55de3fdd8fd7393c7256dbb04f2a72d72
7
+ data.tar.gz: b5b047fe2779423f9d64d88ff8118f538496253dbfbf2cc38969a813ec2fe2a6e81c9d9822b9bbabc66b6bef9a5d50cf3608d2da1bbac2565bb40e2135892c3f
@@ -39362,10 +39362,13 @@ ${m = t3 ? m : H(m, ",")}
39362
39362
  var collapsible_filters_controller_default = class extends Controller {
39363
39363
  static targets = ["content", "icon"];
39364
39364
  static values = {
39365
- expanded: { type: Boolean, default: true }
39365
+ expanded: { type: Boolean, default: true },
39366
+ persistState: { type: Boolean, default: true }
39366
39367
  };
39367
39368
  connect() {
39368
- this.loadState();
39369
+ if (this.persistStateValue) {
39370
+ this.loadState();
39371
+ }
39369
39372
  if (this.expandedValue) {
39370
39373
  this.expand(false);
39371
39374
  } else {
@@ -39393,7 +39396,9 @@ ${m = t3 ? m : H(m, ",")}
39393
39396
  this.contentTarget.classList.add("opacity-100");
39394
39397
  }
39395
39398
  this.updateIconRotation();
39396
- this.saveState(true);
39399
+ if (this.persistStateValue) {
39400
+ this.saveState(true);
39401
+ }
39397
39402
  }
39398
39403
  collapse(animate = true) {
39399
39404
  this.expandedValue = false;
@@ -39409,7 +39414,9 @@ ${m = t3 ? m : H(m, ",")}
39409
39414
  this.contentTarget.classList.add("opacity-0");
39410
39415
  }
39411
39416
  this.updateIconRotation();
39412
- this.saveState(false);
39417
+ if (this.persistStateValue) {
39418
+ this.saveState(false);
39419
+ }
39413
39420
  }
39414
39421
  saveState(expanded) {
39415
39422
  const key = `filters_expanded_${window.location.pathname}`;
@@ -41124,25 +41131,7 @@ ${m = t3 ? m : H(m, ",")}
41124
41131
  userId: Number
41125
41132
  };
41126
41133
  connect() {
41127
- console.log("\u{1F3AF} PermissionToggleController connected");
41128
- console.log("\u{1F3AF} User ID:", this.userIdValue);
41129
- const cards = this.permissionCardTargets;
41130
- console.log("\u{1F3AF} Found", cards.length, "permission cards");
41131
- cards.forEach((card, index2) => {
41132
- console.log(`\u{1F3AF} Card ${index2}:`, {
41133
- permission: card.dataset.permissionName,
41134
- granted: card.dataset.granted,
41135
- resourceType: card.dataset.resourceType
41136
- });
41137
- });
41138
41134
  const hiddenInputs = this.element.querySelectorAll('input[type="hidden"][data-permission-toggle-target="hiddenInput"]');
41139
- console.log("\u{1F3AF} Found", hiddenInputs.length, "hidden inputs");
41140
- hiddenInputs.forEach((input, index2) => {
41141
- console.log(`\u{1F3AF} Hidden input ${index2}:`, {
41142
- name: input.name,
41143
- value: input.value
41144
- });
41145
- });
41146
41135
  }
41147
41136
  togglePermission(event) {
41148
41137
  event.preventDefault();
@@ -41150,11 +41139,6 @@ ${m = t3 ? m : H(m, ",")}
41150
41139
  const permissionName = card.dataset.permissionName;
41151
41140
  const currentlyGranted = card.dataset.granted === "true";
41152
41141
  const newGrantedState = !currentlyGranted;
41153
- console.log("\u{1F3AF} Toggling permission:", {
41154
- permission: permissionName,
41155
- wasGranted: currentlyGranted,
41156
- nowGranted: newGrantedState
41157
- });
41158
41142
  this.updateCardUI(card, newGrantedState);
41159
41143
  this.updateHiddenInput(card, newGrantedState);
41160
41144
  this.showNotification(
@@ -41164,6 +41148,7 @@ ${m = t3 ? m : H(m, ",")}
41164
41148
  }
41165
41149
  toggleAllForResource(event) {
41166
41150
  event.preventDefault();
41151
+ event.stopPropagation();
41167
41152
  const resourceType = event.currentTarget.dataset.resourceType;
41168
41153
  const resourceCards = this.permissionCardTargets.filter(
41169
41154
  (card) => card.dataset.resourceType === resourceType
@@ -41288,6 +41273,93 @@ ${m = t3 ? m : H(m, ",")}
41288
41273
  }
41289
41274
  };
41290
41275
 
41276
+ // app/javascript/easy_admin/controllers/vertical_tabs_controller.js
41277
+ var vertical_tabs_controller_default = class extends Controller {
41278
+ static targets = ["tab", "content"];
41279
+ connect() {
41280
+ const urlParams = new URLSearchParams(window.location.search);
41281
+ const tabFromUrl = urlParams.get("tab");
41282
+ if (tabFromUrl && this.isValidTab(tabFromUrl)) {
41283
+ this.activateTab(tabFromUrl);
41284
+ } else {
41285
+ const firstTab = this.tabTargets[0];
41286
+ if (firstTab) {
41287
+ this.activateTab(firstTab.dataset.tabId);
41288
+ }
41289
+ }
41290
+ this.handlePopState = this.handlePopState.bind(this);
41291
+ window.addEventListener("popstate", this.handlePopState);
41292
+ }
41293
+ disconnect() {
41294
+ window.removeEventListener("popstate", this.handlePopState);
41295
+ }
41296
+ switchTab(event) {
41297
+ event.preventDefault();
41298
+ const tabId = event.currentTarget.dataset.tabId;
41299
+ this.activateTab(tabId);
41300
+ }
41301
+ activateTab(tabId) {
41302
+ this.tabTargets.forEach((tab) => {
41303
+ const isActive = tab.dataset.tabId === tabId;
41304
+ if (isActive) {
41305
+ tab.classList.remove("text-gray-700", "hover:bg-gray-100", "hover:text-gray-900");
41306
+ tab.classList.add("bg-blue-50", "text-blue-700", "border-blue-200");
41307
+ } else {
41308
+ tab.classList.remove("bg-blue-50", "text-blue-700", "border-blue-200");
41309
+ tab.classList.add("text-gray-700", "hover:bg-gray-100", "hover:text-gray-900");
41310
+ }
41311
+ });
41312
+ this.contentTargets.forEach((content) => {
41313
+ const isActive = content.dataset.tabId === tabId;
41314
+ if (isActive) {
41315
+ content.classList.remove("hidden");
41316
+ } else {
41317
+ content.classList.add("hidden");
41318
+ }
41319
+ });
41320
+ if (history.replaceState) {
41321
+ const url = new URL(window.location);
41322
+ url.searchParams.set("tab", tabId);
41323
+ history.replaceState(null, "", url);
41324
+ }
41325
+ }
41326
+ isValidTab(tabId) {
41327
+ return this.tabTargets.some((tab) => tab.dataset.tabId === tabId);
41328
+ }
41329
+ handlePopState() {
41330
+ const urlParams = new URLSearchParams(window.location.search);
41331
+ const tabFromUrl = urlParams.get("tab");
41332
+ if (tabFromUrl && this.isValidTab(tabFromUrl)) {
41333
+ this.activateTabSilently(tabFromUrl);
41334
+ } else {
41335
+ const firstTab = this.tabTargets[0];
41336
+ if (firstTab) {
41337
+ this.activateTabSilently(firstTab.dataset.tabId);
41338
+ }
41339
+ }
41340
+ }
41341
+ activateTabSilently(tabId) {
41342
+ this.tabTargets.forEach((tab) => {
41343
+ const isActive = tab.dataset.tabId === tabId;
41344
+ if (isActive) {
41345
+ tab.classList.remove("text-gray-700", "hover:bg-gray-100", "hover:text-gray-900");
41346
+ tab.classList.add("bg-blue-50", "text-blue-700", "border-blue-200");
41347
+ } else {
41348
+ tab.classList.remove("bg-blue-50", "text-blue-700", "border-blue-200");
41349
+ tab.classList.add("text-gray-700", "hover:bg-gray-100", "hover:text-gray-900");
41350
+ }
41351
+ });
41352
+ this.contentTargets.forEach((content) => {
41353
+ const isActive = content.dataset.tabId === tabId;
41354
+ if (isActive) {
41355
+ content.classList.remove("hidden");
41356
+ } else {
41357
+ content.classList.add("hidden");
41358
+ }
41359
+ });
41360
+ }
41361
+ };
41362
+
41291
41363
  // app/javascript/easy_admin/controllers.js
41292
41364
  application.register("sidebar", sidebar_controller_default);
41293
41365
  application.register("sidebar-nav", sidebar_nav_controller_default);
@@ -41317,6 +41389,7 @@ ${m = t3 ? m : H(m, ",")}
41317
41389
  application.register("version-revert", version_revert_controller_default);
41318
41390
  application.register("role-preview", role_preview_controller_default);
41319
41391
  application.register("permission-toggle", permission_toggle_controller_default);
41392
+ application.register("vertical-tabs", vertical_tabs_controller_default);
41320
41393
 
41321
41394
  // node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js
41322
41395
  var turbo_es2017_esm_exports = {};