lesli_admin 1.1.1 → 1.1.2
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 -0
- data/app/assets/stylesheets/lesli_admin/application.css +648 -584
- data/app/controllers/lesli_admin/account/details_controller.rb +11 -4
- data/app/controllers/lesli_admin/account/locations_controller.rb +8 -4
- data/app/controllers/lesli_admin/accounts_controller.rb +41 -27
- data/app/controllers/lesli_admin/dashboards_controller.rb +21 -0
- data/app/models/lesli_admin/account/currency.rb +4 -2
- data/app/models/lesli_admin/account/detail.rb +3 -0
- data/app/models/lesli_admin/account/location.rb +12 -2
- data/app/models/lesli_admin/account/setting.rb +4 -2
- data/app/models/lesli_admin/account.rb +18 -1
- data/app/models/lesli_admin/dashboard.rb +8 -1
- data/app/services/lesli_admin/account_service.rb +43 -16
- data/app/views/lesli_admin/accounts/show.html.erb +104 -7
- data/app/views/lesli_admin/dashboards/_component-account-metadata.html.erb +44 -0
- data/app/views/lesli_admin/dashboards/_component-installed-engines.html.erb +1 -1
- data/app/views/lesli_admin/dashboards/_component-roles.html.erb +1 -0
- data/app/views/lesli_admin/dashboards/_component-users.html.erb +1 -0
- data/app/views/lesli_admin/settings/_configuration_value.html.erb +52 -0
- data/app/views/lesli_admin/settings/_defaults.html.erb +145 -58
- data/db/migrate/v1/0101000210_create_lesli_admin_account_details.rb +7 -1
- data/db/migrate/v1/0101000410_create_lesli_admin_account_locations.rb +6 -1
- data/lib/lesli_admin/engine.rb +0 -4
- data/lib/lesli_admin/version.rb +1 -1
- data/readme.md +8 -5
- metadata +10 -5
- data/app/assets/config/lesli_admin_manifest.js +0 -38
- data/app/assets/stylesheets/lesli_admin/application.tailwind.css +0 -2
|
@@ -1,71 +1,158 @@
|
|
|
1
1
|
<%
|
|
2
|
-
sections =
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
sections = [
|
|
3
|
+
{
|
|
4
|
+
title: "Instance",
|
|
5
|
+
icon: "dns",
|
|
6
|
+
description: "Runtime identity and operating mode for this installation.",
|
|
7
|
+
config: {
|
|
8
|
+
demo: Lesli.config.demo,
|
|
9
|
+
instance: Lesli.config.instance
|
|
10
|
+
}
|
|
6
11
|
},
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
{
|
|
13
|
+
title: "Company",
|
|
14
|
+
icon: "apartment",
|
|
15
|
+
description: "Organization details displayed throughout the platform.",
|
|
16
|
+
config: Lesli.config.company
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
title: "Locales",
|
|
20
|
+
icon: "translate",
|
|
21
|
+
description: "Languages currently available to users.",
|
|
22
|
+
config: Lesli.config.babel&.fetch(:locales, {})
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: "Date and time",
|
|
26
|
+
icon: "schedule",
|
|
27
|
+
description: "Time zone, week boundaries, and display formats.",
|
|
28
|
+
config: Lesli.config.datetime
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
title: "Security",
|
|
32
|
+
icon: "shield_lock",
|
|
33
|
+
description: "Authentication and account-access behavior.",
|
|
34
|
+
config: Lesli.config.security
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
title: "Theme",
|
|
38
|
+
icon: "palette",
|
|
39
|
+
description: "Colors used by the shared Lesli interface.",
|
|
40
|
+
config: Lesli.config.theme
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
title: "Layout",
|
|
44
|
+
icon: "dashboard_customize",
|
|
45
|
+
description: "Global interface features and visibility controls.",
|
|
46
|
+
config: Lesli.config.layout
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
title: "Mailer",
|
|
50
|
+
icon: "mail",
|
|
51
|
+
description: "Email delivery and template configuration.",
|
|
52
|
+
config: Lesli.config.mailer
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: "Paths",
|
|
56
|
+
icon: "route",
|
|
57
|
+
description: "Application destinations used by navigation and authentication.",
|
|
58
|
+
config: {
|
|
59
|
+
path_after_login: Lesli.config.shield&.fetch(:path_after_login, nil)
|
|
60
|
+
}
|
|
16
61
|
}
|
|
17
|
-
}
|
|
62
|
+
].map { |section| section.merge(config: section[:config] || {}) }
|
|
63
|
+
|
|
64
|
+
leaf_count = lambda do |value|
|
|
65
|
+
case value
|
|
66
|
+
when Hash
|
|
67
|
+
value.values.sum { |nested_value| leaf_count.call(nested_value) }
|
|
68
|
+
when Array
|
|
69
|
+
value.sum { |nested_value| leaf_count.call(nested_value) }
|
|
70
|
+
else
|
|
71
|
+
1
|
|
72
|
+
end
|
|
73
|
+
end
|
|
18
74
|
|
|
19
|
-
|
|
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
|
-
}
|
|
75
|
+
total_settings = sections.sum { |section| leaf_count.call(section[:config]) }
|
|
25
76
|
%>
|
|
26
77
|
|
|
27
78
|
<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
79
|
|
|
34
|
-
<div class="
|
|
35
|
-
|
|
36
|
-
<
|
|
37
|
-
|
|
80
|
+
<div class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm sm:p-6">
|
|
81
|
+
<div class="flex items-center gap-3">
|
|
82
|
+
<span class="material-symbols-outlined rounded-xl bg-sky-50 p-2.5 text-2xl text-sky-700" aria-hidden="true">settings</span>
|
|
83
|
+
<div>
|
|
84
|
+
<h2 id="lesli-configuration-title" class="text-xl font-semibold tracking-tight text-slate-900">
|
|
85
|
+
Lesli configuration
|
|
86
|
+
</h2>
|
|
87
|
+
<p class="mt-1 text-sm leading-6 text-slate-500">
|
|
88
|
+
Effective read-only values loaded by this application instance.
|
|
89
|
+
</p>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<dl class="mt-6 grid grid-cols-2 gap-3 lg:grid-cols-4">
|
|
94
|
+
<div class="rounded-xl bg-slate-50 px-4 py-3">
|
|
95
|
+
<dt class="text-xs font-medium uppercase tracking-wide text-slate-500">Environment</dt>
|
|
96
|
+
<dd class="mt-1 text-sm font-semibold text-slate-900"><%= Rails.env.to_s.humanize %></dd>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="rounded-xl bg-slate-50 px-4 py-3">
|
|
99
|
+
<dt class="text-xs font-medium uppercase tracking-wide text-slate-500">Sections</dt>
|
|
100
|
+
<dd class="mt-1 text-sm font-semibold text-slate-900"><%= sections.size %></dd>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="rounded-xl bg-slate-50 px-4 py-3">
|
|
103
|
+
<dt class="text-xs font-medium uppercase tracking-wide text-slate-500">Values</dt>
|
|
104
|
+
<dd class="mt-1 text-sm font-semibold text-slate-900"><%= total_settings %></dd>
|
|
105
|
+
</div>
|
|
106
|
+
<div class="rounded-xl bg-slate-50 px-4 py-3">
|
|
107
|
+
<dt class="text-xs font-medium uppercase tracking-wide text-slate-500">Demo mode</dt>
|
|
108
|
+
<dd class="mt-1">
|
|
109
|
+
<span class="inline-flex items-center rounded-full px-2 py-0.5 text-xs font-semibold <%= Lesli.config.demo ? "bg-amber-100 text-amber-700" : "bg-emerald-100 text-emerald-700" %>">
|
|
110
|
+
<%= Lesli.config.demo ? "Enabled" : "Disabled" %>
|
|
111
|
+
</span>
|
|
112
|
+
</dd>
|
|
113
|
+
</div>
|
|
114
|
+
</dl>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="mt-5 space-y-4">
|
|
118
|
+
<% sections.each_with_index do |section, index| %>
|
|
119
|
+
<details
|
|
120
|
+
class="group rounded-2xl border border-slate-200 bg-white shadow-sm"
|
|
121
|
+
<%= "open" if index < 2 %>>
|
|
122
|
+
<summary class="flex cursor-pointer list-none items-center gap-4 px-5 py-4 marker:hidden sm:px-6">
|
|
123
|
+
<span class="material-symbols-outlined rounded-xl bg-slate-100 p-2.5 text-2xl text-slate-600" aria-hidden="true"><%= section[:icon] %></span>
|
|
124
|
+
<span class="min-w-0 flex-1">
|
|
125
|
+
<span class="block text-base font-semibold text-slate-900"><%= section[:title] %></span>
|
|
126
|
+
<span class="mt-0.5 block text-sm leading-5 text-slate-500"><%= section[:description] %></span>
|
|
127
|
+
</span>
|
|
128
|
+
<span class="hidden rounded-full bg-slate-100 px-2.5 py-1 text-xs font-semibold text-slate-600 sm:inline-flex">
|
|
129
|
+
<%= pluralize(section[:config].size, "group") %>
|
|
130
|
+
</span>
|
|
131
|
+
<span class="material-symbols-outlined text-slate-400 transition-transform group-open:rotate-180" aria-hidden="true">expand_more</span>
|
|
132
|
+
</summary>
|
|
38
133
|
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
<%
|
|
45
|
-
<
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<% end %>
|
|
52
|
-
</ul>
|
|
53
|
-
<% elsif value == true %>
|
|
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>
|
|
57
|
-
<% elsif value == false %>
|
|
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>
|
|
61
|
-
<% else %>
|
|
62
|
-
<code class="break-all rounded bg-slate-100 px-1.5 py-1 text-xs text-slate-700"><%= value.to_s %></code>
|
|
134
|
+
<div class="border-t border-slate-100 px-5 py-5 sm:px-6">
|
|
135
|
+
<% if section[:config].empty? %>
|
|
136
|
+
<p class="text-sm text-slate-500">No values are configured for this section.</p>
|
|
137
|
+
<% else %>
|
|
138
|
+
<dl class="grid grid-cols-1 gap-4 lg:grid-cols-2">
|
|
139
|
+
<% section[:config].each do |key, value| %>
|
|
140
|
+
<div class="min-w-0 rounded-xl border border-slate-100 bg-slate-50/60 p-4">
|
|
141
|
+
<dt class="text-xs font-semibold uppercase tracking-wide text-slate-500"><%= key.to_s.humanize %></dt>
|
|
142
|
+
<dd class="mt-2 text-sm text-slate-900">
|
|
143
|
+
<%= render("configuration_value", setting_key: key, value: value) %>
|
|
144
|
+
</dd>
|
|
145
|
+
</div>
|
|
63
146
|
<% end %>
|
|
64
|
-
</
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
</article>
|
|
147
|
+
</dl>
|
|
148
|
+
<% end %>
|
|
149
|
+
</div>
|
|
150
|
+
</details>
|
|
69
151
|
<% end %>
|
|
70
152
|
</div>
|
|
153
|
+
|
|
154
|
+
<p class="mt-5 flex items-start gap-2 text-xs leading-5 text-slate-500">
|
|
155
|
+
<span class="material-symbols-outlined text-base" aria-hidden="true">lock</span>
|
|
156
|
+
Sensitive values are filtered on the server and are never included in this page.
|
|
157
|
+
</p>
|
|
71
158
|
</section>
|
|
@@ -65,6 +65,12 @@ class CreateLesliAdminAccountDetails < ActiveRecord::Migration[6.0]
|
|
|
65
65
|
t.datetime :deleted_at, index: true
|
|
66
66
|
t.timestamps
|
|
67
67
|
end
|
|
68
|
-
add_reference(
|
|
68
|
+
add_reference(
|
|
69
|
+
:lesli_admin_account_details,
|
|
70
|
+
:account,
|
|
71
|
+
null: false,
|
|
72
|
+
index: { unique: true },
|
|
73
|
+
foreign_key: { to_table: :lesli_admin_accounts }
|
|
74
|
+
)
|
|
69
75
|
end
|
|
70
76
|
end
|
|
@@ -57,7 +57,12 @@ class CreateLesliAdminAccountLocations < ActiveRecord::Migration[6.0]
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
add_reference(:lesli_admin_account_locations, :parent, foreign_key: { to_table: :lesli_admin_account_locations })
|
|
60
|
-
add_reference(
|
|
60
|
+
add_reference(
|
|
61
|
+
:lesli_admin_account_locations,
|
|
62
|
+
:account,
|
|
63
|
+
null: false,
|
|
64
|
+
foreign_key: { to_table: :lesli_admin_accounts }
|
|
65
|
+
)
|
|
61
66
|
add_index(:lesli_admin_account_locations, %i[account_id name level parent_id], unique: true, name: "location_uniqueness_index")
|
|
62
67
|
end
|
|
63
68
|
end
|
data/lib/lesli_admin/engine.rb
CHANGED
|
@@ -35,10 +35,6 @@ module LesliAdmin
|
|
|
35
35
|
isolate_namespace LesliAdmin
|
|
36
36
|
|
|
37
37
|
initializer :lesli_admin do |app|
|
|
38
|
-
|
|
39
|
-
# register assets manifest
|
|
40
|
-
config.assets.precompile += %w[lesli_admin_manifest.js]
|
|
41
|
-
|
|
42
38
|
# register engine migrations path
|
|
43
39
|
unless app.root.to_s.match root.to_s
|
|
44
40
|
config.paths["db/migrate"].expanded.each do |expanded_path|
|
data/lib/lesli_admin/version.rb
CHANGED
data/readme.md
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
<br />
|
|
9
9
|
|
|
10
10
|
<div align="center">
|
|
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">
|
|
11
|
+
<a target="_blank" href="https://github.com/LesliTech/LesliAdmin/actions/workflows/lesli-ci-engine.yaml">
|
|
12
|
+
<img alt="LesliAdmin test status" src="https://img.shields.io/github/actions/workflow/status/LesliTech/LesliAdmin/lesli-ci-engine.yaml?branch=master&style=for-the-badge&logo=github&label=tests">
|
|
13
13
|
</a>
|
|
14
14
|
<a target="_blank" href="https://rubygems.org/gems/lesli_admin">
|
|
15
15
|
<img alt="Gem Version" src="https://img.shields.io/gem/v/lesli_admin?style=for-the-badge&logo=ruby">
|
|
@@ -45,8 +45,10 @@ It gives account owners and administrators a central interface for maintaining t
|
|
|
45
45
|
|
|
46
46
|
## Features
|
|
47
47
|
|
|
48
|
-
- Core account
|
|
49
|
-
-
|
|
48
|
+
- Core account identity, status, and data-region management
|
|
49
|
+
- Company profile, contact, address, and social-link management
|
|
50
|
+
- Read-only framework configuration viewer with server-side secret filtering
|
|
51
|
+
- Account dashboard with user, role, installed-engine, and lifecycle metrics
|
|
50
52
|
- Installed-engine inventory and metadata
|
|
51
53
|
- Account-scoped data structures for details, locations, settings, and currencies
|
|
52
54
|
- Optional dashboard components through LesliDashboard
|
|
@@ -103,7 +105,7 @@ bin/rails routes -g admin
|
|
|
103
105
|
bin/rails server
|
|
104
106
|
```
|
|
105
107
|
|
|
106
|
-
Install [LesliDashboard](https://rubygems.org/gems/lesli_dashboard) when the application should render LesliAdmin's
|
|
108
|
+
Install [LesliDashboard](https://rubygems.org/gems/lesli_dashboard) when the application should persist and render LesliAdmin's account metrics and metadata components.
|
|
107
109
|
|
|
108
110
|
<br />
|
|
109
111
|
|
|
@@ -149,6 +151,7 @@ bin/rails test
|
|
|
149
151
|
- [Installation guide](https://www.lesli.dev/engines/admin/about/installation)
|
|
150
152
|
- [Account management](https://www.lesli.dev/engines/admin/account/)
|
|
151
153
|
- [Dashboard components](https://www.lesli.dev/engines/admin/about/dashboards)
|
|
154
|
+
- [Settings and configuration](https://www.lesli.dev/engines/admin/about/settings)
|
|
152
155
|
- [Translations](https://www.lesli.dev/engines/admin/about/translations)
|
|
153
156
|
- [Database](https://www.lesli.dev/engines/admin/about/database)
|
|
154
157
|
- [Release notes](https://github.com/LesliTech/LesliAdmin/releases)
|
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lesli_admin
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- The Lesli Development Team
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2026-10-23 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: lesli
|
|
@@ -31,11 +32,9 @@ extensions: []
|
|
|
31
32
|
extra_rdoc_files: []
|
|
32
33
|
files:
|
|
33
34
|
- Rakefile
|
|
34
|
-
- app/assets/config/lesli_admin_manifest.js
|
|
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
|
|
39
38
|
- app/controllers/lesli_admin/account/currencies_controller.rb
|
|
40
39
|
- app/controllers/lesli_admin/account/details_controller.rb
|
|
41
40
|
- app/controllers/lesli_admin/account/locations_controller.rb
|
|
@@ -87,12 +86,16 @@ files:
|
|
|
87
86
|
- app/views/lesli_admin/account/settings/new.html.erb
|
|
88
87
|
- app/views/lesli_admin/account/settings/show.html.erb
|
|
89
88
|
- app/views/lesli_admin/accounts/show.html.erb
|
|
89
|
+
- app/views/lesli_admin/dashboards/_component-account-metadata.html.erb
|
|
90
90
|
- app/views/lesli_admin/dashboards/_component-installed-engines.html.erb
|
|
91
|
+
- app/views/lesli_admin/dashboards/_component-roles.html.erb
|
|
92
|
+
- app/views/lesli_admin/dashboards/_component-users.html.erb
|
|
91
93
|
- app/views/lesli_admin/dashboards/edit.html.erb
|
|
92
94
|
- app/views/lesli_admin/dashboards/index.html.erb
|
|
93
95
|
- app/views/lesli_admin/dashboards/new.html.erb
|
|
94
96
|
- app/views/lesli_admin/dashboards/show.html.erb
|
|
95
97
|
- app/views/lesli_admin/partials/_navigation.html.erb
|
|
98
|
+
- app/views/lesli_admin/settings/_configuration_value.html.erb
|
|
96
99
|
- app/views/lesli_admin/settings/_defaults.html.erb
|
|
97
100
|
- app/views/lesli_admin/settings/_form.html.erb
|
|
98
101
|
- app/views/lesli_admin/settings/_modules.html.erb
|
|
@@ -134,6 +137,7 @@ metadata:
|
|
|
134
137
|
source_code_uri: https://github.com/LesliTech/LesliAdmin
|
|
135
138
|
bug_tracker_uri: https://github.com/LesliTech/LesliAdmin/issues
|
|
136
139
|
documentation_uri: https://www.lesli.dev/engines/admin
|
|
140
|
+
post_install_message:
|
|
137
141
|
rdoc_options: []
|
|
138
142
|
require_paths:
|
|
139
143
|
- lib
|
|
@@ -148,7 +152,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
148
152
|
- !ruby/object:Gem::Version
|
|
149
153
|
version: '0'
|
|
150
154
|
requirements: []
|
|
151
|
-
rubygems_version: 3.
|
|
155
|
+
rubygems_version: 3.5.16
|
|
156
|
+
signing_key:
|
|
152
157
|
specification_version: 4
|
|
153
158
|
summary: Administration area for the Lesli Framework
|
|
154
159
|
test_files: []
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
|
|
3
|
-
Lesli
|
|
4
|
-
|
|
5
|
-
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
-
|
|
7
|
-
This program is free software: you can redistribute it and/or modify
|
|
8
|
-
it under the terms of the GNU General Public License as published by
|
|
9
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
-
(at your option) any later version.
|
|
11
|
-
|
|
12
|
-
This program is distributed in the hope that it will be useful,
|
|
13
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
-
GNU General Public License for more details.
|
|
16
|
-
|
|
17
|
-
You should have received a copy of the GNU General Public License
|
|
18
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
-
|
|
20
|
-
Lesli · Ruby on Rails SaaS development platform.
|
|
21
|
-
|
|
22
|
-
Made with ♥ by https://www.lesli.tech
|
|
23
|
-
Building a better future, one line of code at a time.
|
|
24
|
-
|
|
25
|
-
@contact hello@lesli.tech
|
|
26
|
-
@website https://www.lesli.tech
|
|
27
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
-
|
|
29
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
-
// ·
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
//= link_tree ../images/lesli_admin .png
|
|
34
|
-
//= link_tree ../images/lesli_admin .jpg
|
|
35
|
-
//= link_tree ../images/lesli_admin .svg
|
|
36
|
-
|
|
37
|
-
//= link lesli_admin/application.css
|
|
38
|
-
//= link lesli_admin/application.js
|
|
@@ -1,2 +0,0 @@
|
|
|
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}
|