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 +4 -4
- data/Rakefile +3 -1
- data/app/assets/stylesheets/lesli_admin/application.tailwind.css +2 -0
- data/app/controllers/lesli_admin/account/currencies_controller.rb +2 -2
- data/app/controllers/lesli_admin/account/details_controller.rb +2 -2
- data/app/controllers/lesli_admin/account/locations_controller.rb +2 -2
- data/app/controllers/lesli_admin/account/settings_controller.rb +2 -2
- data/app/views/lesli_admin/dashboards/_component-installed-engines.html.erb +1 -8
- data/app/views/lesli_admin/settings/_defaults.html.erb +43 -33
- data/app/views/lesli_admin/settings/_modules.html.erb +28 -32
- data/db/seeds.rb +1 -1
- data/lib/lesli_admin/version.rb +2 -2
- data/readme.md +120 -49
- metadata +4 -4
- data/lib/scss/application.scss +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4be526cc5d4c0ebe88f74ec2046f9910cba16c61199ad1691901a30c2566c878
|
|
4
|
+
data.tar.gz: 68889417b39b041632c52da972e946311115b676e0008211c0b68e7b7cb4c0d7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a15c772978ba4fd4ed72c7f94790ce50c849314f89b9d80679ccb999f55c42a43ee3c3d72d55179652b1e5f39f77cb4cfc05819342459690f6d9e2d93f8dbd00
|
|
7
|
+
data.tar.gz: 27da84af4ac7c6b58fe44115aa750c14c90102d995e9caa1a4c7d9c818f5251451779557e1bd978c0c7161fc0e8dd64a0f598cfd6d6e0ae70b2aaf180bc0d28a
|
data/Rakefile
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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="
|
|
36
|
-
<
|
|
37
|
-
<
|
|
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-
|
|
40
|
-
<% value.each do |
|
|
41
|
-
<li>
|
|
42
|
-
<
|
|
43
|
-
<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="
|
|
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="
|
|
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="
|
|
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
|
-
</
|
|
64
|
+
</dd>
|
|
56
65
|
</div>
|
|
57
66
|
<% end %>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
</dl>
|
|
68
|
+
</article>
|
|
69
|
+
<% end %>
|
|
70
|
+
</div>
|
|
61
71
|
</section>
|
|
@@ -20,42 +20,38 @@
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
</script>
|
|
23
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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
|
-
|
|
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
|
-
</
|
|
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
|
-
|
|
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"))
|
data/lib/lesli_admin/version.rb
CHANGED
data/readme.md
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<
|
|
3
|
-
|
|
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="
|
|
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="
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
Clone LesliAdmin into the host application's `engines` directory:
|
|
56
113
|
|
|
57
114
|
```shell
|
|
58
|
-
|
|
59
|
-
|
|
115
|
+
cd RailsApp
|
|
116
|
+
mkdir -p engines
|
|
117
|
+
git clone https://github.com/LesliTech/LesliAdmin.git engines/LesliAdmin
|
|
118
|
+
```
|
|
60
119
|
|
|
61
|
-
|
|
62
|
-
gem "lesli", path: "engines/LesliAdmin"
|
|
120
|
+
Reference the local engine from the host application's `Gemfile`:
|
|
63
121
|
|
|
64
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
83
|
-
* [website](https://www.lesli.dev/)
|
|
84
|
-
* [documentation](https://www.lesli.dev/engines/admin)
|
|
158
|
+
<br />
|
|
85
159
|
|
|
160
|
+
## Community
|
|
86
161
|
|
|
87
|
-
|
|
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
|
-
|
|
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
|
|
183
|
+
along with this program. If not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/).
|
|
110
184
|
|
|
111
|
-
|
|
112
|
-
<hr />
|
|
113
|
-
<br />
|
|
114
|
-
<br />
|
|
185
|
+
The complete license text is available in the [license file](./license).
|
|
115
186
|
|
|
116
|
-
|
|
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.
|
|
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:
|
|
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:
|
|
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
|
data/lib/scss/application.scss
DELETED