infotable 1.4.1 → 1.6.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 +4 -4
- data/README.md +179 -11
- data/app/assets/javascripts/infotable/controllers/drawer_controller.js +74 -378
- data/app/assets/javascripts/infotable/controllers/table_controller.js +112 -120
- data/app/assets/javascripts/infotable/vendor/sortable.esm.js +3363 -0
- data/app/controllers/infotable/tables_controller.rb +16 -5
- data/app/helpers/infotable/tables_helper.rb +10 -48
- data/app/views/infotable/tables/_column_visibility.html.erb +4 -4
- data/app/views/infotable/tables/_end_indicator.html.erb +8 -0
- data/app/views/infotable/tables/_filter_drawer.html.erb +6 -6
- data/app/views/infotable/tables/_next_page_frame.html.erb +1 -9
- data/app/views/infotable/tables/_pagination.html.erb +4 -7
- data/app/views/infotable/tables/_table.html.erb +1 -1
- data/app/views/infotable/tables/_table_rows.html.erb +9 -2
- data/app/views/infotable/tables/filters/_boolean.html.erb +1 -1
- data/app/views/infotable/tables/filters/_range.html.erb +1 -1
- data/app/views/infotable/tables/filters/_select.html.erb +2 -2
- data/app/views/infotable/tables/filters/_text.html.erb +2 -2
- data/app/views/infotable/tables/show.html.erb +2 -2
- data/config/importmap.rb +2 -2
- data/config/locales/de.yml +126 -0
- data/config/locales/el.yml +126 -0
- data/config/locales/en.yml +18 -4
- data/config/locales/es.yml +126 -0
- data/config/locales/fr.yml +126 -0
- data/config/locales/it.yml +126 -0
- data/config/locales/pl.yml +18 -4
- data/exe/infotable-mcp +13 -0
- data/lib/generators/infotable/install/templates/initializer.rb +5 -3
- data/lib/generators/infotable/table/table_generator.rb +23 -1
- data/lib/generators/infotable/table/templates/table.rb.tt +8 -1
- data/lib/infotable/base.rb +62 -4
- data/lib/infotable/configuration.rb +1 -1
- data/lib/infotable/engine.rb +1 -8
- data/lib/infotable/filter_processor.rb +10 -1
- data/lib/infotable/formatters/boolean_formatter.rb +4 -4
- data/lib/infotable/formatters/currency_formatter.rb +4 -12
- data/lib/infotable/formatters/date_formatter.rb +3 -9
- data/lib/infotable/formatters/duration_formatter.rb +51 -0
- data/lib/infotable/formatters/filesize_formatter.rb +14 -0
- data/lib/infotable/formatters/image_formatter.rb +31 -0
- data/lib/infotable/formatters/number_formatter.rb +46 -0
- data/lib/infotable/formatters/tags_formatter.rb +44 -0
- data/lib/infotable/formatters/truncate_formatter.rb +19 -0
- data/lib/infotable/mcp/introspection.rb +94 -0
- data/lib/infotable/mcp/server.rb +26 -0
- data/lib/infotable/mcp/table_checker.rb +80 -0
- data/lib/infotable/mcp/table_writer.rb +66 -0
- data/lib/infotable/mcp/tools.rb +122 -0
- data/lib/infotable/mcp.rb +30 -0
- data/lib/infotable/table_resolver.rb +9 -0
- data/lib/infotable/version.rb +1 -1
- data/lib/infotable.rb +22 -0
- metadata +53 -4
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require "generators/infotable/table/table_generator"
|
|
2
|
+
|
|
3
|
+
module Infotable
|
|
4
|
+
module Mcp
|
|
5
|
+
# Renders a table with the `infotable:table` generator into a scratch directory,
|
|
6
|
+
# so the code can be shown first and written to app/infotable only on request.
|
|
7
|
+
class TableWriter
|
|
8
|
+
Result = Struct.new(:path, :code, keyword_init: true)
|
|
9
|
+
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
FLAGS = %i[only skip per_page sort toolbar row_click infinite_scroll countless checkbox authorize].freeze
|
|
13
|
+
|
|
14
|
+
def initialize(model, settings = {})
|
|
15
|
+
@model = model.to_s
|
|
16
|
+
@settings = settings.to_h.symbolize_keys.slice(*FLAGS).compact
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def render
|
|
20
|
+
raise Error, "unknown model #{@model}" unless @model.safe_constantize.is_a?(Class)
|
|
21
|
+
|
|
22
|
+
Dir.mktmpdir("infotable-mcp") do |dir|
|
|
23
|
+
shell = Thor::Base.shell.new
|
|
24
|
+
generator = Infotable::Generators::TableGenerator.new([ @model ], switches, destination_root: dir, shell: shell)
|
|
25
|
+
shell.mute { generator.invoke_all }
|
|
26
|
+
|
|
27
|
+
file = Dir.glob("app/infotable/**/*.rb", base: dir).first or raise Error, "the generator wrote nothing"
|
|
28
|
+
code = File.read(File.join(dir, file))
|
|
29
|
+
check_syntax!(code)
|
|
30
|
+
Result.new(path: file, code: code)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Writes the rendered table into the app; an existing file is only replaced with overwrite: true
|
|
35
|
+
def write(overwrite: false)
|
|
36
|
+
result = render
|
|
37
|
+
target = Rails.root.join(result.path)
|
|
38
|
+
raise Error, "#{result.path} already exists, pass overwrite: true to replace it" if target.exist? && !overwrite
|
|
39
|
+
|
|
40
|
+
target.dirname.mkpath
|
|
41
|
+
target.write(result.code)
|
|
42
|
+
result
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def switches
|
|
48
|
+
@settings.flat_map do |key, value|
|
|
49
|
+
flag = "--#{key.to_s.dasherize}"
|
|
50
|
+
case value
|
|
51
|
+
when true then [ flag ]
|
|
52
|
+
when false then [ "--no-#{key.to_s.dasherize}" ]
|
|
53
|
+
when Array then [ flag, *value.map(&:to_s) ]
|
|
54
|
+
else [ flag, value.to_s ]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def check_syntax!(code)
|
|
60
|
+
RubyVM::InstructionSequence.compile(code)
|
|
61
|
+
rescue SyntaxError => e
|
|
62
|
+
raise Error, "generated code does not parse (check authorize/sort values): #{e.message.lines.first&.strip}"
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
module Infotable
|
|
2
|
+
module Mcp
|
|
3
|
+
class ListModels < ::MCP::Tool
|
|
4
|
+
tool_name "list_models"
|
|
5
|
+
description "Models of this Rails app with column types, enums and associations. Call first, so column names are not guessed."
|
|
6
|
+
input_schema(properties: {})
|
|
7
|
+
annotations(read_only_hint: true)
|
|
8
|
+
|
|
9
|
+
def self.call(server_context: nil)
|
|
10
|
+
Mcp.text(Introspection.models)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class ListTables < ::MCP::Tool
|
|
15
|
+
tool_name "list_tables"
|
|
16
|
+
description "InfoTable tables that already exist in app/infotable, with their columns and settings. Use them as the house style."
|
|
17
|
+
input_schema(properties: {})
|
|
18
|
+
annotations(read_only_hint: true)
|
|
19
|
+
|
|
20
|
+
def self.call(server_context: nil)
|
|
21
|
+
Mcp.text(Introspection.tables)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
class DescribeDsl < ::MCP::Tool
|
|
26
|
+
tool_name "describe_dsl"
|
|
27
|
+
description "The table DSL of the installed infotable version: column options, types, filters, formatters, settings. The full guide is the infotable://readme resource."
|
|
28
|
+
input_schema(properties: {})
|
|
29
|
+
annotations(read_only_hint: true)
|
|
30
|
+
|
|
31
|
+
def self.call(server_context: nil)
|
|
32
|
+
Mcp.text(Introspection.dsl)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class TableOptions < ::MCP::Tool
|
|
37
|
+
tool_name "table_options"
|
|
38
|
+
description "Settings of a new table for a model, as questions with defaults proposed from the model. " \
|
|
39
|
+
"Ask the user these (all at once, defaults pre-filled) before calling generate_table."
|
|
40
|
+
input_schema(properties: { model: { type: "string", description: "Model class name, e.g. Order or Admin::Invoice" } }, required: [ "model" ])
|
|
41
|
+
annotations(read_only_hint: true)
|
|
42
|
+
|
|
43
|
+
def self.call(model:, server_context: nil)
|
|
44
|
+
Mcp.text(Introspection.table_options(model) || "#{model} is not an ActiveRecord model; call list_models")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class GenerateTable < ::MCP::Tool
|
|
49
|
+
tool_name "generate_table"
|
|
50
|
+
description "Generates app/infotable/<models>_table.rb for a model with the infotable:table generator. " \
|
|
51
|
+
"Shows the code only; set write: true to save it (refuses to replace a file unless overwrite: true). " \
|
|
52
|
+
"Answers from table_options map to the parameters. Run validate_table afterwards."
|
|
53
|
+
input_schema(
|
|
54
|
+
properties: {
|
|
55
|
+
model: { type: "string" },
|
|
56
|
+
only: { type: "array", items: { type: "string" }, description: "Only these columns" },
|
|
57
|
+
skip: { type: "array", items: { type: "string" }, description: "Leave these columns out" },
|
|
58
|
+
per_page: { type: "integer" },
|
|
59
|
+
sort: { type: "string", description: "column:direction, e.g. created_at:desc" },
|
|
60
|
+
toolbar: { type: "string", enum: %w[header rail] },
|
|
61
|
+
row_click: { type: "boolean" },
|
|
62
|
+
infinite_scroll: { type: "boolean" },
|
|
63
|
+
countless: { type: "boolean" },
|
|
64
|
+
checkbox: { type: "boolean" },
|
|
65
|
+
authorize: { type: "string", description: "Ruby expression over `controller`, e.g. controller.current_user&.admin?" },
|
|
66
|
+
write: { type: "boolean", description: "Save the file (default: only show the code)" },
|
|
67
|
+
overwrite: { type: "boolean" }
|
|
68
|
+
},
|
|
69
|
+
required: [ "model" ]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def self.call(model:, write: false, overwrite: false, server_context: nil, **settings)
|
|
73
|
+
writer = TableWriter.new(model, settings)
|
|
74
|
+
result = write ? writer.write(overwrite: overwrite) : writer.render
|
|
75
|
+
Mcp.text(path: result.path, written: write, code: result.code)
|
|
76
|
+
rescue TableWriter::Error => e
|
|
77
|
+
Mcp.error(e.message)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class ValidateTable < ::MCP::Tool
|
|
82
|
+
tool_name "validate_table"
|
|
83
|
+
description "Loads a table (by name like posts_table, or from source code) and reports mistakes: missing columns, bad default sort, " \
|
|
84
|
+
"failing query. preview: N also returns the first N rows as the table would show them."
|
|
85
|
+
input_schema(
|
|
86
|
+
properties: {
|
|
87
|
+
name: { type: "string", description: "Table name, e.g. orders_table or admin_orders_table" },
|
|
88
|
+
source: { type: "string", description: "Table source code to check without saving it" },
|
|
89
|
+
preview: { type: "integer", description: "Rows to return (max 20)" }
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
annotations(read_only_hint: true)
|
|
93
|
+
|
|
94
|
+
def self.call(name: nil, source: nil, preview: 0, server_context: nil)
|
|
95
|
+
return Mcp.error("pass name or source") if name.blank? && source.blank?
|
|
96
|
+
|
|
97
|
+
Mcp.text(TableChecker.new(name: name, source: source, preview: preview).call)
|
|
98
|
+
rescue Infotable::TableResolver::NotFound, ScriptError, StandardError => e
|
|
99
|
+
Mcp.error("#{e.class}: #{e.message}")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
class NewTablePrompt < ::MCP::Prompt
|
|
104
|
+
prompt_name "new_table"
|
|
105
|
+
description "Create an InfoTable table for a model, asking the user about its settings first"
|
|
106
|
+
arguments [ ::MCP::Prompt::Argument.new(name: "model", description: "Model class name", required: true) ]
|
|
107
|
+
|
|
108
|
+
def self.template(args, server_context: nil)
|
|
109
|
+
model = args["model"] || args[:model]
|
|
110
|
+
text = <<~TEXT
|
|
111
|
+
Create an InfoTable table for #{model}.
|
|
112
|
+
1. Call list_tables to see how tables in this app look, and table_options for #{model}.
|
|
113
|
+
2. Ask the user the questions of table_options in ONE message, with the proposed defaults filled in, and wait for the answers.
|
|
114
|
+
3. Call generate_table with the answers (without write) and show the code.
|
|
115
|
+
4. After the user agrees, call generate_table with write: true, then validate_table with preview: 5 and report the result.
|
|
116
|
+
Add a batch action, formatter or association column only when the user asks; describe_dsl lists what exists.
|
|
117
|
+
TEXT
|
|
118
|
+
::MCP::Prompt::Result.new(messages: [ ::MCP::Prompt::Message.new(role: "user", content: ::MCP::Content::Text.new(text)) ])
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require "mcp"
|
|
3
|
+
rescue LoadError
|
|
4
|
+
abort "infotable-mcp needs the mcp gem: add `gem \"mcp\", group: :development` to your Gemfile and run bundle install"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require "json"
|
|
8
|
+
require "rails/generators"
|
|
9
|
+
require "tmpdir"
|
|
10
|
+
|
|
11
|
+
module Infotable
|
|
12
|
+
# MCP server for creating tables with an AI assistant. See exe/infotable-mcp.
|
|
13
|
+
module Mcp
|
|
14
|
+
autoload :Introspection, "infotable/mcp/introspection"
|
|
15
|
+
autoload :Server, "infotable/mcp/server"
|
|
16
|
+
autoload :TableWriter, "infotable/mcp/table_writer"
|
|
17
|
+
autoload :TableChecker, "infotable/mcp/table_checker"
|
|
18
|
+
|
|
19
|
+
def self.text(payload)
|
|
20
|
+
text = payload.is_a?(String) ? payload : JSON.pretty_generate(payload)
|
|
21
|
+
::MCP::Tool::Response.new([ { type: "text", text: text } ])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.error(message)
|
|
25
|
+
::MCP::Tool::Response.new([ { type: "text", text: message } ], error: true)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
require "infotable/mcp/tools"
|
|
@@ -22,9 +22,18 @@ module Infotable
|
|
|
22
22
|
raise NotFound, "Table '#{table_name}' not found. Make sure it's defined in app/infotable/"
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
CANDIDATES = Concurrent::Map.new
|
|
26
|
+
|
|
27
|
+
# The class names to try are pure string work (up to 2**(n-1) of them): memoized per name
|
|
25
28
|
def candidates(table_name)
|
|
26
29
|
return [] unless table_name.to_s.match?(/\A[a-z0-9]+(_[a-z0-9]+)*\z/i)
|
|
27
30
|
|
|
31
|
+
CANDIDATES.compute_if_absent(table_name.to_s) { build_candidates(table_name) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def build_candidates(table_name)
|
|
35
|
+
return [] unless table_name.to_s.match?(/\A[a-z0-9]+(_[a-z0-9]+)*\z/i)
|
|
36
|
+
|
|
28
37
|
parts = table_name.to_s.sub(/_table\z/, "").split("_")
|
|
29
38
|
return [] if parts.empty? || parts.size > MAX_PARTS
|
|
30
39
|
|
data/lib/infotable/version.rb
CHANGED
data/lib/infotable.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "rails-i18n"
|
|
1
2
|
require "infotable/version"
|
|
2
3
|
require "infotable/configuration"
|
|
3
4
|
require "infotable/engine"
|
|
@@ -24,6 +25,27 @@ module Infotable
|
|
|
24
25
|
autoload :LinkFormatter, "infotable/formatters/link_formatter"
|
|
25
26
|
autoload :AvatarFormatter, "infotable/formatters/avatar_formatter"
|
|
26
27
|
autoload :PercentFormatter, "infotable/formatters/percent_formatter"
|
|
28
|
+
autoload :NumberFormatter, "infotable/formatters/number_formatter"
|
|
29
|
+
autoload :TagsFormatter, "infotable/formatters/tags_formatter"
|
|
30
|
+
autoload :TruncateFormatter, "infotable/formatters/truncate_formatter"
|
|
31
|
+
autoload :ImageFormatter, "infotable/formatters/image_formatter"
|
|
32
|
+
autoload :FilesizeFormatter, "infotable/formatters/filesize_formatter"
|
|
33
|
+
autoload :DurationFormatter, "infotable/formatters/duration_formatter"
|
|
34
|
+
|
|
35
|
+
# `formatter: :name` => class. Anything else is looked up as a custom "<Name>Formatter" constant.
|
|
36
|
+
def self.built_in
|
|
37
|
+
@built_in ||= {
|
|
38
|
+
date: DateFormatter, datetime: DateFormatter,
|
|
39
|
+
currency: CurrencyFormatter,
|
|
40
|
+
boolean: BooleanFormatter,
|
|
41
|
+
badge: BadgeFormatter, status: BadgeFormatter,
|
|
42
|
+
action: ActionFormatter, actions: ActionFormatter,
|
|
43
|
+
link: LinkFormatter, avatar: AvatarFormatter, percent: PercentFormatter,
|
|
44
|
+
number: NumberFormatter, tags: TagsFormatter, list: TagsFormatter,
|
|
45
|
+
truncate: TruncateFormatter, image: ImageFormatter,
|
|
46
|
+
filesize: FilesizeFormatter, duration: DurationFormatter
|
|
47
|
+
}.freeze
|
|
48
|
+
end
|
|
27
49
|
end
|
|
28
50
|
|
|
29
51
|
# Returns the root path of the InfoTable gem
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: infotable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jakub Cieślar
|
|
8
8
|
autorequire:
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -24,6 +24,20 @@ dependencies:
|
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '8.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rails-i18n
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '8.0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '8.0'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
42
|
name: csv
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -122,12 +136,27 @@ dependencies:
|
|
|
122
136
|
- - ">="
|
|
123
137
|
- !ruby/object:Gem::Version
|
|
124
138
|
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: mcp
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
125
153
|
description: InfoTable provides server-side datatable functionality with filtering,
|
|
126
154
|
sorting, searching, and pagination. Built with Hotwire, Stimulus, and Tailwind CSS
|
|
127
155
|
for a modern, no-reload user experience.
|
|
128
156
|
email:
|
|
129
157
|
- jakub@infovation.pl
|
|
130
|
-
executables:
|
|
158
|
+
executables:
|
|
159
|
+
- infotable-mcp
|
|
131
160
|
extensions: []
|
|
132
161
|
extra_rdoc_files: []
|
|
133
162
|
files:
|
|
@@ -137,6 +166,7 @@ files:
|
|
|
137
166
|
- app/assets/javascripts/infotable/controllers/drawer_controller.js
|
|
138
167
|
- app/assets/javascripts/infotable/controllers/table_controller.js
|
|
139
168
|
- app/assets/javascripts/infotable/index.js
|
|
169
|
+
- app/assets/javascripts/infotable/vendor/sortable.esm.js
|
|
140
170
|
- app/assets/tailwind/infotable/engine.css
|
|
141
171
|
- app/controllers/infotable/application_controller.rb
|
|
142
172
|
- app/controllers/infotable/tables_controller.rb
|
|
@@ -147,6 +177,7 @@ files:
|
|
|
147
177
|
- app/models/infotable/application_record.rb
|
|
148
178
|
- app/views/infotable/tables/_active_filters.html.erb
|
|
149
179
|
- app/views/infotable/tables/_column_visibility.html.erb
|
|
180
|
+
- app/views/infotable/tables/_end_indicator.html.erb
|
|
150
181
|
- app/views/infotable/tables/_filter_drawer.html.erb
|
|
151
182
|
- app/views/infotable/tables/_next_page_frame.html.erb
|
|
152
183
|
- app/views/infotable/tables/_pagination.html.erb
|
|
@@ -163,9 +194,15 @@ files:
|
|
|
163
194
|
- app/views/infotable/tables/show.html.erb
|
|
164
195
|
- app/views/layouts/infotable/application.html.erb
|
|
165
196
|
- config/importmap.rb
|
|
197
|
+
- config/locales/de.yml
|
|
198
|
+
- config/locales/el.yml
|
|
166
199
|
- config/locales/en.yml
|
|
200
|
+
- config/locales/es.yml
|
|
201
|
+
- config/locales/fr.yml
|
|
202
|
+
- config/locales/it.yml
|
|
167
203
|
- config/locales/pl.yml
|
|
168
204
|
- config/routes.rb
|
|
205
|
+
- exe/infotable-mcp
|
|
169
206
|
- lib/generators/infotable/install/install_generator.rb
|
|
170
207
|
- lib/generators/infotable/install/templates/initializer.rb
|
|
171
208
|
- lib/generators/infotable/install/templates/tailwind.config.js
|
|
@@ -184,8 +221,20 @@ files:
|
|
|
184
221
|
- lib/infotable/formatters/boolean_formatter.rb
|
|
185
222
|
- lib/infotable/formatters/currency_formatter.rb
|
|
186
223
|
- lib/infotable/formatters/date_formatter.rb
|
|
224
|
+
- lib/infotable/formatters/duration_formatter.rb
|
|
225
|
+
- lib/infotable/formatters/filesize_formatter.rb
|
|
226
|
+
- lib/infotable/formatters/image_formatter.rb
|
|
187
227
|
- lib/infotable/formatters/link_formatter.rb
|
|
228
|
+
- lib/infotable/formatters/number_formatter.rb
|
|
188
229
|
- lib/infotable/formatters/percent_formatter.rb
|
|
230
|
+
- lib/infotable/formatters/tags_formatter.rb
|
|
231
|
+
- lib/infotable/formatters/truncate_formatter.rb
|
|
232
|
+
- lib/infotable/mcp.rb
|
|
233
|
+
- lib/infotable/mcp/introspection.rb
|
|
234
|
+
- lib/infotable/mcp/server.rb
|
|
235
|
+
- lib/infotable/mcp/table_checker.rb
|
|
236
|
+
- lib/infotable/mcp/table_writer.rb
|
|
237
|
+
- lib/infotable/mcp/tools.rb
|
|
189
238
|
- lib/infotable/search_processor.rb
|
|
190
239
|
- lib/infotable/sql.rb
|
|
191
240
|
- lib/infotable/table_resolver.rb
|