lesli_admin 1.0.2 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcfea6ed96a81aab1ecb84e54a06f0d6aa14c9221074accd041cadebc7f6b788
4
- data.tar.gz: '08f33b0478d7038a53e852824bee01326cb88522293db5dddf827a7f6028b0f7'
3
+ metadata.gz: 4be526cc5d4c0ebe88f74ec2046f9910cba16c61199ad1691901a30c2566c878
4
+ data.tar.gz: 68889417b39b041632c52da972e946311115b676e0008211c0b68e7b7cb4c0d7
5
5
  SHA512:
6
- metadata.gz: 0fda832059c70e6cbe03ef80a1e044db64ca42528af8f771d1e9381b35844cb2aa34ef28cbcb902e84c93c5261787bee2f9a352ea351af9f2d5ef8aa5e347060
7
- data.tar.gz: 803510d55a87e01ac38958fcb7407883e72179fcaf0556b41c287f2416fa8f6ef815e5f40598b7bec3d35155f8f8e5902415353d77812aafe0a9236eb2353960
6
+ metadata.gz: a15c772978ba4fd4ed72c7f94790ce50c849314f89b9d80679ccb999f55c42a43ee3c3d72d55179652b1e5f39f77cb4cfc05819342459690f6d9e2d93f8dbd00
7
+ data.tar.gz: 27da84af4ac7c6b58fe44115aa750c14c90102d995e9caa1a4c7d9c818f5251451779557e1bd978c0c7161fc0e8dd64a0f598cfd6d6e0ae70b2aaf180bc0d28a
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  require "bundler/setup"
2
2
 
3
- load "rails/tasks/statistics.rake"
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+
5
+ load "rails/tasks/engine.rake"
4
6
 
5
7
  require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-leading:initial}}}@layer theme{:root,:host{--color-red-100:oklch(93.6% .032 17.717);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-900:oklch(20.8% .042 265.755);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-lg:.5rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer components{.module-engine-card .partial-engine-spec>div{margin-bottom:calc(var(--spacing) * 4);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-slate-200);padding-bottom:calc(var(--spacing) * 4)}.module-engine-card .partial-engine-spec h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-slate-900)}.module-engine-card .partial-engine-spec p{margin-top:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);color:var(--color-slate-600)}.module-engine-card .partial-engine-spec ul{column-gap:calc(var(--spacing) * 4);row-gap:calc(var(--spacing) * 2);flex-wrap:wrap;display:flex}.module-engine-card .partial-engine-spec li{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--color-slate-600);margin:0}.module-engine-card .partial-engine-spec li:last-child,.module-engine-card .partial-engine-spec .material-symbols{display:none}}@layer utilities{.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-1{margin-left:var(--spacing)}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.w-fit{width:fit-content}.min-w-0{min-width:0}.flex-1{flex:1}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-5{gap:calc(var(--spacing) * 5)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-6{column-gap:calc(var(--spacing) * 6)}.gap-y-5{row-gap:calc(var(--spacing) * 5)}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-slate-200{border-color:var(--color-slate-200)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-emerald-600{background-color:var(--color-emerald-600)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-600{background-color:var(--color-red-600)}.bg-slate-100{background-color:var(--color-slate-100)}.bg-white{background-color:var(--color-white)}.p-5{padding:calc(var(--spacing) * 5)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.break-all{word-break:break-all}.text-emerald-700{color:var(--color-emerald-700)}.text-red-700{color:var(--color-red-700)}.text-slate-600{color:var(--color-slate-600)}.text-slate-700{color:var(--color-slate-700)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:bg-emerald-700:hover{background-color:var(--color-emerald-700)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-emerald-500\/30:focus-visible{--tw-ring-color:#00bb7f4d}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-emerald-500\/30:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-emerald-500) 30%, transparent)}}.focus-visible\:ring-red-500\/30:focus-visible{--tw-ring-color:#fb2c364d}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-red-500\/30:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-red-500) 30%, transparent)}}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:p-6{padding:calc(var(--spacing) * 6)}}@media (min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media (min-width:80rem){.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-leading{syntax:"*";inherits:false}
@@ -25,7 +25,7 @@ module LesliAdmin
25
25
  @account_currency = Account::Currency.new(account_currency_params)
26
26
 
27
27
  if @account_currency.save
28
- redirect_to @account_currency, notice: "Currency was successfully created."
28
+ redirect_to @account_currency, notice: "Currency was successfully created.", allow_other_host: false
29
29
  else
30
30
  render :new, status: :unprocessable_entity
31
31
  end
@@ -34,7 +34,7 @@ module LesliAdmin
34
34
  # PATCH/PUT /account/currencies/1
35
35
  def update
36
36
  if @account_currency.update(account_currency_params)
37
- redirect_to @account_currency, notice: "Currency was successfully updated.", status: :see_other
37
+ redirect_to @account_currency, notice: "Currency was successfully updated.", status: :see_other, allow_other_host: false
38
38
  else
39
39
  render :edit, status: :unprocessable_entity
40
40
  end
@@ -25,7 +25,7 @@ module LesliAdmin
25
25
  @account_detail = Account::Detail.new(account_detail_params)
26
26
 
27
27
  if @account_detail.save
28
- redirect_to @account_detail, notice: "Detail was successfully created."
28
+ redirect_to @account_detail, notice: "Detail was successfully created.", allow_other_host: false
29
29
  else
30
30
  render :new, status: :unprocessable_entity
31
31
  end
@@ -34,7 +34,7 @@ module LesliAdmin
34
34
  # PATCH/PUT /account/details/1
35
35
  def update
36
36
  if @account_detail.update(account_detail_params)
37
- redirect_to @account_detail, notice: "Detail was successfully updated.", status: :see_other
37
+ redirect_to @account_detail, notice: "Detail was successfully updated.", status: :see_other, allow_other_host: false
38
38
  else
39
39
  render :edit, status: :unprocessable_entity
40
40
  end
@@ -25,7 +25,7 @@ module LesliAdmin
25
25
  @account_location = Account::Location.new(account_location_params)
26
26
 
27
27
  if @account_location.save
28
- redirect_to @account_location, notice: "Location was successfully created."
28
+ redirect_to @account_location, notice: "Location was successfully created.", allow_other_host: false
29
29
  else
30
30
  render :new, status: :unprocessable_entity
31
31
  end
@@ -34,7 +34,7 @@ module LesliAdmin
34
34
  # PATCH/PUT /account/locations/1
35
35
  def update
36
36
  if @account_location.update(account_location_params)
37
- redirect_to @account_location, notice: "Location was successfully updated.", status: :see_other
37
+ redirect_to @account_location, notice: "Location was successfully updated.", status: :see_other, allow_other_host: false
38
38
  else
39
39
  render :edit, status: :unprocessable_entity
40
40
  end
@@ -25,7 +25,7 @@ module LesliAdmin
25
25
  @account_setting = Account::Setting.new(account_setting_params)
26
26
 
27
27
  if @account_setting.save
28
- redirect_to @account_setting, notice: "Setting was successfully created."
28
+ redirect_to @account_setting, notice: "Setting was successfully created.", allow_other_host: false
29
29
  else
30
30
  render :new, status: :unprocessable_entity
31
31
  end
@@ -34,7 +34,7 @@ module LesliAdmin
34
34
  # PATCH/PUT /account/settings/1
35
35
  def update
36
36
  if @account_setting.update(account_setting_params)
37
- redirect_to @account_setting, notice: "Setting was successfully updated.", status: :see_other
37
+ redirect_to @account_setting, notice: "Setting was successfully updated.", status: :see_other, allow_other_host: false
38
38
  else
39
39
  render :edit, status: :unprocessable_entity
40
40
  end
@@ -1,8 +1 @@
1
- <div class="box has-text-centered py-6">
2
- <p class="is-title is-size-3 mb-2">
3
- <b><%= LesliSystem.engines.size %></b>
4
- </p>
5
- <p class="is-title is-size-4">
6
- Installed engines
7
- </p>
8
- </div>
1
+ <%= render(LesliView::Widgets::Count.new('Installed engines', LesliSystem.engines.size)) %>
@@ -1,61 +1,71 @@
1
- <%
1
+ <%
2
2
  sections = {
3
3
  "Instance Info" => {
4
4
  demo: Lesli.config.demo,
5
5
  instance: Lesli.config.instance
6
6
  },
7
7
  "Company Info" => Lesli.config.company,
8
- "Available Locales" => Lesli.config.locales,
8
+ "Available Locales" => Lesli.config.babel[:locales],
9
9
  "Datetime Settings" => Lesli.config.datetime,
10
10
  "Security Settings" => Lesli.config.security,
11
11
  "Theme" => Lesli.config.theme,
12
12
  "Layout" => Lesli.config.layout,
13
13
  "Mailer" => Lesli.config.mailer,
14
14
  "Paths" => {
15
- path_after_login: Lesli.config.path_after_login
15
+ path_after_login: Lesli.config.shield[:path_after_login]
16
16
  }
17
- }
17
+ }
18
+
19
+ grid_classes = {
20
+ "Instance Info" => "sm:grid-cols-2 lg:grid-cols-4",
21
+ "Datetime Settings" => "sm:grid-cols-2",
22
+ "Security Settings" => "sm:grid-cols-2 lg:grid-cols-4",
23
+ "Theme" => "sm:grid-cols-2 lg:grid-cols-3"
24
+ }
18
25
  %>
19
- <section class="section pt-0">
20
- <h4 class="title is-size-4 mb-4">Lesli Configuration</h4>
21
26
 
22
- <% sections.each do |title, config| %>
23
- <div class="box">
24
- <h5 class="subtitle is-size-6 has-text-weight-semibold mb-4"><%= title %></h5>
25
- <div class="columns is-multiline is-mobile">
26
- <%
27
- grid = title.underscore
28
- grid = "is-one-quarter" if title.underscore == "instance info"
29
- grid = "is-half" if title.underscore == "datetime settings"
30
- grid = "is-one-quarter" if title.underscore == "security settings"
31
- grid = "is-one-third" if title.underscore == "theme"
27
+ <section aria-labelledby="lesli-configuration-title">
28
+ <h4
29
+ id="lesli-configuration-title"
30
+ class="mb-5 text-xl font-semibold tracking-tight text-slate-900">
31
+ Lesli Configuration
32
+ </h4>
33
+
34
+ <div class="space-y-5">
35
+ <% sections.each do |title, config| %>
36
+ <article class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm sm:p-6">
37
+ <h5 class="mb-4 text-base font-semibold text-slate-900"><%= title %></h5>
32
38
 
33
- %>
39
+ <dl class="grid grid-cols-1 gap-x-6 gap-y-5 <%= grid_classes.fetch(title, "sm:grid-cols-2 lg:grid-cols-4") %>">
34
40
  <% config.each do |key, value| %>
35
- <div class="column <%= grid %>">
36
- <p class="has-text-weight-semibold"><%= key.to_s.humanize %></p>
37
- <div>
41
+ <div class="min-w-0">
42
+ <dt class="text-sm font-medium text-slate-600"><%= key.to_s.humanize %></dt>
43
+ <dd class="mt-2 text-sm text-slate-900">
38
44
  <% if value.is_a?(Hash) %>
39
- <ul class="pl-4">
40
- <% value.each do |key, value| %>
41
- <li>
42
- <strong><%= key.to_s.humanize %>:</strong>
43
- <code><%= value %></code>
45
+ <ul class="space-y-2 border-l-2 border-slate-200 pl-3">
46
+ <% value.each do |nested_key, nested_value| %>
47
+ <li class="min-w-0">
48
+ <span class="font-medium text-slate-700"><%= nested_key.to_s.humanize %>:</span>
49
+ <code class="ml-1 break-all rounded bg-slate-100 px-1.5 py-0.5 text-xs text-slate-700"><%= nested_value %></code>
44
50
  </li>
45
51
  <% end %>
46
52
  </ul>
47
-
48
53
  <% elsif value == true %>
49
- <span class="tag is-success has-text-white">Enabled</span>
54
+ <span class="inline-flex items-center rounded-full bg-emerald-100 px-2.5 py-1 text-xs font-semibold text-emerald-700">
55
+ Enabled
56
+ </span>
50
57
  <% elsif value == false %>
51
- <span class="tag is-danger has-text-white">Disabled</span>
58
+ <span class="inline-flex items-center rounded-full bg-red-100 px-2.5 py-1 text-xs font-semibold text-red-700">
59
+ Disabled
60
+ </span>
52
61
  <% else %>
53
- <code class="is-size-7"><%= value.to_s %></code>
62
+ <code class="break-all rounded bg-slate-100 px-1.5 py-1 text-xs text-slate-700"><%= value.to_s %></code>
54
63
  <% end %>
55
- </div>
64
+ </dd>
56
65
  </div>
57
66
  <% end %>
58
- </div>
59
- </div>
60
- <% end %>
67
+ </dl>
68
+ </article>
69
+ <% end %>
70
+ </div>
61
71
  </section>
@@ -20,42 +20,38 @@
20
20
  }
21
21
  }
22
22
  </script>
23
- <style>
24
- .fixed-grid .partial-engine-spec ul {
25
- display: flex;
26
- }
27
- .fixed-grid .partial-engine-spec ul li {
28
- margin: 0 1rem 0 0;
29
- font-size: 13px;
30
- }
31
- .fixed-grid .partial-engine-spec ul li:last-child {
32
- display: none;
33
- }
34
- .fixed-grid .partial-engine-spec .material-symbols {
35
- font-size: 0px;
36
- }
37
- </style>
23
+
38
24
  <%
39
- @lesli_engines = LesliSystem.engines.map do |engine, engine_info|
40
- engine_info[:summary] = engine_info[:summary]&.sub("for the Lesli Framework","")&.sub("for The Lesli Framework","")
41
- engine_info
42
- end
25
+ lesli_engines = LesliSystem.engines.values.map do |engine_info|
26
+ summary = engine_info[:summary]
27
+ &.sub("for the Lesli Framework", "")
28
+ &.sub("for The Lesli Framework", "")
29
+
30
+ engine_info.merge(summary: summary)
31
+ end
43
32
  %>
44
33
 
45
- <div class="fixed-grid">
46
- <div class="grid" x-data="engineManager()">
47
- <% @lesli_engines.each do |engine| %>
34
+ <section
35
+ class="grid grid-cols-1 gap-5 xl:grid-cols-2"
36
+ aria-label="Modules"
37
+ x-data="engineManager()">
38
+ <% lesli_engines.each do |engine| %>
48
39
  <% next if engine[:name] == "Root" %>
49
- <div class="cell">
50
- <div class="box">
40
+
41
+ <% engine_key = engine[:path].delete("/") %>
42
+
43
+ <article class="module-engine-card flex min-w-0 flex-col rounded-2xl border border-slate-200 bg-white p-5 shadow-sm sm:p-6">
44
+ <div class="min-w-0 flex-1">
51
45
  <%= render(LesliView::Partials::EngineSpec.new(engine)) %>
52
- <button
53
- @click="toggleEngine('<%= engine[:path].gsub("/","") %>')"
54
- :class="data.engines.includes('<%= engine[:path].gsub("/","") %>') ? 'button is-small is-info' : 'button is-small is-danger has-text-white'"
55
- x-text="data.engines.includes('<%= engine[:path].gsub("/","") %>') ? 'Activar módulo' : 'Desactivar módulo'">
56
- </button>
57
46
  </div>
58
- </div>
47
+
48
+ <button
49
+ type="button"
50
+ class="mt-5 inline-flex w-fit items-center justify-center rounded-lg px-3 py-2 text-sm font-semibold text-white shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
51
+ @click="toggleEngine(<%= engine_key.to_json %>)"
52
+ :class="data.engines.includes(<%= engine_key.to_json %>) ? 'bg-emerald-600 hover:bg-emerald-700 focus-visible:ring-emerald-500/30' : 'bg-red-600 hover:bg-red-700 focus-visible:ring-red-500/30'"
53
+ x-text="data.engines.includes(<%= engine_key.to_json %>) ? 'Activar módulo' : 'Desactivar módulo'">
54
+ </button>
55
+ </article>
59
56
  <% end %>
60
- </div>
61
- </div>
57
+ </section>
data/db/seeds.rb CHANGED
@@ -31,7 +31,7 @@ Building a better future, one line of code at a time.
31
31
  =end
32
32
 
33
33
 
34
- L2.msg("LesliAdmin", "Version: #{LesliAdmin::VERSION}", "Build: #{LesliAdmin::BUILD}")
34
+ Termline.info("Loading seeds for: LesliAdmin #{LesliAdmin::VERSION} (#{LesliAdmin::BUILD})")
35
35
 
36
36
  if Rails.env.development? || Lesli.config.demo
37
37
  #load(LesliAdmin::Engine.root.join("db", "seed", "#{ Rails.env.downcase }.rb"))
@@ -1,4 +1,4 @@
1
1
  module LesliAdmin
2
- VERSION = "1.0.2"
3
- BUILD = "1771710537"
2
+ VERSION = "1.1.1"
3
+ BUILD = "1791607001"
4
4
  end
data/readme.md CHANGED
@@ -1,14 +1,15 @@
1
1
  <div align="center">
2
- <img width="100" alt="LesliAdmin logo" src="./app/assets/images/lesli_admin/admin-logo.svg" />
3
- <h3 align="center">Administration area for the Lesli Framework.</h3>
2
+ <h1 align="center">
3
+ <img width="100" alt="LesliAdmin" src="./app/assets/images/lesli_admin/admin-logo.svg" />
4
+ </h1>
5
+ <h3 align="center">Account and application administration for the Lesli Framework.</h3>
4
6
  </div>
5
7
 
6
8
  <br />
7
- <hr/>
8
9
 
9
10
  <div align="center">
10
- <a target="_blank" href="https://github.com/LesliTech/LesliAdmin/actions">
11
- <img alt="Tests passing" src="https://img.shields.io/badge/Tests-passing-green?style=for-the-badge&logo=github">
11
+ <a target="_blank" href="https://github.com/LesliTech/LesliAdmin/actions/workflows/lesli-ci.yaml">
12
+ <img alt="LesliAdmin test status" src="https://img.shields.io/github/actions/workflow/status/LesliTech/LesliAdmin/lesli-ci.yaml?branch=master&style=for-the-badge&logo=github&label=tests">
12
13
  </a>
13
14
  <a target="_blank" href="https://rubygems.org/gems/lesli_admin">
14
15
  <img alt="Gem Version" src="https://img.shields.io/gem/v/lesli_admin?style=for-the-badge&logo=ruby">
@@ -16,83 +17,156 @@
16
17
  <a target="_blank" href="https://codecov.io/github/LesliTech/LesliAdmin">
17
18
  <img alt="Codecov" src="https://img.shields.io/codecov/c/github/LesliTech/LesliAdmin?style=for-the-badge&logo=codecov">
18
19
  </a>
20
+ <a target="_blank" href="https://sonarcloud.io/project/overview?id=LesliTech_LesliAdmin">
21
+ <img alt="Sonar Quality Gate" src="https://img.shields.io/sonar/quality_gate/LesliTech_LesliAdmin?server=https%3A%2F%2Fsonarcloud.io&style=for-the-badge&logo=sonarqubecloud&label=Quality">
22
+ </a>
19
23
  </div>
20
24
 
21
- <hr/>
22
25
  <br />
23
26
 
24
27
  <div align="center">
25
28
  <img
26
29
  style="width:100%;max-width:800px;border-radius:6px;"
27
- alt="Lesli screenshot" src="./docs/images/screenshot.png" />
30
+ alt="LesliAdmin account administration"
31
+ src="./docs/images/screenshot.png" />
28
32
  </div>
29
33
 
34
+ ---
35
+
36
+ <br />
37
+
38
+ ## Introduction
39
+
40
+ LesliAdmin is the official account and application administration engine for the [Lesli Framework](https://github.com/LesliTech/Lesli).
41
+
42
+ It gives account owners and administrators a central interface for maintaining the core account identity, inspecting application configuration, and understanding the engines installed in a Lesli application.
43
+
30
44
  <br />
31
- <hr/>
45
+
46
+ ## Features
47
+
48
+ - Core account name and email management
49
+ - Framework configuration overview
50
+ - Installed-engine inventory and metadata
51
+ - Account-scoped data structures for details, locations, settings, and currencies
52
+ - Optional dashboard components through LesliDashboard
53
+
54
+ <br />
55
+
56
+ ## Try LesliAdmin
57
+
58
+ - [Try the online demo](https://demo.lesli.dev/)
59
+ - [Run the Docker demo](https://github.com/LesliTech/lesli-docker-demo)
60
+
32
61
  <br />
33
62
 
34
- ### Installation
63
+ ## Quick Start
64
+
65
+ ### Requirements
66
+
67
+ - A Rails application with [Lesli 5.1](https://rubygems.org/gems/lesli)
68
+ - SQLite by default, or PostgreSQL when preferred by the host application
69
+
70
+ ### Install LesliAdmin
71
+
72
+ Add the engine to the host Rails application and prepare its database:
35
73
 
36
74
  ```shell
37
- # Add LesliAdmin engine gem
38
75
  bundle add lesli_admin
76
+ bin/rails lesli:db:prepare
77
+ ```
78
+
79
+ ### Mount the engine
39
80
 
40
- # Setup & initialize the database
41
- rake lesli:db:setup
81
+ Applications using Lesli's standard router mount LesliAdmin automatically at `/admin`:
82
+
83
+ ```ruby
84
+ # config/routes.rb
85
+ Rails.application.routes.draw do
86
+ Lesli::Router.mount(self)
87
+ end
42
88
  ```
43
89
 
90
+ If the application does not use the standard Lesli router, mount the engine directly:
91
+
44
92
  ```ruby
45
- # Load LesliAdmin engine
93
+ # config/routes.rb
46
94
  Rails.application.routes.draw do
47
95
  mount LesliAdmin::Engine => "/admin"
48
96
  end
49
97
  ```
50
98
 
99
+ Start Rails and visit [http://127.0.0.1:3000/admin](http://127.0.0.1:3000/admin):
100
+
101
+ ```shell
102
+ bin/rails routes -g admin
103
+ bin/rails server
104
+ ```
105
+
106
+ Install [LesliDashboard](https://rubygems.org/gems/lesli_dashboard) when the application should render LesliAdmin's shared dashboard and installed-engines component.
107
+
51
108
  <br />
52
- <hr/>
53
- <br />
54
109
 
55
- ### Development
110
+ ## Development
111
+
112
+ Clone LesliAdmin into the host application's `engines` directory:
56
113
 
57
114
  ```shell
58
- # clone the lesli repo inside your engine folder: RailsApp/engines
59
- git clone https://github.com/LesliTech/LesliAdmin.git
115
+ cd RailsApp
116
+ mkdir -p engines
117
+ git clone https://github.com/LesliTech/LesliAdmin.git engines/LesliAdmin
118
+ ```
60
119
 
61
- # Load LesliAdmin as a Gem
62
- gem "lesli", path: "engines/LesliAdmin"
120
+ Reference the local engine from the host application's `Gemfile`:
63
121
 
64
- # Install the necessary Gems to run LesliAdmin
122
+ ```ruby
123
+ gem "lesli_admin", path: "engines/LesliAdmin"
124
+ ```
125
+
126
+ Install dependencies, prepare the host database, and start Rails:
127
+
128
+ ```shell
65
129
  bundle install
130
+ bin/rails lesli:db:prepare
131
+ bin/rails server
132
+ ```
66
133
 
67
- # Setup & initialize the database
68
- rake lesli:db:setup
134
+ ### Tests
69
135
 
136
+ From a complete Lesli development workspace, run the engine test suite from the LesliAdmin directory:
137
+
138
+ ```shell
139
+ cd engines/LesliAdmin
140
+ bin/rails test
70
141
  ```
71
142
 
72
143
  <br />
73
- <hr/>
74
- <br />
75
-
76
- ### Demo
77
144
 
78
- * [online demo](https://demo.lesli.dev/)
79
- * [docker demo](https://github.com/LesliTech/lesli-docker-demo)
145
+ ## Documentation
80
146
 
147
+ - [Lesli website](https://www.lesli.dev/)
148
+ - [Documentation](https://www.lesli.dev/engines/admin)
149
+ - [Installation guide](https://www.lesli.dev/engines/admin/about/installation)
150
+ - [Account management](https://www.lesli.dev/engines/admin/account/)
151
+ - [Dashboard components](https://www.lesli.dev/engines/admin/about/dashboards)
152
+ - [Translations](https://www.lesli.dev/engines/admin/about/translations)
153
+ - [Database](https://www.lesli.dev/engines/admin/about/database)
154
+ - [Release notes](https://github.com/LesliTech/LesliAdmin/releases)
155
+ - [Issue tracker](https://github.com/LesliTech/LesliAdmin/issues)
156
+ - [Source code](https://github.com/LesliTech/LesliAdmin)
81
157
 
82
- ### Documentation
83
- * [website](https://www.lesli.dev/)
84
- * [documentation](https://www.lesli.dev/engines/admin)
158
+ <br />
85
159
 
160
+ ## Community
86
161
 
87
- ### Connect with Lesli
162
+ - [X: @LesliTech](https://x.com/LesliTech)
163
+ - [hello@lesli.tech](mailto:hello@lesli.tech)
164
+ - [https://www.lesli.tech](https://www.lesli.tech)
88
165
 
89
- * [X: @LesliTech](https://x.com/LesliTech)
90
- * [Email: hello@lesli.tech](hello@lesli.tech)
91
- * [Website: https://www.lesli.tech](https://www.lesli.tech)
166
+ <br />
92
167
 
168
+ ## License
93
169
 
94
- ### License
95
- -------
96
170
  Copyright (c) 2026, Lesli Technologies, S. A.
97
171
 
98
172
  This program is free software: you can redistribute it and/or modify
@@ -106,19 +180,16 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
106
180
  GNU General Public License for more details.
107
181
 
108
182
  You should have received a copy of the GNU General Public License
109
- along with this program. If not, see http://www.gnu.org/licenses/.
183
+ along with this program. If not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/).
110
184
 
111
- <br />
112
- <hr />
113
- <br />
114
- <br />
185
+ The complete license text is available in the [license file](./license).
115
186
 
116
- <div align="center" class="has-text-centered">
117
- <img width="200" alt="Lesli logo" src="https://cdn.lesli.tech/lesli/brand/app-logo.svg" />
118
- <h3 align="center" class="mt-0">
119
- The Open-Source SaaS Development Framework for Ruby on Rails.
120
- </h3>
121
- </div>
187
+ ---
122
188
 
123
189
  <br />
124
190
  <br />
191
+
192
+ <div align="center">
193
+ <img width="80" alt="Lesli icon" src="https://cdn.lesli.tech/lesli/brand/app-icon.svg" />
194
+ <h3 align="center">The Open-Source SaaS Development Framework for Ruby on Rails.</h3>
195
+ </div>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lesli_admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Lesli Development Team
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '5.0'
18
+ version: 5.1.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '5.0'
25
+ version: 5.1.0
26
26
  description: Administration area for the Lesli Framework
27
27
  email:
28
28
  - hello@lesli.tech
@@ -35,6 +35,7 @@ files:
35
35
  - app/assets/images/lesli_admin/admin-logo.svg
36
36
  - app/assets/javascripts/lesli_admin/application.js
37
37
  - app/assets/stylesheets/lesli_admin/application.css
38
+ - app/assets/stylesheets/lesli_admin/application.tailwind.css
38
39
  - app/controllers/lesli_admin/account/currencies_controller.rb
39
40
  - app/controllers/lesli_admin/account/details_controller.rb
40
41
  - app/controllers/lesli_admin/account/locations_controller.rb
@@ -121,7 +122,6 @@ files:
121
122
  - lib/lesli_admin.rb
122
123
  - lib/lesli_admin/engine.rb
123
124
  - lib/lesli_admin/version.rb
124
- - lib/scss/application.scss
125
125
  - lib/tasks/lesli_admin_tasks.rake
126
126
  - license
127
127
  - readme.md
@@ -1,4 +0,0 @@
1
-
2
- .lesli.dashboards {
3
- @import "Lesli/scss/templates/dashboards";
4
- }