Skip to content

Commit 0e04284

Browse files
author
huan
committed
Adding customization dashboard panel which will be generally used
1 parent e7ac867 commit 0e04284

File tree

4 files changed

+219
-18
lines changed

4 files changed

+219
-18
lines changed

app/admin/dashboard.rb

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
ActiveAdmin.register_page "Dashboard" do
33
menu priority: 1, label: proc { I18n.t("active_admin.dashboard") }
44

5+
controller do
6+
include Admin::DashboardHelper
7+
end
8+
59
content title: proc { I18n.t("active_admin.dashboard") } do
610
div class: "blank_slate_container", id: "dashboard_default_message" do
711
span class: "blank_slate" do
@@ -10,24 +14,26 @@
1014
end
1115
end
1216

13-
# Here is an example of a simple dashboard with columns and panels.
14-
#
15-
# columns do
16-
# column do
17-
# panel "Recent Posts" do
18-
# ul do
19-
# Post.recent(5).map do |post|
20-
# li link_to(post.title, admin_post_path(post))
21-
# end
22-
# end
23-
# end
24-
# end
17+
render partial: 'admin/dashboard/customization'
18+
19+
from_date = Admin::CustomizationHelper.parse_date(params[:from], Date.today.last_year)
20+
to_date = Admin::CustomizationHelper.parse_date(params[:to], Date.today)
21+
is_bar_chart = Admin::CustomizationHelper.is_bar_chart(params[:chart_type])
22+
23+
columns do
24+
column do
25+
panel "Recent Posts" do
26+
27+
end
28+
end
2529

26-
# column do
27-
# panel "Info" do
28-
# para "Welcome to ActiveAdmin."
29-
# end
30-
# end
31-
# end
30+
column do
31+
panel "System Info" do
32+
para "Latest Migration: #{latest_migration}"
33+
para "Ruby Version: #{RUBY_VERSION}"
34+
para "Rails Version: #{Rails.version}"
35+
end
36+
end
37+
end
3238
end # content
3339
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module Admin::CustomizationHelper
2+
GROUP_BY_DAY = 'day'.freeze
3+
GROUP_BY_WEEK = 'week'.freeze
4+
GROUP_BY_MONTH = 'month'.freeze
5+
GROUP_BY_YEAR = 'year'.freeze
6+
7+
FORMAT_DAY = "%Y-%m-%d".freeze
8+
FORMAT_WEEK = "W%V/%y".freeze
9+
FORMAT_MONTH = "%m/%y".freeze
10+
FORMAT_YEAR = "%Y".freeze
11+
12+
def self.filter_by_date(data, from = nil, to = nil)
13+
data = data.where('created_at >= ?', from) if from.present? && from.is_a?(Date)
14+
data = data.where('created_at <= ?', to) if to.present? && to.is_a?(Date)
15+
return data
16+
end
17+
18+
def self.group_data_by_created_at(data, group)
19+
return data.group_by_week(:created_at, format: FORMAT_WEEK).count if group == GROUP_BY_WEEK
20+
return data.group_by_month(:created_at, format: FORMAT_MONTH).count if group == GROUP_BY_MONTH
21+
return data.group_by_year(:created_at, format: FORMAT_YEAR).count if group == GROUP_BY_YEAR
22+
return data.group_by_day(:created_at, format: FORMAT_DAY).count
23+
end
24+
25+
def self.parse_date(date_string, default = nil)
26+
begin
27+
return default unless date_string.present?
28+
return Date.strptime(date_string, FORMAT_DAY)
29+
rescue ArgumentError
30+
return default
31+
end
32+
end
33+
34+
def self.parse_group(group_source)
35+
return [GROUP_BY_DAY, GROUP_BY_WEEK, GROUP_BY_MONTH, GROUP_BY_YEAR].include?(group_source) ? group_source : GROUP_BY_WEEK
36+
end
37+
38+
def self.is_bar_chart(chart_type)
39+
return chart_type == 'bar'
40+
end
41+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module Admin::DashboardHelper
2+
def latest_migration
3+
# For schema_migrations table (standard Rails migrations)
4+
latest = ActiveRecord::Base.connection.execute("SELECT version FROM schema_migrations ORDER BY version DESC LIMIT 1").first
5+
6+
latest ? latest['version'] : "No migrations run" # Handle the case where no migrations have been run
7+
rescue ActiveRecord::StatementInvalid # Handle potential database errors
8+
"Error getting migration info"
9+
end
10+
end
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<style>
2+
.form-grid {
3+
display: grid;
4+
grid-template-columns: 1fr 1fr 1fr 30% 15%;
5+
gap: 20px;
6+
align-items: center;
7+
}
8+
9+
.form-group {
10+
display: flex;
11+
flex-direction: column;
12+
padding: 10px;
13+
}
14+
15+
/* Hide default radio buttons */
16+
.radio-group input[type="radio"] {
17+
display: none;
18+
}
19+
20+
/* Style the labels to look like buttons */
21+
.radio-btn {
22+
display: inline-block;
23+
padding: 10px 20px;
24+
margin: 5px;
25+
font-size: 14px;
26+
border: 1px solid #838a90;
27+
background: white;
28+
color: #838a90;
29+
border-radius: 5px;
30+
cursor: pointer;
31+
transition: all 0.3s;
32+
}
33+
34+
/* Change appearance when selected */
35+
.radio-group input[type="radio"]:checked + .radio-btn {
36+
background: #838a90;
37+
color: white;
38+
}
39+
40+
/* Hover effect */
41+
.radio-btn:hover {
42+
background: #838a90;
43+
color: white;
44+
}
45+
</style>
46+
47+
<%= form_with url: admin_dashboard_path, method: :get, html: { class: "form-horizontal" } do |f| %>
48+
<fieldset class="inputs">
49+
<legend class="fieldset-title">
50+
<span>Customize The Dashboard</span>
51+
</legend>
52+
<div class="form-grid">
53+
<div class="form-group">
54+
<%= f.label :from, "Filter From" %>
55+
<%= f.text_field :from, value: Admin::CustomizationHelper.parse_date(params[:from], Date.today.last_year), id: 'from_date' %>
56+
</div>
57+
<div class="form-group">
58+
<%= f.label :to, "To" %>
59+
<%= f.text_field :to, value: Admin::CustomizationHelper.parse_date(params[:to], Date.today), id: 'to_date' %>
60+
</div>
61+
<div class="form-group">
62+
<%= f.label :chart_type, "Chart Type" %>
63+
<div class="radio-group">
64+
<%= f.radio_button :chart_type, "line", id: "chart_type_line", checked: !Admin::CustomizationHelper.is_bar_chart(params[:chart_type]) %>
65+
<%= f.label :chart_type_line, "Line", class: "radio-btn" %>
66+
67+
<%= f.radio_button :chart_type, "bar", id: "chart_type_bar", checked: Admin::CustomizationHelper.is_bar_chart(params[:chart_type]) %>
68+
<%= f.label :chart_type_bar, "Bar", class: "radio-btn" %>
69+
</div>
70+
</div>
71+
<div class="form-group">
72+
<%= f.label :group, "Group By" %>
73+
<div class="radio-group">
74+
<%= f.radio_button :group, "day", id: "group_day", checked: Admin::CustomizationHelper.parse_group(params[:group]) == 'day' %>
75+
<%= f.label :group_day, "Day", class: "radio-btn" %>
76+
77+
<%= f.radio_button :group, "week", id: "group_week", checked: Admin::CustomizationHelper.parse_group(params[:group]) == 'week' %>
78+
<%= f.label :group_week, "Week", class: "radio-btn" %>
79+
80+
<%= f.radio_button :group, "month", id: "group_month", checked: Admin::CustomizationHelper.parse_group(params[:group]) == 'month' %>
81+
<%= f.label :group_month, "Month", class: "radio-btn" %>
82+
83+
<%= f.radio_button :group, "year", id: "group_year", checked: Admin::CustomizationHelper.parse_group(params[:group]) == 'year' %>
84+
<%= f.label :group_year, "Year", class: "radio-btn" %>
85+
</div>
86+
</div>
87+
<div class="form-group">
88+
<%= f.submit "Apply" %>
89+
</div>
90+
</ol>
91+
</fieldset>
92+
<% end %>
93+
94+
<script>
95+
$(document).ready(function() {
96+
let $from_date = $("#from_date")
97+
let $to_date = $("#to_date")
98+
99+
$from_date.datepicker({
100+
dateFormat: "yy-mm-dd",
101+
onSelect: function(selectedDate) {
102+
updateToDateMin()
103+
}
104+
});
105+
$from_date.on("change", function() {
106+
updateToDateMin();
107+
});
108+
109+
$to_date.datepicker({
110+
dateFormat: "yy-mm-dd",
111+
onSelect: function(selectedDate) {
112+
updateFromDateMax();
113+
}
114+
});
115+
$from_date.on("change", function() {
116+
updateFromDateMax();
117+
});
118+
119+
if ($from_date.val() !== "") {
120+
updateToDateMin();
121+
}
122+
if ($to_date.val() !== "") {
123+
updateFromDateMax();
124+
}
125+
126+
function updateToDateMin() {
127+
let selectedDate = $from_date.val();
128+
if (selectedDate === "") {
129+
$to_date.datepicker("option", "minDate", null);
130+
} else {
131+
$to_date.datepicker("option", "minDate", selectedDate);
132+
}
133+
}
134+
135+
function updateFromDateMax() {
136+
let selectedDate = $to_date.val();
137+
if (selectedDate === "") {
138+
$from_date.datepicker("option", "maxDate", null);
139+
} else {
140+
$from_date.datepicker("option", "maxDate", selectedDate);
141+
}
142+
}
143+
});
144+
</script>

0 commit comments

Comments
 (0)