dbdoc_engine 0.1.0
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 +7 -0
- data/README.md +331 -0
- data/Rakefile +8 -0
- data/app/assets/builds/dbdoc_engine/application.css +5 -0
- data/app/assets/images/dbdoc_engine/arrowdown.svg +3 -0
- data/app/assets/images/dbdoc_engine/arrowhorizontal.svg +3 -0
- data/app/assets/images/dbdoc_engine/arrowleft.svg +3 -0
- data/app/assets/images/dbdoc_engine/changelog.svg +3 -0
- data/app/assets/images/dbdoc_engine/column_stats_dbdocs.svg +23 -0
- data/app/assets/images/dbdoc_engine/diagram.svg +3 -0
- data/app/assets/images/dbdoc_engine/double_arrow.svg +4 -0
- data/app/assets/images/dbdoc_engine/group_bu.svg +3 -0
- data/app/assets/images/dbdoc_engine/japan_circle.png +0 -0
- data/app/assets/images/dbdoc_engine/log_in_image.png +0 -0
- data/app/assets/images/dbdoc_engine/logo.svg +12 -0
- data/app/assets/images/dbdoc_engine/orange_changelog.svg +3 -0
- data/app/assets/images/dbdoc_engine/orange_fields.svg +23 -0
- data/app/assets/images/dbdoc_engine/orange_logo.svg +12 -0
- data/app/assets/images/dbdoc_engine/orange_table.svg +21 -0
- data/app/assets/images/dbdoc_engine/orange_updates.svg +43 -0
- data/app/assets/images/dbdoc_engine/orange_wiki.svg +3 -0
- data/app/assets/images/dbdoc_engine/search.svg +3 -0
- data/app/assets/images/dbdoc_engine/setting.svg +3 -0
- data/app/assets/images/dbdoc_engine/table_dbdocs.svg +21 -0
- data/app/assets/images/dbdoc_engine/uk_circle_transparent.png +0 -0
- data/app/assets/images/dbdoc_engine/update_stats_dbdocs.svg +43 -0
- data/app/assets/images/dbdoc_engine/wiki.svg +3 -0
- data/app/assets/stylesheets/dbdoc_engine/admin.css +176 -0
- data/app/assets/stylesheets/dbdoc_engine/admin_header.css +179 -0
- data/app/assets/stylesheets/dbdoc_engine/application.scss +1 -0
- data/app/assets/stylesheets/dbdoc_engine/changelog.css +173 -0
- data/app/assets/stylesheets/dbdoc_engine/dashboard.css +513 -0
- data/app/assets/stylesheets/dbdoc_engine/dbdoc_application.css +117 -0
- data/app/assets/stylesheets/dbdoc_engine/ecommerce.css +253 -0
- data/app/assets/stylesheets/dbdoc_engine/group_details.css +178 -0
- data/app/assets/stylesheets/dbdoc_engine/header.css +212 -0
- data/app/assets/stylesheets/dbdoc_engine/loading_spinner.css +127 -0
- data/app/assets/stylesheets/dbdoc_engine/login.css +213 -0
- data/app/assets/stylesheets/dbdoc_engine/schema_diagram.css +149 -0
- data/app/assets/stylesheets/dbdoc_engine/sidebar.css +296 -0
- data/app/assets/stylesheets/dbdoc_engine/table_details.css +417 -0
- data/app/controllers/dbdoc_engine/admin/base_controller.rb +23 -0
- data/app/controllers/dbdoc_engine/admin/dashboard_controller.rb +16 -0
- data/app/controllers/dbdoc_engine/admin/data_transfer_controller.rb +63 -0
- data/app/controllers/dbdoc_engine/admin/db_design_dynamic_tables_controller.rb +198 -0
- data/app/controllers/dbdoc_engine/admin/db_design_table_groups_controller.rb +107 -0
- data/app/controllers/dbdoc_engine/application_controller.rb +65 -0
- data/app/controllers/dbdoc_engine/concerns/internationalization.rb +57 -0
- data/app/controllers/dbdoc_engine/db_doc_sessions_controller.rb +33 -0
- data/app/controllers/dbdoc_engine/home_controller.rb +79 -0
- data/app/controllers/dbdoc_engine/schema_diagram_controller.rb +293 -0
- data/app/helper/dbdoc_engine/application_helper.rb +35 -0
- data/app/helpers/dbdoc_engine/application_helper.rb +4 -0
- data/app/helpers/dbdoc_engine/changelogs_helper.rb +27 -0
- data/app/helpers/dbdoc_engine/column_helper.rb +30 -0
- data/app/helpers/dbdoc_engine/db_design_dynamic_tables_helper.rb +15 -0
- data/app/helpers/dbdoc_engine/home_helper.rb +75 -0
- data/app/javascript/dbdoc_engine/application.js +12 -0
- data/app/javascript/dbdoc_engine/controllers/application.js +29 -0
- data/app/javascript/dbdoc_engine/controllers/auto_submit_controller.js +17 -0
- data/app/javascript/dbdoc_engine/controllers/chart_controller.js +58 -0
- data/app/javascript/dbdoc_engine/controllers/column-type_controller.js +149 -0
- data/app/javascript/dbdoc_engine/controllers/column_controller.js +362 -0
- data/app/javascript/dbdoc_engine/controllers/column_search_controller.js +42 -0
- data/app/javascript/dbdoc_engine/controllers/dbdoc_accordion_controller.js +42 -0
- data/app/javascript/dbdoc_engine/controllers/ecommerce_controller.js +73 -0
- data/app/javascript/dbdoc_engine/controllers/group_details_controller.js +88 -0
- data/app/javascript/dbdoc_engine/controllers/import_export_controller.js +200 -0
- data/app/javascript/dbdoc_engine/controllers/index.js +9 -0
- data/app/javascript/dbdoc_engine/controllers/language_controller.js +100 -0
- data/app/javascript/dbdoc_engine/controllers/loading_spinner_controller.js +48 -0
- data/app/javascript/dbdoc_engine/controllers/login_controller.js +75 -0
- data/app/javascript/dbdoc_engine/controllers/notification_controller.js +15 -0
- data/app/javascript/dbdoc_engine/controllers/schema_diagram_controller.js +1129 -0
- data/app/javascript/dbdoc_engine/controllers/select2_controller.js +67 -0
- data/app/javascript/dbdoc_engine/controllers/sidebar_controller.js +943 -0
- data/app/javascript/dbdoc_engine/controllers/table_details_controller.js +245 -0
- data/app/javascript/dbdoc_engine/controllers/table_group_validation_controller.js +148 -0
- data/app/javascript/dbdoc_engine/controllers/table_validation_controller.js +423 -0
- data/app/jobs/dbdoc_engine/application_job.rb +4 -0
- data/app/mailers/dbdoc_engine/application_mailer.rb +6 -0
- data/app/models/dbdoc_engine/application_record.rb +6 -0
- data/app/models/dbdoc_engine/concerns/soft_deletable.rb +30 -0
- data/app/models/dbdoc_engine/db_design_changelog.rb +44 -0
- data/app/models/dbdoc_engine/db_design_dynamic_column.rb +211 -0
- data/app/models/dbdoc_engine/db_design_dynamic_table.rb +124 -0
- data/app/models/dbdoc_engine/db_design_table_group.rb +88 -0
- data/app/models/dbdoc_engine/user.rb +21 -0
- data/app/queries/dbdoc_engine/admin_dashboard_queries.rb +71 -0
- data/app/queries/dbdoc_engine/db_design_changelog_queries.rb +68 -0
- data/app/queries/dbdoc_engine/db_design_dynamic_column_queries.rb +37 -0
- data/app/queries/dbdoc_engine/db_design_dynamic_table_commands.rb +106 -0
- data/app/queries/dbdoc_engine/db_design_dynamic_table_queries.rb +194 -0
- data/app/queries/dbdoc_engine/db_design_table_group_queries.rb +154 -0
- data/app/services/dbdoc_engine/db_design_dynamic_table_export_service.rb +38 -0
- data/app/services/dbdoc_engine/db_design_dynamic_table_handler_service.rb +49 -0
- data/app/services/dbdoc_engine/db_design_dynamic_tables_service.rb +21 -0
- data/app/services/dbdoc_engine/error_handler_service.rb +43 -0
- data/app/services/dbdoc_engine/schema_rb_import_service.rb +194 -0
- data/app/services/dbdoc_engine/schema_rb_parser_service.rb +339 -0
- data/app/services/dbdoc_engine/table_filter_service.rb +35 -0
- data/app/services/dbdoc_engine/table_groups_service.rb +199 -0
- data/app/services/dbdoc_engine/table_management_service.rb +192 -0
- data/app/views/dbdoc_engine/admin/dashboard/_action_badge.html.erb +11 -0
- data/app/views/dbdoc_engine/admin/dashboard/_changelog_rows.html.erb +22 -0
- data/app/views/dbdoc_engine/admin/dashboard/_changelog_table_headers.html.erb +8 -0
- data/app/views/dbdoc_engine/admin/dashboard/_filter_fields.html.erb +43 -0
- data/app/views/dbdoc_engine/admin/dashboard/index.html.erb +159 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_column_fields.html.erb +225 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_deleted_table_index.html.erb +110 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_foreign_key_fields.html.erb +51 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_form.html.erb +75 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_recent_activity.html.erb +39 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_table_columns.html.erb +127 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_table_index.html.erb +109 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/_table_information.html.erb +99 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/deleted_tables.html.erb +95 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/edit.html.erb +23 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/export_all_to_excel.xlsx.axlsx +240 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/export_to_excel.xlsx.axlsx +135 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/index.html.erb +109 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/new.html.erb +25 -0
- data/app/views/dbdoc_engine/admin/db_design_dynamic_tables/show_table_info.html.erb +125 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/_deleted_table_groups_list.html.erb +75 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/_form.html.erb +88 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/_table_groups_list.html.erb +82 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/deleted_groups.html.erb +60 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/edit.html.erb +25 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/index.html.erb +85 -0
- data/app/views/dbdoc_engine/admin/db_design_table_groups/new.html.erb +26 -0
- data/app/views/dbdoc_engine/db_doc_sessions/new.html.erb +59 -0
- data/app/views/dbdoc_engine/home/changelog_details.html.erb +80 -0
- data/app/views/dbdoc_engine/home/changelogs.html.erb +20 -0
- data/app/views/dbdoc_engine/home/group_details.html.erb +94 -0
- data/app/views/dbdoc_engine/home/index.html.erb +11 -0
- data/app/views/dbdoc_engine/home/partials/_action_badge.html.erb +11 -0
- data/app/views/dbdoc_engine/home/partials/_breadcrumb_navigation.html.erb +30 -0
- data/app/views/dbdoc_engine/home/partials/_changelog_rows.html.erb +35 -0
- data/app/views/dbdoc_engine/home/partials/_changelog_table_headers.html.erb +16 -0
- data/app/views/dbdoc_engine/home/partials/_column_headers.html.erb +23 -0
- data/app/views/dbdoc_engine/home/partials/_column_row.html.erb +157 -0
- data/app/views/dbdoc_engine/home/partials/_filter_form.html.erb +47 -0
- data/app/views/dbdoc_engine/home/partials/_group_section.html.erb +84 -0
- data/app/views/dbdoc_engine/home/partials/_pagination.html.erb +5 -0
- data/app/views/dbdoc_engine/home/partials/_stats_container.html.erb +46 -0
- data/app/views/dbdoc_engine/home/partials/_table_groups.html.erb +7 -0
- data/app/views/dbdoc_engine/home/partials/_table_information_section.html.erb +50 -0
- data/app/views/dbdoc_engine/home/partials/_table_section.html.erb +48 -0
- data/app/views/dbdoc_engine/home/table_details.html.erb +9 -0
- data/app/views/dbdoc_engine/schema_diagram/index.html.erb +102 -0
- data/app/views/dbdoc_engine/shared/_admin_header.html.erb +78 -0
- data/app/views/dbdoc_engine/shared/_header.html.erb +94 -0
- data/app/views/dbdoc_engine/shared/_js_translations.html.erb +3 -0
- data/app/views/dbdoc_engine/shared/_language_button.html.erb +14 -0
- data/app/views/dbdoc_engine/shared/_sidebar.html.erb +128 -0
- data/app/views/kaminari/dbdoc_engine/_first_page.html.erb +3 -0
- data/app/views/kaminari/dbdoc_engine/_gap.html.erb +3 -0
- data/app/views/kaminari/dbdoc_engine/_last_page.html.erb +3 -0
- data/app/views/kaminari/dbdoc_engine/_next_page.html.erb +3 -0
- data/app/views/kaminari/dbdoc_engine/_page.html.erb +9 -0
- data/app/views/kaminari/dbdoc_engine/_paginator.html.erb +17 -0
- data/app/views/kaminari/dbdoc_engine/_prev_page.html.erb +3 -0
- data/app/views/layouts/dbdoc_engine/application.html.erb +107 -0
- data/app/views/layouts/dbdoc_engine/header.html.erb +108 -0
- data/config/importmap.rb +11 -0
- data/config/locales/en.yml +307 -0
- data/config/locales/ja.yml +306 -0
- data/config/routes.rb +73 -0
- data/db/migrate/rails7/20250227060610_create_db_design_table_groups.rb +15 -0
- data/db/migrate/rails7/20250227094626_create_db_design_dynamic_tables.rb +19 -0
- data/db/migrate/rails7/20250228022732_create_db_design_dynamic_columns.rb +34 -0
- data/db/migrate/rails7/20250401051453_create_db_design_changelogs.rb +26 -0
- data/db/migrate/rails7/20250411040822_create_users.rb +14 -0
- data/db/migrate/rails7/20250421080851_add_missing_indexes_to_dbdoc_tables.rb +23 -0
- data/db/migrate/rails8/20250227060610_create_db_design_table_groups.rb +15 -0
- data/db/migrate/rails8/20250227094626_create_db_design_dynamic_tables.rb +19 -0
- data/db/migrate/rails8/20250228022732_create_db_design_dynamic_columns.rb +34 -0
- data/db/migrate/rails8/20250401051453_create_db_design_changelogs.rb +26 -0
- data/db/migrate/rails8/20250411040822_create_users.rb +14 -0
- data/db/migrate/rails8/20250421080851_add_missing_indexes_to_dbdoc_tables.rb +23 -0
- data/db/seeds.rb +28 -0
- data/lib/dbdoc_engine/engine.rb +57 -0
- data/lib/dbdoc_engine/version.rb +3 -0
- data/lib/dbdoc_engine.rb +9 -0
- data/lib/generators/dbdoc_engine/install/install_generator.rb +245 -0
- data/lib/generators/dbdoc_engine/uninstall/uninstall_generator.rb +196 -0
- data/lib/tasks/dbdoc_engine_tasks.rake +44 -0
- data/public/dbdoc_engine_assets/images/camel_chess_head.png +0 -0
- data/public/dbdoc_engine_assets/images/dblogo.svg +4 -0
- data/public/dbdoc_engine_assets/images/japan_circle.png +0 -0
- data/public/dbdoc_engine_assets/images/king_chess_head.png +0 -0
- data/public/dbdoc_engine_assets/images/login-bg.svg +44 -0
- data/public/dbdoc_engine_assets/images/logo.png +0 -0
- data/public/dbdoc_engine_assets/images/logo.svg +12 -0
- data/public/dbdoc_engine_assets/images/queen_chess_head.png +0 -0
- data/public/dbdoc_engine_assets/images/soldier_chess_headd.png +0 -0
- data/public/dbdoc_engine_assets/images/uk_circle_transparent.png +0 -0
- metadata +415 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# Service for table groups controller
|
|
2
|
+
module DbdocEngine
|
|
3
|
+
class TableGroupsService
|
|
4
|
+
def initialize(params)
|
|
5
|
+
@params = params
|
|
6
|
+
@errors = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Fetch table groups with optional search and soft-delete filters
|
|
10
|
+
def fetch_table_groups
|
|
11
|
+
showing_deleted = @params[:show_deleted] == "true"
|
|
12
|
+
query = DbdocEngine::DbDesignTableGroupQueries.search_all_groups(@params[:search], showing_deleted)
|
|
13
|
+
[ query.page(@params[:page]).per(6), showing_deleted ]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Fetch only soft-deleted table groups
|
|
17
|
+
def fetch_deleted_groups
|
|
18
|
+
query = DbdocEngine::DbDesignTableGroupQueries.search_deleted_groups(@params[:search])
|
|
19
|
+
query.page(@params[:page]).per(5)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Create a new table group
|
|
23
|
+
def create_group
|
|
24
|
+
table_group = DbdocEngine::DbDesignTableGroupQueries.create_table_group(table_group_params)
|
|
25
|
+
if table_group.persisted?
|
|
26
|
+
{ success: true, message: I18n.t("dbdoc.group_creation") }
|
|
27
|
+
else
|
|
28
|
+
{ success: false, errors: table_group.errors.full_messages, table_group: table_group }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Update an existing table group
|
|
33
|
+
def update_group(table_group)
|
|
34
|
+
if DbdocEngine::DbDesignTableGroupQueries.update_table_group(table_group, table_group_params)
|
|
35
|
+
{ success: true, message: I18n.t("dbdoc.group_updation") }
|
|
36
|
+
else
|
|
37
|
+
{ success: false, errors: table_group.errors.full_messages, table_group: table_group }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Soft delete a table group
|
|
42
|
+
def delete_group(table_group)
|
|
43
|
+
# Check if the group has any active tables
|
|
44
|
+
if DbdocEngine::DbDesignDynamicTableQueries.group_has_active_tables?(table_group.id, false)
|
|
45
|
+
add_error(I18n.t("dbdoc.group_delete_validation"))
|
|
46
|
+
return failure_result
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Store original name before changing it
|
|
50
|
+
original_name = table_group.group_name
|
|
51
|
+
|
|
52
|
+
# Append ID to the group name for soft deletion
|
|
53
|
+
new_name = "#{original_name}_deleted_#{table_group.id}"
|
|
54
|
+
|
|
55
|
+
# Update the group name before soft deletion
|
|
56
|
+
table_group.group_name = new_name
|
|
57
|
+
|
|
58
|
+
if table_group.soft_delete
|
|
59
|
+
# Log the soft deletion to changelog
|
|
60
|
+
DbdocEngine::DbDesignChangelogQueries.log_change(
|
|
61
|
+
DbDesignChangelog::ACTION_DELETE,
|
|
62
|
+
DbDesignChangelog::ENTITY_TABLE_GROUP,
|
|
63
|
+
original_name,
|
|
64
|
+
"Soft deleted table group '#{original_name}'",
|
|
65
|
+
table_group.updated_by,
|
|
66
|
+
{
|
|
67
|
+
group_name: original_name,
|
|
68
|
+
group_color: table_group.group_color,
|
|
69
|
+
deleted: true
|
|
70
|
+
},
|
|
71
|
+
nil
|
|
72
|
+
)
|
|
73
|
+
{ success: true, message: I18n.t("dbdoc.group_deletion") }
|
|
74
|
+
else
|
|
75
|
+
add_error("Unable to delete table group.")
|
|
76
|
+
failure_result
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Restore a soft-deleted table group
|
|
81
|
+
def restore_group(table_group)
|
|
82
|
+
# Extract the original name from the current name
|
|
83
|
+
original_name = extract_original_name(table_group.group_name)
|
|
84
|
+
|
|
85
|
+
# Check if another group with the same name exists
|
|
86
|
+
if DbdocEngine::DbDesignTableGroupQueries.group_exists?(original_name)
|
|
87
|
+
add_error(I18n.t("dbdoc.group_restore_validation"))
|
|
88
|
+
return failure_result
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Restore the original name
|
|
92
|
+
table_group.group_name = original_name
|
|
93
|
+
|
|
94
|
+
# Use query class for restoration
|
|
95
|
+
if DbdocEngine::DbDesignTableGroupQueries.restore(table_group)
|
|
96
|
+
# Use query class for logging
|
|
97
|
+
DbdocEngine::DbDesignChangelogQueries.log_change(
|
|
98
|
+
DbDesignChangelog::ACTION_UPDATE,
|
|
99
|
+
DbDesignChangelog::ENTITY_TABLE_GROUP,
|
|
100
|
+
original_name,
|
|
101
|
+
"Restored deleted table group '#{original_name}'",
|
|
102
|
+
"Super Admin",
|
|
103
|
+
{ deleted: true, group_name: table_group.group_name },
|
|
104
|
+
{ deleted: false, group_name: original_name }
|
|
105
|
+
)
|
|
106
|
+
message = I18n.t("dbdoc.success.group_restored", original_name: original_name)
|
|
107
|
+
{ success: true, message: message }
|
|
108
|
+
else
|
|
109
|
+
add_error("Unable to restore group '#{original_name}'.")
|
|
110
|
+
failure_result
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Permanently delete a table group
|
|
115
|
+
def permanent_delete_group(table_group)
|
|
116
|
+
# Check if the group has any associated tables (including soft-deleted ones)
|
|
117
|
+
if DbdocEngine::DbDesignDynamicTableQueries.group_has_active_tables?(table_group.id, true)
|
|
118
|
+
add_error(I18n.t("dbdoc.group_permanent_delete_validation"))
|
|
119
|
+
return failure_result
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Extract the original name from the current name
|
|
123
|
+
original_name = extract_original_name(table_group.group_name)
|
|
124
|
+
|
|
125
|
+
# Store table group info before destruction for logging
|
|
126
|
+
group_info = {
|
|
127
|
+
group_name: original_name,
|
|
128
|
+
group_color: table_group.group_color,
|
|
129
|
+
permanently_deleted: true
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
# Use query class for permanent deletion
|
|
133
|
+
if DbdocEngine::DbDesignTableGroupQueries.permanent_delete(table_group)
|
|
134
|
+
# Use query class for logging
|
|
135
|
+
DbdocEngine::DbDesignChangelogQueries.log_change(
|
|
136
|
+
DbDesignChangelog::ACTION_DELETE,
|
|
137
|
+
DbDesignChangelog::ENTITY_TABLE_GROUP,
|
|
138
|
+
original_name,
|
|
139
|
+
"Permanently deleted table group '#{original_name}'",
|
|
140
|
+
"Super Admin",
|
|
141
|
+
group_info,
|
|
142
|
+
nil
|
|
143
|
+
)
|
|
144
|
+
message = I18n.t("dbdoc.success.table_group_permanently_deleted", original_name: original_name)
|
|
145
|
+
{ success: true, message: message }
|
|
146
|
+
else
|
|
147
|
+
add_error("Unable to permanently delete table group '#{original_name}'.")
|
|
148
|
+
failure_result
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Get existing group names, excluding the current one being edited
|
|
153
|
+
def existing_group_names
|
|
154
|
+
DbdocEngine::DbDesignTableGroupQueries.group_names_except(@params[:id])
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
# Extract the original group name from a deleted group name
|
|
160
|
+
def extract_original_name(deleted_name)
|
|
161
|
+
# Pattern for names like "original_name_deleted_123"
|
|
162
|
+
if deleted_name =~ /(.+)_deleted_\d+$/
|
|
163
|
+
::Regexp.last_match(1) # Return the captured group (everything before "_deleted_")
|
|
164
|
+
else
|
|
165
|
+
deleted_name # If pattern doesn't match, return the name as is
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Check if there's already a group with the given name
|
|
170
|
+
def name_conflict?(group_name)
|
|
171
|
+
DbdocEngine::DbDesignTableGroupQueries.group_exists?(group_name)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Strong parameters
|
|
175
|
+
def table_group_params
|
|
176
|
+
@params.require(:db_design_table_group).permit(:group_name, :group_color, :created_by, :updated_by)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def associated_tables?(table_group, include_deleted = false)
|
|
180
|
+
DbdocEngine::DbDesignDynamicTableQueries.group_has_active_tables?(table_group.id, include_deleted)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Adds an error message to the errors array
|
|
184
|
+
def add_error(message)
|
|
185
|
+
@errors ||= []
|
|
186
|
+
@errors << message
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Returns a success result
|
|
190
|
+
def success_result
|
|
191
|
+
{ success: true }
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Returns a failure result with errors
|
|
195
|
+
def failure_result
|
|
196
|
+
{ success: false, errors: @errors }
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Service for managing table lifecycle operations
|
|
2
|
+
module DbdocEngine
|
|
3
|
+
class TableManagementService
|
|
4
|
+
attr_reader :table, :errors
|
|
5
|
+
|
|
6
|
+
def initialize(table)
|
|
7
|
+
@table = table
|
|
8
|
+
@errors = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Soft deletes a table if it's not referenced by other tables
|
|
12
|
+
def soft_delete
|
|
13
|
+
if foreign_key_dependencies?
|
|
14
|
+
add_error(I18n.t("dbdoc.errors.messages.cannot_delete_referenced_table", table_name: table.table_name))
|
|
15
|
+
return failure_result
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Store original name before changing it
|
|
19
|
+
original_name = table.table_name
|
|
20
|
+
|
|
21
|
+
# Append ID to the table name for soft deletion
|
|
22
|
+
new_name = "#{original_name}_deleted_#{table.id}"
|
|
23
|
+
|
|
24
|
+
if table.update(table_name: new_name, deleted_at: Time.current)
|
|
25
|
+
# Log the soft deletion to changelog
|
|
26
|
+
DbDesignChangelog.log_change(
|
|
27
|
+
DbDesignChangelog::ACTION_DELETE,
|
|
28
|
+
DbDesignChangelog::ENTITY_TABLE,
|
|
29
|
+
original_name,
|
|
30
|
+
"Soft deleted table '#{original_name}'",
|
|
31
|
+
table.updated_by,
|
|
32
|
+
{
|
|
33
|
+
table_name: original_name,
|
|
34
|
+
group_id: table.db_design_table_group_id,
|
|
35
|
+
description: table.description,
|
|
36
|
+
deleted: true
|
|
37
|
+
},
|
|
38
|
+
nil
|
|
39
|
+
)
|
|
40
|
+
success_result
|
|
41
|
+
else
|
|
42
|
+
add_error("Unable to delete table '#{original_name}'.")
|
|
43
|
+
failure_result
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Permanently removes a table from the database
|
|
48
|
+
def permanent_destroy
|
|
49
|
+
# Extract original table name from the current name
|
|
50
|
+
original_name = extract_original_name(table.table_name)
|
|
51
|
+
|
|
52
|
+
table_info = {
|
|
53
|
+
table_name: original_name,
|
|
54
|
+
group_id: table.db_design_table_group_id,
|
|
55
|
+
description: table.description,
|
|
56
|
+
permanently_deleted: true
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if table.destroy
|
|
60
|
+
# Log the permanent deletion to changelog
|
|
61
|
+
DbDesignChangelog.log_change(
|
|
62
|
+
DbDesignChangelog::ACTION_DELETE,
|
|
63
|
+
DbDesignChangelog::ENTITY_TABLE,
|
|
64
|
+
original_name,
|
|
65
|
+
"Permanently deleted table '#{original_name}'",
|
|
66
|
+
"Super Admin",
|
|
67
|
+
table_info,
|
|
68
|
+
nil
|
|
69
|
+
)
|
|
70
|
+
success_result
|
|
71
|
+
else
|
|
72
|
+
add_error("Unable to permanently delete table '#{original_name}'.")
|
|
73
|
+
failure_result
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Restores a soft-deleted table
|
|
78
|
+
def restore
|
|
79
|
+
# Extract the original name from the current name
|
|
80
|
+
original_name = extract_original_name(table.table_name)
|
|
81
|
+
|
|
82
|
+
# Check if another table with the same name exists
|
|
83
|
+
if name_conflict?(original_name)
|
|
84
|
+
add_error(I18n.t("dbdoc.errors.messages.unable_to_restore_table_duplicate", original_name: original_name))
|
|
85
|
+
return failure_result
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Check if the table's group is soft-deleted
|
|
89
|
+
if table_group_is_deleted?
|
|
90
|
+
group_name = get_table_group_name
|
|
91
|
+
add_error(I18n.t("dbdoc.errors.messages.cannot_restore_table_deleted_group",
|
|
92
|
+
table_name: original_name,
|
|
93
|
+
group_name: group_name))
|
|
94
|
+
return failure_result
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
if table.update(table_name: original_name, deleted_at: nil)
|
|
98
|
+
# Log the restoration to changelog
|
|
99
|
+
DbDesignChangelog.log_change(
|
|
100
|
+
DbDesignChangelog::ACTION_UPDATE,
|
|
101
|
+
DbDesignChangelog::ENTITY_TABLE,
|
|
102
|
+
original_name,
|
|
103
|
+
"Restored deleted table '#{original_name}'",
|
|
104
|
+
"Super Admin",
|
|
105
|
+
{ deleted: true },
|
|
106
|
+
{ deleted: false }
|
|
107
|
+
)
|
|
108
|
+
success_result
|
|
109
|
+
else
|
|
110
|
+
add_error("Unable to restore table '#{original_name}'.")
|
|
111
|
+
failure_result
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
# Extract the original table name from a deleted table name
|
|
118
|
+
def extract_original_name(deleted_name)
|
|
119
|
+
# Pattern for names like "original_name_deleted_123"
|
|
120
|
+
if deleted_name =~ /(.+)_deleted_\d+$/
|
|
121
|
+
::Regexp.last_match(1) # Return the captured group (everything before "_deleted_")
|
|
122
|
+
else
|
|
123
|
+
deleted_name # If pattern doesn't match, return the name as is
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Checks if any other table has a foreign key reference to this table
|
|
128
|
+
def foreign_key_dependencies?
|
|
129
|
+
# Check if any active (non-deleted) tables reference this table
|
|
130
|
+
DbDesignDynamicColumn
|
|
131
|
+
.joins(:db_design_dynamic_table)
|
|
132
|
+
.where(foreign_table_name: table.table_name)
|
|
133
|
+
.where(db_design_dynamic_tables: { deleted_at: nil })
|
|
134
|
+
.exists?
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Check if there's already a table with the given name
|
|
138
|
+
def name_conflict?(table_name)
|
|
139
|
+
DbDesignDynamicTable
|
|
140
|
+
.without_deleted
|
|
141
|
+
.where(table_name: table_name)
|
|
142
|
+
.where.not(id: table.id)
|
|
143
|
+
.exists?
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Check if the table's group is soft-deleted
|
|
147
|
+
def table_group_is_deleted?
|
|
148
|
+
return false if table.db_design_table_group_id.blank?
|
|
149
|
+
|
|
150
|
+
group = DbdocEngine::DbDesignTableGroup.with_deleted.find_by(id: table.db_design_table_group_id)
|
|
151
|
+
group&.deleted_at.present?
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Get the table group name (including soft-deleted groups)
|
|
155
|
+
def get_table_group_name
|
|
156
|
+
return "Unknown Group" if table.db_design_table_group_id.blank?
|
|
157
|
+
|
|
158
|
+
group = DbdocEngine::DbDesignTableGroup.with_deleted.find_by(id: table.db_design_table_group_id)
|
|
159
|
+
if group
|
|
160
|
+
# Extract original name if it's a deleted group name
|
|
161
|
+
extract_original_group_name(group.group_name)
|
|
162
|
+
else
|
|
163
|
+
"Unknown Group"
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Extract the original group name from a deleted group name
|
|
168
|
+
def extract_original_group_name(deleted_name)
|
|
169
|
+
# Pattern for names like "original_name_deleted_123"
|
|
170
|
+
if deleted_name =~ /(.+)_deleted_\d+$/
|
|
171
|
+
::Regexp.last_match(1) # Return the captured group (everything before "_deleted_")
|
|
172
|
+
else
|
|
173
|
+
deleted_name # If pattern doesn't match, return the name as is
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Adds an error message to the errors array
|
|
178
|
+
def add_error(message)
|
|
179
|
+
@errors << message
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Returns a success result
|
|
183
|
+
def success_result
|
|
184
|
+
{ success: true }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Returns a failure result with errors
|
|
188
|
+
def failure_result
|
|
189
|
+
{ success: false, errors: @errors }
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<% case action_type %>
|
|
2
|
+
<% when 'create' %>
|
|
3
|
+
<!-- Display a green badge when the action type is 'create' -->
|
|
4
|
+
<span class="badge bg-success"><%= t('dbdoc.create') %></span>
|
|
5
|
+
<% when 'update' %>
|
|
6
|
+
<!-- Display a yellow badge when the action type is 'update' -->
|
|
7
|
+
<span class="badge bg-warning text-dark"><%= t('dbdoc.update') %></span>
|
|
8
|
+
<% when 'delete' %>
|
|
9
|
+
<!-- Display a red badge when the action type is 'delete' -->
|
|
10
|
+
<span class="badge bg-danger"><%= t('dbdoc.delete') %></span>
|
|
11
|
+
<% end %>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<% if changelogs.any? %>
|
|
2
|
+
<!-- Check if there are any changelog records -->
|
|
3
|
+
<% changelogs.each do |log| %>
|
|
4
|
+
<!-- Iterate over each changelog entry -->
|
|
5
|
+
<tr>
|
|
6
|
+
<!-- Display the timestamp of the change, formatted as 'YYYY-MM-DD HH:MM:SS' -->
|
|
7
|
+
<td class='contents-changelog'><%= log.change_timestamp.strftime('%Y-%m-%d %H:%M:%S') %></td>
|
|
8
|
+
<td>
|
|
9
|
+
<!-- Render a partial to display an action badge based on the action type -->
|
|
10
|
+
<%= render 'dbdoc_engine/admin/dashboard/action_badge', action_type: log.action_type %>
|
|
11
|
+
</td>
|
|
12
|
+
<!-- Display the change description with a max width of 250px and text truncation -->
|
|
13
|
+
<td class='contents-changelog'><%= log.changed_by %> <%= log.description %></td>
|
|
14
|
+
<!-- Display the name of the user who made the change -->
|
|
15
|
+
</tr>
|
|
16
|
+
<% end %>
|
|
17
|
+
<% else %>
|
|
18
|
+
<!-- If no changelogs exist, display a message -->
|
|
19
|
+
<tr>
|
|
20
|
+
<td colspan='7' class='text-center text-muted'>No changes found matching your criteria.</td>
|
|
21
|
+
</tr>
|
|
22
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<tr>
|
|
2
|
+
<!-- Table header for the date and time of the change -->
|
|
3
|
+
<th class='text-custom-secondary changelog-headers-1'><%= t('dbdoc.date_and_time') %></th>
|
|
4
|
+
<!-- Table header for the type of action performed (e.g., create, update, delete) -->
|
|
5
|
+
<th class='text-custom-secondary changelog-headers-2'><%= t('dbdoc.action') %></th>
|
|
6
|
+
<!-- Table header for a brief description of the change made -->
|
|
7
|
+
<th class='text-custom-secondary'><%= t('dbdoc.description') %></th>
|
|
8
|
+
</tr>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!-- Action Type Dropdown Filter -->
|
|
2
|
+
<div class='col-md-3'>
|
|
3
|
+
<div class='input-group'>
|
|
4
|
+
<!-- Icon for action type -->
|
|
5
|
+
<span class='input-group-text'><i class='bi bi-gear'></i></span>
|
|
6
|
+
<!-- Dropdown for selecting action type (create, update, delete, etc.) -->
|
|
7
|
+
<%= f.select :action_type, action_type_options,
|
|
8
|
+
{ selected: params[:action_type] },
|
|
9
|
+
class: 'form-select salect' %>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<!-- Date From Filter -->
|
|
14
|
+
<div class='col-md-3'>
|
|
15
|
+
<div class='input-group'>
|
|
16
|
+
<!-- Icon for date from -->
|
|
17
|
+
<span class='input-group-text'><i class='bi bi-calendar'></i></span>
|
|
18
|
+
<!-- Date picker for start date filter -->
|
|
19
|
+
<%= f.date_field :date_from, value: params[:date_from],
|
|
20
|
+
class: 'form-control cantrol', placeholder: 'From Date' %>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<!-- Date To Filter -->
|
|
25
|
+
<div class='col-md-3'>
|
|
26
|
+
<div class='input-group'>
|
|
27
|
+
<!-- Icon for date to -->
|
|
28
|
+
<span class='input-group-text'><i class='bi bi-calendar'></i></span>
|
|
29
|
+
<!-- Date picker for end date filter -->
|
|
30
|
+
<%= f.date_field :date_to, value: params[:date_to],
|
|
31
|
+
class: 'form-control cantrol', placeholder: 'To Date' %>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<!-- Filter Action Buttons -->
|
|
36
|
+
<div class='col-md-12 mt-3'>
|
|
37
|
+
<div class='d-flex gap-2'>
|
|
38
|
+
<!-- Button to apply filters -->
|
|
39
|
+
<%= f.submit 'Apply Filters', class: 'btn applybutton' %>
|
|
40
|
+
<!-- Button to clear filters and reset the form -->
|
|
41
|
+
<%= link_to 'Clear Filters', dbdoc_engine.admin_dashboard_path, class: 'btn clear-button' %>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<%# Dashboard %>
|
|
2
|
+
<div class='dashboard-container'>
|
|
3
|
+
<div class="d-flex align-items-center justify-content-between mb-4">
|
|
4
|
+
<h1 class='fw-bold dashboard-title mb-0'><%= t('dbdoc.dashboard') %></h1>
|
|
5
|
+
<span class="text-muted" style="font-size:13px;"><%= Time.current.strftime("%A, %B %d, %Y") %></span>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<%# Top Stats Row %>
|
|
9
|
+
<div class='dashboard-stats-row'>
|
|
10
|
+
<div class='stat-card stat-profile'>
|
|
11
|
+
<div class='stat-icon-wrap stat-icon-profile'>
|
|
12
|
+
<% if current_user.role == 'superadmin' %>
|
|
13
|
+
<img src='/dbdoc_engine_assets/images/king_chess_head.png' alt='Superadmin' class='stat-avatar' />
|
|
14
|
+
<% elsif current_user.role == 'admin' %>
|
|
15
|
+
<img src='/dbdoc_engine_assets/images/queen_chess_head.png' alt='Admin' class='stat-avatar' />
|
|
16
|
+
<% else %>
|
|
17
|
+
<img src='/dbdoc_engine_assets/images/camel_chess_head.png' alt='User' class='stat-avatar' />
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
<div class='stat-info'>
|
|
21
|
+
<span class='stat-label'><%= t('dbdoc.accountprofile') %></span>
|
|
22
|
+
<span class='stat-value stat-value-sm'>
|
|
23
|
+
<%= case current_user.role
|
|
24
|
+
when 'superadmin' then t('dbdoc.superadmin')
|
|
25
|
+
when 'admin' then t('dbdoc.admin')
|
|
26
|
+
else t('dbdoc.user')
|
|
27
|
+
end %>
|
|
28
|
+
</span>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class='stat-card'>
|
|
33
|
+
<div class='stat-icon-wrap stat-icon-groups'><i class="bi bi-collection"></i></div>
|
|
34
|
+
<div class='stat-info'>
|
|
35
|
+
<span class='stat-label'><%= t('dbdoc.groupsdash') %></span>
|
|
36
|
+
<span class='stat-value'><%= @groups_count %></span>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<div class='stat-card'>
|
|
41
|
+
<div class='stat-icon-wrap stat-icon-tables'><i class="bi bi-table"></i></div>
|
|
42
|
+
<div class='stat-info'>
|
|
43
|
+
<span class='stat-label'><%= t('dbdoc.tablesdash') %></span>
|
|
44
|
+
<span class='stat-value'><%= @tables_count %></span>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div class='stat-card'>
|
|
49
|
+
<div class='stat-icon-wrap stat-icon-columns'><i class="bi bi-layout-three-columns"></i></div>
|
|
50
|
+
<div class='stat-info'>
|
|
51
|
+
<span class='stat-label'><%= t('dbdoc.columnsdash') %></span>
|
|
52
|
+
<span class='stat-value'><%= @columns_count %></span>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<%# Action Cards Row %>
|
|
58
|
+
<div class='dashboard-action-row'>
|
|
59
|
+
<%= link_to dbdoc_engine.export_all_to_excel_admin_db_design_dynamic_tables_path(format: :xlsx),
|
|
60
|
+
target: '_blank', data: { turbo: false }, class: 'action-card action-card-excel text-decoration-none' do %>
|
|
61
|
+
<div class='action-card-icon'><i class="bi bi-file-earmark-spreadsheet"></i></div>
|
|
62
|
+
<div class='action-card-body'>
|
|
63
|
+
<span class='action-card-title'><%= t('dbdoc.downloadexceldash') %></span>
|
|
64
|
+
<span class='action-card-sub'><%= t('dbdoc.alltables') %></span>
|
|
65
|
+
</div>
|
|
66
|
+
<% end %>
|
|
67
|
+
|
|
68
|
+
<div class="action-card" data-controller="import-export" data-import-export-base-path-value="<%= dbdoc_engine.root_path.chomp('/') %>">
|
|
69
|
+
<div class='action-card-icon action-icon-json'><i class="bi bi-filetype-json"></i></div>
|
|
70
|
+
<div class='action-card-body'>
|
|
71
|
+
<span class='action-card-title'><%= t('dbdoc.export_import') %></span>
|
|
72
|
+
<div class='d-flex gap-2 mt-1'>
|
|
73
|
+
<button data-action="click->import-export#export" class="btn btn-sm action-btn action-btn-export" type="button">
|
|
74
|
+
<i class="bi bi-box-arrow-up me-1"></i><%= t('dbdoc.export') %>
|
|
75
|
+
</button>
|
|
76
|
+
<button data-action="click->import-export#showImport" class="btn btn-sm action-btn action-btn-import" type="button">
|
|
77
|
+
<i class="bi bi-box-arrow-in-down me-1"></i><%= t('dbdoc.import') %>
|
|
78
|
+
</button>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<div data-import-export-target="dropZone"
|
|
82
|
+
data-action="dragover->import-export#handleDragOver dragleave->import-export#handleDragLeave drop->import-export#handleDrop"
|
|
83
|
+
class="drop-zone">
|
|
84
|
+
<p class="mb-1"><i class="bi bi-cloud-arrow-up me-1"></i><%= t('dbdoc.drop_file_here') %>
|
|
85
|
+
<label for="import-json-file" class="drop-zone-link"><%= t('dbdoc.click_to_select') %></label>
|
|
86
|
+
</p>
|
|
87
|
+
<input type="file" id="import-json-file" data-import-export-target="fileInput" accept=".json" style="display:none;" data-action="change->import-export#handleFileChange">
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
<div class="action-card" data-controller="import-export" data-import-export-base-path-value="<%= dbdoc_engine.root_path.chomp('/') %>">
|
|
92
|
+
<div class='action-card-icon action-icon-schema'><i class="bi bi-database-gear"></i></div>
|
|
93
|
+
<div class='action-card-body'>
|
|
94
|
+
<span class='action-card-title'><%= t('dbdoc.import_schema') %></span>
|
|
95
|
+
<div class='d-flex gap-2 mt-1'>
|
|
96
|
+
<button data-action="click->import-export#importProjectSchema" class="btn btn-sm action-btn action-btn-schema" type="button">
|
|
97
|
+
<i class="bi bi-database-down me-1"></i><%= t('dbdoc.import_project_schema') %>
|
|
98
|
+
</button>
|
|
99
|
+
<button data-action="click->import-export#showSchemaUpload" class="btn btn-sm action-btn action-btn-upload" type="button">
|
|
100
|
+
<i class="bi bi-upload me-1"></i><%= t('dbdoc.upload_schema_file') %>
|
|
101
|
+
</button>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
<div data-import-export-target="schemaDropZone"
|
|
105
|
+
data-action="dragover->import-export#handleDragOver dragleave->import-export#handleDragLeave drop->import-export#handleSchemaDrop"
|
|
106
|
+
class="drop-zone">
|
|
107
|
+
<p class="mb-1"><i class="bi bi-cloud-arrow-up me-1"></i><%= t('dbdoc.drop_schema_here') %>
|
|
108
|
+
<label for="import-schema-file" class="drop-zone-link"><%= t('dbdoc.click_to_select') %></label>
|
|
109
|
+
</p>
|
|
110
|
+
<input type="file" id="import-schema-file" data-import-export-target="schemaFileInput" accept=".rb" style="display:none;" data-action="change->import-export#handleSchemaFileChange">
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
|
|
115
|
+
<%# Main Content: Activity + Chart %>
|
|
116
|
+
<div class='dashboard-main-row'>
|
|
117
|
+
<div class='dashboard-table-section'>
|
|
118
|
+
<div class='d-flex align-items-center justify-content-between mb-3'>
|
|
119
|
+
<div class='dashboard-section-title mb-0'><i class="bi bi-clock-history me-2"></i><%= t('dbdoc.recentactivity') %></div>
|
|
120
|
+
<div class='filter-buttons'>
|
|
121
|
+
<%= link_to t('dbdoc.allactions'), dbdoc_engine.admin_dashboard_path,
|
|
122
|
+
class: "filter-button #{'active' unless params[:action_type]}",
|
|
123
|
+
data: { turbo_action: 'replace' } %>
|
|
124
|
+
<%= link_to t('dbdoc.create'), dbdoc_engine.admin_dashboard_path(action_type: 'create'),
|
|
125
|
+
class: "filter-button #{'active' if params[:action_type] == 'create'}",
|
|
126
|
+
data: { turbo_action: 'replace' } %>
|
|
127
|
+
<%= link_to t('dbdoc.update'), dbdoc_engine.admin_dashboard_path(action_type: 'update'),
|
|
128
|
+
class: "filter-button #{'active' if params[:action_type] == 'update'}",
|
|
129
|
+
data: { turbo_action: 'replace' } %>
|
|
130
|
+
<%= link_to t('dbdoc.delete'), dbdoc_engine.admin_dashboard_path(action_type: 'delete'),
|
|
131
|
+
class: "filter-button #{'active' if params[:action_type] == 'delete'}",
|
|
132
|
+
data: { turbo_action: 'replace' } %>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<div class='table-responsive dashboard_table_scroll'>
|
|
137
|
+
<table class='table table-hover mb-0'>
|
|
138
|
+
<thead class='sticky-top dashboard_table_header'>
|
|
139
|
+
<%= render partial: 'dbdoc_engine/admin/dashboard/changelog_table_headers' %>
|
|
140
|
+
</thead>
|
|
141
|
+
<tbody>
|
|
142
|
+
<%= render partial: 'dbdoc_engine/admin/dashboard/changelog_rows', locals: { changelogs: @changelogs } %>
|
|
143
|
+
</tbody>
|
|
144
|
+
</table>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div class='dashboard-chart-section'>
|
|
149
|
+
<div class='dashboard-section-title mb-3'><i class="bi bi-bar-chart-line me-2"></i><%= t('dbdoc.actionoverview') %></div>
|
|
150
|
+
<div class='dashboard-chart-wrap'>
|
|
151
|
+
<canvas
|
|
152
|
+
id='actionBarChart'
|
|
153
|
+
data-controller='chart'
|
|
154
|
+
data-chart-data-value='<%= @chart_data.to_json %>'>
|
|
155
|
+
</canvas>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|