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,225 @@
|
|
|
1
|
+
<%# This partial displays a column entry in the table design It uses accordion pattern to show/hide column details Each column can be configured with data type, constraints, and relationships %>
|
|
2
|
+
<div class='column-fields mb-4'
|
|
3
|
+
data-controller='column-type column'
|
|
4
|
+
data-column-type-target='columnFields'
|
|
5
|
+
data-table-id='<%= f.object.db_design_dynamic_table_id || table&.id %>'>
|
|
6
|
+
|
|
7
|
+
<!-- Single Accordion Container -->
|
|
8
|
+
<div class='accordion'>
|
|
9
|
+
<div class='accordion-item' data-controller="dbdoc-accordion">
|
|
10
|
+
<h2 class='accordion-header'>
|
|
11
|
+
<% accordion_id = "column-#{f.object.id || "new-#{SecureRandom.hex(4)}"}" %>
|
|
12
|
+
<button class='accordion-button collapsed'
|
|
13
|
+
type='button'
|
|
14
|
+
data-action='click->dbdoc-accordion#toggle'
|
|
15
|
+
data-dbdoc-accordion-target="button"
|
|
16
|
+
aria-expanded='false'
|
|
17
|
+
aria-controls='<%= accordion_id %>'>
|
|
18
|
+
<% if f.object.column_name.present? %>
|
|
19
|
+
<strong><%= f.object.column_name %></strong>
|
|
20
|
+
<span class='ms-2 text-muted'>
|
|
21
|
+
<%= f.object.data_type %>
|
|
22
|
+
<% if f.object.length.present? %>(<%= f.object.length %>)<% end %>
|
|
23
|
+
<% if f.object.decimal_precision.present? && ['real', 'double precision', 'numeric', 'decimal'].include?(f.object.data_type) %>
|
|
24
|
+
,<%= f.object.decimal_precision %> decimal places
|
|
25
|
+
<% end %>
|
|
26
|
+
</span>
|
|
27
|
+
<% if f.object.is_primary_key %><span class='badge bg-primary ms-2'>PK</span><% end %>
|
|
28
|
+
<% if f.object.is_foreign_key %><span class='badge bg-info ms-2'>FK</span><% end %>
|
|
29
|
+
<% if f.object.not_null %><span class='badge bg-warning ms-2'>NOT NULL</span><% end %>
|
|
30
|
+
<% else %>
|
|
31
|
+
<em><%= t('dbdoc.new_column') %></em>
|
|
32
|
+
<% end %>
|
|
33
|
+
</button>
|
|
34
|
+
</h2>
|
|
35
|
+
|
|
36
|
+
<!-- Accordion Content -->
|
|
37
|
+
<div id='<%= accordion_id %>'
|
|
38
|
+
class='accordion-collapse collapse'
|
|
39
|
+
data-dbdoc-accordion-target="content">
|
|
40
|
+
<div class='accordion-body'>
|
|
41
|
+
|
|
42
|
+
<!-- Column details form -->
|
|
43
|
+
<div class='card mb-3'>
|
|
44
|
+
<!-- Card header with column details title -->
|
|
45
|
+
<div class='card-header bg-white d-flex justify-content-between align-items-center'>
|
|
46
|
+
<h5 class='mb-0 fs-6'><%= t('dbdoc.column_details') %></h5>
|
|
47
|
+
</div>
|
|
48
|
+
<div class='card-body'>
|
|
49
|
+
<!-- First row: Column name, Physical column name, Data type -->
|
|
50
|
+
<div class='row mb-3'>
|
|
51
|
+
<div class='col-md-4'>
|
|
52
|
+
<!-- Column name field with validation feedback -->
|
|
53
|
+
<%= f.label :column_name, t('dbdoc.column_name'), class: 'form-label required-field' %>
|
|
54
|
+
<%= f.text_field :column_name,
|
|
55
|
+
class: "form-control #{f.object.errors[:column_name].any? ? 'is-invalid' : ''}",
|
|
56
|
+
data: {
|
|
57
|
+
error_target: 'columnName',
|
|
58
|
+
column_type_target: 'columnNameInput',
|
|
59
|
+
action: 'input->column#updateAccordionTitle'
|
|
60
|
+
} %>
|
|
61
|
+
</div>
|
|
62
|
+
<div class='col-md-4'>
|
|
63
|
+
<!-- Physical column name field with validation feedback -->
|
|
64
|
+
<%= f.label :physical_column_name, t('dbdoc.physical_column_name'), class: 'form-label required-field' %>
|
|
65
|
+
<%= f.text_field :physical_column_name,
|
|
66
|
+
class: "form-control #{f.object.errors[:physical_column_name].any? ? 'is-invalid' : ''}",
|
|
67
|
+
data: { error_target: 'physicalColumnName' } %>
|
|
68
|
+
</div>
|
|
69
|
+
<div class='col-md-4'>
|
|
70
|
+
<!-- Data type selector dropdown -->
|
|
71
|
+
<%= f.label :data_type, t('dbdoc.data_type'), class: 'form-label required-field' %>
|
|
72
|
+
<%= data_type_select(f, f.object.data_type) %>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
<!-- Second row: Length, Decimal Precision, Default value -->
|
|
76
|
+
<div class='row mb-3'>
|
|
77
|
+
<div class='col-md-4'>
|
|
78
|
+
<!-- Length field with validation and suggestion feature -->
|
|
79
|
+
<%= f.label :length, t('dbdoc.length'), class: 'form-label' %>
|
|
80
|
+
<%= f.number_field :length,
|
|
81
|
+
class: "form-control #{f.object.errors[:length].any? ? 'is-invalid' : ''}",
|
|
82
|
+
min: 1,
|
|
83
|
+
data: {
|
|
84
|
+
column_type_target: 'length',
|
|
85
|
+
action: 'input->column-type#clearSuggestion input->column#updateAccordionTitle',
|
|
86
|
+
error_target: 'length'
|
|
87
|
+
} %>
|
|
88
|
+
<!-- Helper text area for length suggestions based on data type -->
|
|
89
|
+
<small class='form-text text-muted' data-column-type-target='lengthSuggestion'></small>
|
|
90
|
+
</div>
|
|
91
|
+
<!-- New Decimal Precision field - hidden by default and shown by Stimulus controller -->
|
|
92
|
+
<div class='col-md-4' data-column-type-target='decimalPrecisionContainer'>
|
|
93
|
+
<!-- Decimal precision field with validation -->
|
|
94
|
+
<%= f.label :decimal_precision, t('dbdoc.decimal_precision'), class: 'form-label' %>
|
|
95
|
+
<%= f.number_field :decimal_precision,
|
|
96
|
+
class: "form-control #{f.object.errors[:decimal_precision].any? ? 'is-invalid' : ''}",
|
|
97
|
+
min: 0,
|
|
98
|
+
data: {
|
|
99
|
+
column_type_target: 'decimalPrecision',
|
|
100
|
+
action: 'input->column#updateAccordionTitle',
|
|
101
|
+
error_target: 'decimalPrecision'
|
|
102
|
+
} %>
|
|
103
|
+
<small class='form-text text-muted'><%= t('dbdoc.decimal_precision_hint') %></small>
|
|
104
|
+
</div>
|
|
105
|
+
<div class='col-md-4'>
|
|
106
|
+
<!-- Default value field with validation -->
|
|
107
|
+
<%= f.label :default_value, t('dbdoc.default_value'), class: 'form-label' %>
|
|
108
|
+
<%= f.text_field :default_value,
|
|
109
|
+
class: "form-control #{f.object.errors[:default_value].any? ? 'is-invalid' : ''}",
|
|
110
|
+
data: { error_target: 'defaultValue' } %>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
<!-- Third row: Sample value and Column properties -->
|
|
114
|
+
<div class='row mb-3'>
|
|
115
|
+
<div class='col-md-4'>
|
|
116
|
+
<!-- Sample value field with validation -->
|
|
117
|
+
<%= f.label :sample_value, t('dbdoc.sample_value'), class: 'form-label' %>
|
|
118
|
+
<%= f.text_field :sample_value,
|
|
119
|
+
class: "form-control #{f.object.errors[:sample_value].any? ? 'is-invalid' : ''}",
|
|
120
|
+
data: { error_target: 'sampleValue' } %>
|
|
121
|
+
</div>
|
|
122
|
+
<div class='col-md-4'>
|
|
123
|
+
<!-- Column properties section with checkboxes for constraints -->
|
|
124
|
+
<label class='form-label'><%= t('dbdoc.column_properties') %></label>
|
|
125
|
+
<!-- Key checkbox options organized in a grid -->
|
|
126
|
+
<div class='row'>
|
|
127
|
+
<div class='col-md-3'>
|
|
128
|
+
<!-- Primary key checkbox with accordion update event -->
|
|
129
|
+
<div class='form-check mt-2'>
|
|
130
|
+
<%= f.check_box :is_primary_key,
|
|
131
|
+
class: 'form-check-input',
|
|
132
|
+
data: { action: 'change->column#updateAccordionTitle' } %>
|
|
133
|
+
<%= f.label :is_primary_key, 'Primary🔑', class: 'form-check-label' %>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
<div class='col-md-3'>
|
|
137
|
+
<!-- Candidate key checkbox -->
|
|
138
|
+
<div class='form-check mt-2'>
|
|
139
|
+
<%= f.check_box :is_candidate_key, class: 'form-check-input' %>
|
|
140
|
+
<%= f.label :is_candidate_key, 'Candidate🔑', class: 'form-check-label' %>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
<div class='col-md-3'>
|
|
144
|
+
<!-- Unique key checkbox -->
|
|
145
|
+
<div class='form-check mt-2'>
|
|
146
|
+
<%= f.check_box :is_unique_key, class: 'form-check-input' %>
|
|
147
|
+
<%= f.label :is_unique_key, 'Unique🔑', class: 'form-check-label' %>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
<div class='col-md-3'>
|
|
151
|
+
<!-- Indexed checkbox -->
|
|
152
|
+
<div class='form-check mt-2'>
|
|
153
|
+
<%= f.check_box :is_indexed, class: 'form-check-input' %>
|
|
154
|
+
<%= f.label :is_indexed, 'Indexed', class: 'form-check-label' %>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
<div class='col-md-3'>
|
|
158
|
+
<!-- Not null checkbox with accordion update event -->
|
|
159
|
+
<div class='form-check mt-2'>
|
|
160
|
+
<%= f.check_box :not_null,
|
|
161
|
+
class: 'form-check-input',
|
|
162
|
+
data: { action: 'change->column#updateAccordionTitle' } %>
|
|
163
|
+
<%= f.label :not_null, 'Not Null', class: 'form-check-label' %>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
<!-- Foreign key section toggle -->
|
|
170
|
+
<div class='row mb-3'>
|
|
171
|
+
<div class='col-12'>
|
|
172
|
+
<!-- Foreign key checkbox to toggle related fields -->
|
|
173
|
+
<div class='form-check mb-2'>
|
|
174
|
+
<%= f.check_box :is_foreign_key,
|
|
175
|
+
class: 'form-check-input foreign-key-checkbox',
|
|
176
|
+
data: { action: 'click->column#toggleForeignKeyFields change->column#updateAccordionTitle' } %>
|
|
177
|
+
<%= f.label :is_foreign_key, t('dbdoc.is_foreign_key?'), class: 'form-check-label fw-semibold' %>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
<!-- Render foreign key fields partial - shown/hidden based on checkbox -->
|
|
182
|
+
<%= render 'foreign_key_fields', f: f, other_tables: %>
|
|
183
|
+
<!-- Last row: Description and Created by fields -->
|
|
184
|
+
<div class='row'>
|
|
185
|
+
<div class='col-md-6'>
|
|
186
|
+
<!-- Description field with validation -->
|
|
187
|
+
<%= f.label :description, t('dbdoc.description'), class: 'form-label' %>
|
|
188
|
+
<%= f.text_area :description,
|
|
189
|
+
class: "form-control #{f.object.errors[:description].any? ? 'is-invalid' : ''}",
|
|
190
|
+
rows: 1,
|
|
191
|
+
data: { error_target: 'description' } %>
|
|
192
|
+
</div>
|
|
193
|
+
<div class='col-md-6'>
|
|
194
|
+
<!-- Created by field with validation -->
|
|
195
|
+
<%= f.label :created_by, t('dbdoc.created_by'), class: 'form-label required-field' %>
|
|
196
|
+
<%= f.text_field :created_by,
|
|
197
|
+
class: "form-control #{f.object.errors[:created_by].any? ? 'is-invalid' : ''}",
|
|
198
|
+
data: { error_target: 'createdBy' } %>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
<!-- Hidden fields and remove button -->
|
|
202
|
+
<div class='mt-3'>
|
|
203
|
+
<!-- Hidden field to store table ID reference -->
|
|
204
|
+
<%= f.hidden_field :table_id, value: f.object.db_design_dynamic_table_id || table&.id %>
|
|
205
|
+
<!-- Hidden field for soft delete functionality -->
|
|
206
|
+
<%= f.hidden_field :_destroy, data: {
|
|
207
|
+
column_target: 'destroyField',
|
|
208
|
+
column_type_target: 'destroyInput'
|
|
209
|
+
} %>
|
|
210
|
+
<!-- Button to remove this column from the table -->
|
|
211
|
+
<button type='button'
|
|
212
|
+
class='btn btn-danger remove-column-btn'
|
|
213
|
+
data-action='column#remove'
|
|
214
|
+
data-column-type-target='removeButton'>
|
|
215
|
+
<i class='bi bi-trash me-1'></i><%= t('dbdoc.remove') %>
|
|
216
|
+
</button>
|
|
217
|
+
</div>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<div class='card card-custom shadow mb-4'>
|
|
2
|
+
<div class='card-body p-0'>
|
|
3
|
+
<div class='table-responsive p-1'>
|
|
4
|
+
<!-- Table for displaying deleted dynamic tables -->
|
|
5
|
+
<table class='table mb-0 fs-6'>
|
|
6
|
+
<thead class='table-secondary bg-light'>
|
|
7
|
+
<tr>
|
|
8
|
+
<!-- Table Group Column Header -->
|
|
9
|
+
<th class='text-custom-secondary' width="20%"><small><i class='bi bi-folder me-2'></i><%= t('dbdoc.table_group') %></small></th>
|
|
10
|
+
<!-- Table Name Column Header -->
|
|
11
|
+
<th class='text-custom-secondary' width="20%"><small><%= t('dbdoc.table_name') %></small></th>
|
|
12
|
+
<!-- Columns Count Header -->
|
|
13
|
+
<th class='text-custom-secondary' width="20%"><small><%= t('dbdoc.columns') %></small></th>
|
|
14
|
+
<!-- Description Header -->
|
|
15
|
+
<th class='text-custom-secondary' width="20%"><small><%= t('dbdoc.description') %></small></th>
|
|
16
|
+
<!-- Deleted At Timestamp Header -->
|
|
17
|
+
<th class='text-custom-secondary' width="20%"><small><%= t('dbdoc.deleted_at') %></small></th>
|
|
18
|
+
<!-- Actions Header -->
|
|
19
|
+
<th class='text-custom-secondary' width="20%"><small><%= t('dbdoc.actions') %></small></th>
|
|
20
|
+
</tr>
|
|
21
|
+
</thead>
|
|
22
|
+
<tbody>
|
|
23
|
+
<!-- Group tables by their table group (including soft-deleted groups) -->
|
|
24
|
+
<% grouped_tables = tables.group_by { |table|
|
|
25
|
+
# Find the table group including soft-deleted ones
|
|
26
|
+
if table.db_design_table_group_id.present?
|
|
27
|
+
DbdocEngine::DbDesignTableGroup.with_deleted.find_by(id: table.db_design_table_group_id)
|
|
28
|
+
else
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
} %>
|
|
32
|
+
<% grouped_tables.each do |group, tables| %>
|
|
33
|
+
<% tables.each_with_index do |table, index| %>
|
|
34
|
+
<!-- Deleted Table Row -->
|
|
35
|
+
<tr class='table-danger bg-opacity-10'>
|
|
36
|
+
<% if index == 0 %>
|
|
37
|
+
<!-- Display group info only once per group -->
|
|
38
|
+
<td class='fw-medium border-end bg-light bg-opacity-25' rowspan='<%= tables.length %>'>
|
|
39
|
+
<% if group %>
|
|
40
|
+
<!-- Group name with color dot and deleted indicator -->
|
|
41
|
+
<small><div class='d-flex align-items-center'>
|
|
42
|
+
<span class='me-2 rounded-circle colour-circle' style='background-color: <%= group.group_color %>;'></span>
|
|
43
|
+
<span>
|
|
44
|
+
<%= group.group_name %> (<%= tables.size %>)
|
|
45
|
+
<% if group.deleted_at.present? %>
|
|
46
|
+
<br><span class='text-danger'><i class='bi bi-trash-fill me-1'></i>Deleted Group</span>
|
|
47
|
+
<% end %>
|
|
48
|
+
</span>
|
|
49
|
+
</div></small>
|
|
50
|
+
<% else %>
|
|
51
|
+
<!-- Ungrouped Label -->
|
|
52
|
+
<small><span class='text-muted'>Ungrouped</span></small>
|
|
53
|
+
<% end %>
|
|
54
|
+
</td>
|
|
55
|
+
<% end %>
|
|
56
|
+
<!-- Table name and physical name -->
|
|
57
|
+
<td class='fw-medium'>
|
|
58
|
+
<small><div><%= table.table_name %></div>
|
|
59
|
+
<small class='text-muted'><%= table.physical_table_name %></small></small>
|
|
60
|
+
</td>
|
|
61
|
+
<!-- Column count badge -->
|
|
62
|
+
<td>
|
|
63
|
+
<small><span class='ms-4'>
|
|
64
|
+
<%= table.db_design_dynamic_columns.size %>
|
|
65
|
+
</span></small>
|
|
66
|
+
</td>
|
|
67
|
+
<!-- Table description -->
|
|
68
|
+
<td>
|
|
69
|
+
<div class='description-text truncate-by-width' data-bs-toggle="tooltip" title="<%= table.description %>">
|
|
70
|
+
<small><%= table.description %></small>
|
|
71
|
+
</div>
|
|
72
|
+
</td>
|
|
73
|
+
<!-- Deleted at timestamp -->
|
|
74
|
+
<td>
|
|
75
|
+
<small><small class='text-danger'>
|
|
76
|
+
<i class='bi bi-calendar-x me-1'></i>
|
|
77
|
+
<%= table.deleted_at&.strftime('%Y-%m-%d %H:%M') %>
|
|
78
|
+
</small></small>
|
|
79
|
+
</td>
|
|
80
|
+
<!-- Restore and Delete Permanently Actions -->
|
|
81
|
+
<td>
|
|
82
|
+
<small><div class='d-flex justify-content-end gap-2'>
|
|
83
|
+
<!-- Restore button -->
|
|
84
|
+
<%= button_to dbdoc_engine.restore_admin_db_design_dynamic_table_path(table),
|
|
85
|
+
method: :patch,
|
|
86
|
+
data: {turbo: false },
|
|
87
|
+
class: 'btn btn-outline-success btn-sm px-2 shadow-sm' do %>
|
|
88
|
+
<i class='bi bi-arrow-counterclockwise'></i>
|
|
89
|
+
<% end %>
|
|
90
|
+
<!-- Permanent delete button -->
|
|
91
|
+
<%= button_to dbdoc_engine.permanent_destroy_admin_db_design_dynamic_table_path(table),
|
|
92
|
+
method: :delete,
|
|
93
|
+
data: { confirm: t('dbdoc.confirm_permanent_delete'), turbo: false },
|
|
94
|
+
class: 'btn btn-outline-danger btn-sm px-2 shadow-sm' do %>
|
|
95
|
+
<i class='bi bi-trash-fill'></i>
|
|
96
|
+
<% end %>
|
|
97
|
+
</div></small>
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
<% end %>
|
|
101
|
+
<% end %>
|
|
102
|
+
</tbody>
|
|
103
|
+
</table>
|
|
104
|
+
<!-- Pagination controls -->
|
|
105
|
+
<div class='d-flex mt-3 justify-content-end p-3'>
|
|
106
|
+
<small><%= paginate tables, theme: 'dbdoc_engine' %></small>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<%# This partial renders the foreign key relationship fields with direct search functionality in dropdowns %>
|
|
2
|
+
|
|
3
|
+
<% other_tables ||= [] %>
|
|
4
|
+
|
|
5
|
+
<!-- Foreign Key Fields Wrapper (initially hidden) -->
|
|
6
|
+
<div class='foreign-key-fields bg-light p-3 rounded border mb-3 hidden'>
|
|
7
|
+
<div class='row mb-3'>
|
|
8
|
+
<!-- Referenced Table Dropdown with Search -->
|
|
9
|
+
<div class='col-md-4' data-controller="select2" data-select2-placeholder-value="<%= t('dbdoc.select_table') %>">
|
|
10
|
+
<%= f.label :foreign_table_name, t('dbdoc.referenced_table'), class: 'form-label required-field' %>
|
|
11
|
+
<%= f.collection_select :foreign_table_name, other_tables, :table_name, :table_name,
|
|
12
|
+
{ include_blank: t('dbdoc.select_table'), selected: f.object.foreign_table_name },
|
|
13
|
+
class: 'form-select foreign-table-dropdown',
|
|
14
|
+
data: {
|
|
15
|
+
select2_target: 'select',
|
|
16
|
+
action: 'change->column#loadColumns',
|
|
17
|
+
column_existing_foreign_table: f.object.foreign_table_name,
|
|
18
|
+
column_existing_foreign_column: f.object.foreign_column_name
|
|
19
|
+
} %>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<!-- Referenced Column Dropdown with Search -->
|
|
23
|
+
<div class='col-md-4' data-controller="select2" data-select2-placeholder-value="<%= t('dbdoc.select_column') %>">
|
|
24
|
+
<%= f.label :foreign_column_name, t('dbdoc.referenced_column'), class: 'form-label required-field' %>
|
|
25
|
+
<%= f.select :foreign_column_name, [],
|
|
26
|
+
{ include_blank: t('dbdoc.select_column'), selected: f.object.foreign_column_name },
|
|
27
|
+
class: 'form-select foreign-column-dropdown',
|
|
28
|
+
data: {
|
|
29
|
+
select2_target: 'select'
|
|
30
|
+
} %>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<!-- Relationship Type Dropdown -->
|
|
34
|
+
<div class='col-md-4' data-controller="select2" data-select2-placeholder-value="<%= t('dbdoc.select_relationship_type') %>">
|
|
35
|
+
<%= f.label :relationship_type, t('dbdoc.relationship_type'), class: 'form-label required-field' %>
|
|
36
|
+
<%= f.select :relationship_type,
|
|
37
|
+
[
|
|
38
|
+
[t('dbdoc.one_to_one'), 'one_to_one'],
|
|
39
|
+
[t('dbdoc.one_to_many'), 'one_to_many'],
|
|
40
|
+
[t('dbdoc.many_to_one'), 'many_to_one'],
|
|
41
|
+
[t('dbdoc.many_to_many'), 'many_to_many']
|
|
42
|
+
],
|
|
43
|
+
{ include_blank: t('dbdoc.select_relationship_type'), selected: f.object.relationship_type },
|
|
44
|
+
class: 'form-select relationship-type-dropdown',
|
|
45
|
+
data: {
|
|
46
|
+
select2_target: 'select',
|
|
47
|
+
action: 'change->column#updateAccordionTitle'
|
|
48
|
+
} %>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<%# This is the main form for creating and editing tables. It includes form validation controller and nested fields for columns %>
|
|
2
|
+
|
|
3
|
+
<!-- Table Form Start -->
|
|
4
|
+
<%= form_with(
|
|
5
|
+
model: [:admin, table],
|
|
6
|
+
local: true,
|
|
7
|
+
class: 'needs-validation ps-5 pe-5 pt-4 bg-white rounded',
|
|
8
|
+
data: {
|
|
9
|
+
controller: 'table-validation',
|
|
10
|
+
action: 'submit->table-validation#validate',
|
|
11
|
+
table_validation_existing_tables_value: existing_tables.to_json
|
|
12
|
+
}
|
|
13
|
+
) do |f| %>
|
|
14
|
+
|
|
15
|
+
<!-- Table Information Partial -->
|
|
16
|
+
<%= render 'table_information', f: f, table: table %>
|
|
17
|
+
|
|
18
|
+
<!-- Columns Section Card -->
|
|
19
|
+
<div class='card mb-4 shadow'>
|
|
20
|
+
<div class='card-header bg-light d-flex justify-content-between align-items-center'>
|
|
21
|
+
<!-- Section Heading -->
|
|
22
|
+
<h3 class='mb-0 fs-5'><%= t('dbdoc.columns') %></h3>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<!-- Columns Section Body -->
|
|
26
|
+
<div class='card-body'>
|
|
27
|
+
<div data-controller="column">
|
|
28
|
+
|
|
29
|
+
<!-- Column Toolbar: Add Button & Search -->
|
|
30
|
+
<div class="mb-3 d-flex">
|
|
31
|
+
<!-- Add Column Button -->
|
|
32
|
+
<button type="button" class='btn btn-primary' data-action="column#add">
|
|
33
|
+
<i class="bi bi-plus-circle me-1"></i><%= t('dbdoc.add_column') %>
|
|
34
|
+
</button>
|
|
35
|
+
|
|
36
|
+
<!-- Column Search Input -->
|
|
37
|
+
<div class="ms-2 flex-grow-1">
|
|
38
|
+
<div class="input-group">
|
|
39
|
+
<span class="input-group-text"><i class="bi bi-search"></i></span>
|
|
40
|
+
<input
|
|
41
|
+
type="text"
|
|
42
|
+
class="form-control"
|
|
43
|
+
placeholder="<%= t('dbdoc.search_columns') %>"
|
|
44
|
+
data-column-target="searchInput"
|
|
45
|
+
data-action="input->column#filterColumns">
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<!-- Columns List Container -->
|
|
51
|
+
<div id="columns" data-column-target="columns" class='columns-container'>
|
|
52
|
+
<% if table.persisted? && table.db_design_dynamic_columns.any? %>
|
|
53
|
+
<!-- Render Existing Columns in Edit Mode -->
|
|
54
|
+
<%= f.fields_for :db_design_dynamic_columns do |column_form| %>
|
|
55
|
+
<%= render "column_fields", f: column_form, other_tables: other_tables %>
|
|
56
|
+
<% end %>
|
|
57
|
+
<% else %>
|
|
58
|
+
<!-- Message When No Columns Exist -->
|
|
59
|
+
<div class="alert alert-info mb-4">
|
|
60
|
+
<%= t('dbdoc.column_note') %>
|
|
61
|
+
</div>
|
|
62
|
+
<% end %>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
<!-- Fixed Bottom Action Buttons -->
|
|
69
|
+
<div class="d-flex justify-content-end p-3 fixed-bottom">
|
|
70
|
+
<%= f.submit t('dbdoc.save_table'), class: 'btn btn-success btn-sm px-4' %>
|
|
71
|
+
<%= link_to t('dbdoc.back'), dbdoc_engine.admin_db_design_dynamic_tables_path, class: 'btn btn-secondary btn-sm shadow ms-2' %>
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<% end %>
|
|
75
|
+
<!-- Table Form End -->
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<div class="card shadow mb-4">
|
|
2
|
+
<div class="card-header bg-white d-flex align-items-center">
|
|
3
|
+
<i class="bi bi-clock-history me-2 text-primary"></i>
|
|
4
|
+
<span class="fw-bold" style="color: #5366A0;"><%= t('dbdoc.recentactivity') %></span>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="card-body p-0">
|
|
7
|
+
<div class="table-responsive">
|
|
8
|
+
<table class="table mb-0">
|
|
9
|
+
<thead class="table-light bg-light">
|
|
10
|
+
<tr>
|
|
11
|
+
<th class="text-custom-secondary ps-3"><small><%= t('dbdoc.date_and_time') %></small></th>
|
|
12
|
+
<th class="text-custom-secondary"><small><%= t('dbdoc.action') %></small></th>
|
|
13
|
+
<th class="text-custom-secondary"><small><%= t('dbdoc.description') %></small></th>
|
|
14
|
+
</tr>
|
|
15
|
+
</thead>
|
|
16
|
+
<tbody>
|
|
17
|
+
<% if recent_changelogs.any? %>
|
|
18
|
+
<% recent_changelogs.each do |log| %>
|
|
19
|
+
<tr>
|
|
20
|
+
<td class='ps-3'><small><%= log.change_timestamp.strftime('%Y-%m-%d %H:%M:%S') %></small></td>
|
|
21
|
+
<td>
|
|
22
|
+
<%= render 'dbdoc_engine/admin/dashboard/action_badge', action_type: log.action_type %>
|
|
23
|
+
</td>
|
|
24
|
+
<td><small><%= log.changed_by %> <%= log.description %></small></td>
|
|
25
|
+
</tr>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% else %>
|
|
28
|
+
<tr>
|
|
29
|
+
<td colspan="3" class="text-center text-muted py-4">
|
|
30
|
+
<i class="bi bi-exclamation-circle fs-3 d-block mb-2"></i>
|
|
31
|
+
<small><%= t('dbdoc.no_changes_found') %></small>
|
|
32
|
+
</td>
|
|
33
|
+
</tr>
|
|
34
|
+
<% end %>
|
|
35
|
+
</tbody>
|
|
36
|
+
</table>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</div>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<!-- Columns Card -->
|
|
2
|
+
<div class='card shadow mb-4'>
|
|
3
|
+
<div class='card-header bg-white d-flex justify-content-between align-items-center text-custom-primary'>
|
|
4
|
+
<h5 class='mb-0'>
|
|
5
|
+
<%= t('dbdoc.table_columns') %>
|
|
6
|
+
<span class='ms-2 badge text-custom-primary1 rounded-pill'><small><%= columns.count %></small></span>
|
|
7
|
+
</h5>
|
|
8
|
+
<div>
|
|
9
|
+
<div class='input-group'>
|
|
10
|
+
<span class='input-group-text bg-light'>
|
|
11
|
+
<i class='bi bi-search'></i>
|
|
12
|
+
</span>
|
|
13
|
+
<input type='text' class='form-control form-control-sm'
|
|
14
|
+
placeholder='<%= t('dbdoc.search_columns') %>'
|
|
15
|
+
data-controller='column-search'
|
|
16
|
+
data-action='input->column-search#filter'>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div class='card-body p-0 mb-3'>
|
|
21
|
+
<div class='table-responsive'>
|
|
22
|
+
<table class='table mb-0'>
|
|
23
|
+
<thead class='table-light bg-light'>
|
|
24
|
+
<tr>
|
|
25
|
+
<th class='ps-3 text-center text-custom-secondary'>#</th>
|
|
26
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.column_name') %></small></th>
|
|
27
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.physical_name') %></small></th>
|
|
28
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.data_type') %></small></th>
|
|
29
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.decimal_precision') %></small></th>
|
|
30
|
+
<th class='text-custom-secondary' width="20%" ><small><%= t('dbdoc.constraints') %></small></th>
|
|
31
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.default_value') %></small></th>
|
|
32
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.sample_value') %></small></th>
|
|
33
|
+
<th class='text-custom-secondary'><small><%= t('dbdoc.description') %></small></th>
|
|
34
|
+
</tr>
|
|
35
|
+
</thead>
|
|
36
|
+
<tbody>
|
|
37
|
+
<% if columns.empty? %>
|
|
38
|
+
<tr>
|
|
39
|
+
<td colspan='7' class='text-center py-4 text-muted'>
|
|
40
|
+
<i class='bi bi-exclamation-circle fs-3 d-block mb-2'></i>
|
|
41
|
+
<small><%= t('dbdoc.no_columns_defined') %></small>
|
|
42
|
+
</td>
|
|
43
|
+
</tr>
|
|
44
|
+
<% else %>
|
|
45
|
+
<% columns.each_with_index do |column, index| %>
|
|
46
|
+
<tr>
|
|
47
|
+
<td class='ps-3 text-center'><small><%= index + 1 %></small></td>
|
|
48
|
+
<td>
|
|
49
|
+
<% if column.is_primary_key %>
|
|
50
|
+
<span class='me-1 text-warning'><i class='bi bi-key-fill' title='Primary Key'></i></span>
|
|
51
|
+
<% end %>
|
|
52
|
+
<span class='<%= column.is_primary_key ? 'fw-bold' : '' %>'><small><%= column.column_name %></small></span>
|
|
53
|
+
</td>
|
|
54
|
+
<td><small><%= column.physical_column_name %></small></td>
|
|
55
|
+
<td>
|
|
56
|
+
<small><%= column.data_type %>
|
|
57
|
+
<% if column.length.present? %>
|
|
58
|
+
(<%= column.length %>)
|
|
59
|
+
<% end %></small>
|
|
60
|
+
</td>
|
|
61
|
+
<td>
|
|
62
|
+
<% if column.decimal_precision.present? %>
|
|
63
|
+
<small><%= column.decimal_precision %></small>
|
|
64
|
+
<% else %>
|
|
65
|
+
<small>-</small>
|
|
66
|
+
<% end %>
|
|
67
|
+
</td>
|
|
68
|
+
<td>
|
|
69
|
+
<div class="d-flex flex-wrap align-items-start gap-1">
|
|
70
|
+
<% if column.not_null %>
|
|
71
|
+
<span class="badge bg-secondary small fw-normal"><small>NOT NULL</small></span>
|
|
72
|
+
<% end %>
|
|
73
|
+
<% if column.is_foreign_key %>
|
|
74
|
+
<span class="badge bg-darkblue small fw-normal">
|
|
75
|
+
<i class="bi bi-link"></i> <small>FK → <%= column.foreign_table_name %>.<%= column.foreign_column_name %></small>
|
|
76
|
+
</span>
|
|
77
|
+
<% end %>
|
|
78
|
+
<% if column.is_candidate_key %>
|
|
79
|
+
<span class="badge bg-orange small fw-normal"><i class="bi bi-key"></i> <small>Candidate</small></span>
|
|
80
|
+
<% end %>
|
|
81
|
+
<% if column.is_unique_key %>
|
|
82
|
+
<span class="badge bg-yellow small fw-normal"><i class="bi bi-key"></i> <small>Unique</small></span>
|
|
83
|
+
<% end %>
|
|
84
|
+
<% if column.is_indexed %>
|
|
85
|
+
<span class="badge bg-green text-dark small fw-normal"><i class="bi bi-search"></i> <small>Indexed</small></span>
|
|
86
|
+
<% end %>
|
|
87
|
+
</div>
|
|
88
|
+
</td>
|
|
89
|
+
<td>
|
|
90
|
+
<% if column.default_value.present? %>
|
|
91
|
+
<span class="badge bg-light text-dark small fw-normal">
|
|
92
|
+
<small><%= column.default_value %></small>
|
|
93
|
+
</span>
|
|
94
|
+
<% else %>
|
|
95
|
+
<small>-</small>
|
|
96
|
+
<% end %>
|
|
97
|
+
</td>
|
|
98
|
+
<td>
|
|
99
|
+
<% if column.sample_value.present? %>
|
|
100
|
+
<span class="badge bg-light text-dark small fw-normal">
|
|
101
|
+
<small><%= column.sample_value %></small>
|
|
102
|
+
</span>
|
|
103
|
+
<% else %>
|
|
104
|
+
<small>-</small>
|
|
105
|
+
<% end %>
|
|
106
|
+
</td>
|
|
107
|
+
<td>
|
|
108
|
+
<div class='column-description truncate-by-width' title='<%= column.description %>'>
|
|
109
|
+
<% if column.description.present? %>
|
|
110
|
+
<small><%= column.description %></small>
|
|
111
|
+
<% else %>
|
|
112
|
+
<small>-</small>
|
|
113
|
+
<% end %>
|
|
114
|
+
</div>
|
|
115
|
+
</td>
|
|
116
|
+
</tr>
|
|
117
|
+
<% end %>
|
|
118
|
+
<% end %>
|
|
119
|
+
</tbody>
|
|
120
|
+
</table>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div class='d-flex justify-content-end mt-5 mx-3'>
|
|
124
|
+
<%= paginate columns, theme: 'dbdoc_engine' %>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|