Skip to content

Commit cbad870

Browse files
NevelitoPaul-Bob
andauthored
feature: copyable field option (#3468)
* add new feature, copy field value * make display changes * fix bug in text_area field * run rubocop, and make small changes * Fix sugestion by Rubocop and include buttons text in test_helpers_spec * Request changes * Fix failing checks * Fix specs * fix failing check * Self code review * Fix copy firld content spec * Fix spec * Final fix spec * Self check changes and fix what user can copy * refactor * re-organize imports * revert dependencies downgrade * revert schema * rm unwanted styles * lint * fix test * adjust position * tippy * bundle --------- Co-authored-by: Paul Bob <[email protected]> Co-authored-by: Paul Bob <[email protected]>
1 parent e4aa5e5 commit cbad870

33 files changed

+157
-25
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ gem "amazing_print"
114114
group :development, :test do
115115
gem "faker", require: false
116116
gem "i18n-tasks", "~> 1.0.12"
117+
gem "ruby-openai"
117118
gem "erb-formatter", require: false
118119
# https://thoughtbot.com/blog/a-standard-way-to-lint-your-views
119120
gem "erb_lint", require: false

Gemfile.lock

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,19 +267,27 @@ GEM
267267
rubocop (>= 1)
268268
smart_properties
269269
erubi (1.13.0)
270+
event_stream_parser (1.0.0)
270271
factory_bot (6.5.0)
271272
activesupport (>= 5.0.0)
272273
factory_bot_rails (6.4.4)
273274
factory_bot (~> 6.5)
274275
railties (>= 5.0.0)
275276
faker (3.5.1)
276277
i18n (>= 1.8.11, < 2)
278+
faraday (2.12.2)
279+
faraday-net_http (>= 2.0, < 3.5)
280+
json
281+
logger
282+
faraday-multipart (1.1.0)
283+
multipart-post (~> 2.0)
284+
faraday-net_http (3.4.0)
285+
net-http (>= 0.5.0)
277286
ferrum (0.15)
278287
addressable (~> 2.5)
279288
concurrent-ruby (~> 1.1)
280289
webrick (~> 1.7)
281290
websocket-driver (~> 0.7)
282-
ffi (1.17.0)
283291
ffi (1.17.0-x86_64-linux-gnu)
284292
flay (2.13.3)
285293
erubi (~> 1.10)
@@ -379,7 +387,6 @@ GEM
379387
mini_histogram (0.3.1)
380388
mini_magick (4.13.2)
381389
mini_mime (1.1.5)
382-
mini_portile2 (2.8.8)
383390
minitest (5.25.4)
384391
monetize (1.13.0)
385392
money (~> 6.12)
@@ -391,6 +398,9 @@ GEM
391398
money (~> 6.13)
392399
railties (>= 3.0)
393400
msgpack (1.7.5)
401+
multipart-post (2.4.1)
402+
net-http (0.6.0)
403+
uri
394404
net-imap (0.5.2)
395405
date
396406
net-protocol
@@ -401,9 +411,6 @@ GEM
401411
net-smtp (0.5.0)
402412
net-protocol
403413
nio4r (2.7.4)
404-
nokogiri (1.17.2)
405-
mini_portile2 (~> 2.8.2)
406-
racc (~> 1.4)
407414
nokogiri (1.17.2-x86_64-linux)
408415
racc (~> 1.4)
409416
orm_adapter (0.5.0)
@@ -537,6 +544,10 @@ GEM
537544
rubocop-ast (>= 1.31.1, < 2.0)
538545
rubocop-shopify (2.15.1)
539546
rubocop (~> 1.51)
547+
ruby-openai (7.3.1)
548+
event_stream_parser (>= 0.3.0, < 2.0.0)
549+
faraday (>= 1)
550+
faraday-multipart (>= 1)
540551
ruby-progressbar (1.13.0)
541552
ruby-statistics (3.0.2)
542553
ruby-vips (2.2.2)
@@ -662,7 +673,6 @@ GEM
662673
zeitwerk (2.7.1)
663674

664675
PLATFORMS
665-
ruby
666676
x86_64-linux
667677

668678
DEPENDENCIES
@@ -730,6 +740,7 @@ DEPENDENCIES
730740
rspec-retry (~> 0.6.2)
731741
rubocop
732742
rubocop-shopify
743+
ruby-openai
733744
ruby-statistics (< 4)
734745
rubycritic
735746
simplecov
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<%= content_tag :div,
2+
class: "opacity-0 group-hover:opacity-100 transition-opacity duration-200",
3+
data: {
4+
controller: "clipboard",
5+
clipboard_success_duration_value: @duration_value,
6+
clipboard_success_content_value: @content_value
7+
} do %>
8+
<div class="hidden" data-clipboard-target="source"><%= @value %></div>
9+
<div class="text-xs xl:text-sm">
10+
<%= content_tag :button,
11+
type: "button",
12+
data: {
13+
action: "clipboard#copy",
14+
clipboard_target: "button",
15+
tippy: "tooltip",
16+
tippy_content: I18n.t("avo.copy")
17+
} do %>
18+
<%= helpers.svg "heroicons/outline/clipboard", class: "h-4 inline" %>
19+
<% end %>
20+
</div>
21+
<% end %>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# frozen_string_literal: true
2+
3+
class Avo::ClipboardComponent < Avo::BaseComponent
4+
prop :value
5+
6+
def before_render
7+
@duration_value = 2500
8+
@content_value = helpers.svg("heroicons/outline/clipboard-document-check", class: "h-4 inline").tr('"', "'")
9+
end
10+
11+
def render?
12+
@value.present?
13+
end
14+
end

app/components/avo/field_wrapper_component.html.erb

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@
2626
}), data: {slot: "value"} do %>
2727
<div class="self-center w-full break-words <% unless full_width? || compact? || stacked? %> md:w-8/12 has-sidebar:w-full <% end %>">
2828
<% if on_show? %>
29-
<% if render_dash? %>
30-
31-
<% else %>
32-
<%= content %>
33-
<% end %>
29+
<div class="flex flex-row items-center group gap-x-1">
30+
<% if render_dash? %>
31+
32+
<% else %>
33+
<%= content %>
34+
<% end %>
35+
<% if @field.copyable %>
36+
<%= render Avo::ClipboardComponent.new(value: @field.value) %>
37+
<% end %>
38+
</div>
3439
<% elsif on_edit? %>
3540
<%= content %>
3641
<% if record.present? and record.errors.include? @field.id %>

app/components/avo/index/field_wrapper_component.html.erb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@
99
<% if render_dash? %>
1010
1111
<% else %>
12-
<% if @center_content %>
13-
<div class="flex items-center justify-center">
12+
<div class="flex flex-row items-center gap-x-1 group">
13+
<% if @center_content %>
14+
<div class="flex items-center justify-center">
15+
<%= content %>
16+
</div>
17+
<% else %>
1418
<%= content %>
15-
</div>
16-
<% else %>
17-
<%= content %>
18-
<% end %>
19+
<% end %>
20+
<% if @field.copyable %>
21+
<%= render Avo::ClipboardComponent.new(value: @field.value) %>
22+
<% end %>
23+
</div>
1924
<% end %>
2025
<% if params[:avo_debug].present? %>
2126
<!-- Raw value: -->

app/javascript/js/application.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { Alert, Popover } from 'tailwindcss-stimulus-components'
22
import { Application } from '@hotwired/stimulus'
3-
import TextareaAutogrow from 'stimulus-textarea-autogrow'
3+
import Clipboard from '@stimulus-components/clipboard'
44
import PasswordVisibility from '@stimulus-components/password-visibility'
5+
import TextareaAutogrow from 'stimulus-textarea-autogrow'
56
import TurboPower from 'turbo_power'
67

78
TurboPower.initialize(window.Turbo.StreamActions)
89

910
const application = Application.start()
10-
application.register('textarea-autogrow', TextareaAutogrow)
11-
application.register('password-visibility', PasswordVisibility)
1211

1312
// Configure Stimulus development experience
1413
application.debug = window?.localStorage.getItem('avo.debug')
@@ -17,5 +16,8 @@ window.Stimulus = application
1716
// Register stimulus-components controller
1817
application.register('alert', Alert)
1918
application.register('popover', Popover)
19+
application.register('clipboard', Clipboard)
20+
application.register('password-visibility', PasswordVisibility)
21+
application.register('textarea-autogrow', TextareaAutogrow)
2022

2123
export { application }

lib/avo/fields/base_field.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class BaseField
4848
attr_reader :computable # if allowed to be computable
4949
attr_reader :computed # if block is present
5050
attr_reader :computed_value # the value after computation
51+
attr_reader :copyable # if allowed to be copyable
5152

5253
# Hydrated payload
5354
attr_accessor :record
@@ -87,6 +88,7 @@ def initialize(id, **args, &block)
8788
@components = args[:components] || {}
8889
@for_attribute = args[:for_attribute]
8990
@meta = args[:meta]
91+
@copyable = args[:copyable] || false
9092

9193
@args = args
9294

lib/generators/avo/templates/locales/avo.ar.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ ar:
3030
click_to_reveal_filters: انقر لإظهار المرشحات
3131
close_modal: أغلق النافذة
3232
confirm: تأكيد
33+
copy: نسخ
3334
create_new_item: إنشاء %{item} جديد
3435
dashboard: لوحة القيادة
3536
dashboards: لوحات القيادة

lib/generators/avo/templates/locales/avo.de.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ de:
2424
click_to_reveal_filters: Klicken, um Filter anzuzeigen
2525
close_modal: Modal schließen
2626
confirm: Bestätigen
27+
copy: Kopieren
2728
create_new_item: Neues %{item} erstellen
2829
dashboard: Dashboard
2930
dashboards: Dashboards

0 commit comments

Comments
 (0)