ideasbugs 0.5.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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +114 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +339 -0
  5. data/Rakefile +19 -0
  6. data/app/controllers/ideasbugs/application_controller.rb +15 -0
  7. data/app/controllers/ideasbugs/feedbacks_controller.rb +156 -0
  8. data/app/controllers/ideasbugs/screenshots_controller.rb +27 -0
  9. data/app/helpers/ideasbugs/widget_helper.rb +18 -0
  10. data/app/models/ideasbugs/application_record.rb +7 -0
  11. data/app/models/ideasbugs/feedback.rb +30 -0
  12. data/app/views/ideasbugs/feedbacks/index.html.erb +78 -0
  13. data/app/views/ideasbugs/feedbacks/show.html.erb +63 -0
  14. data/app/views/layouts/ideasbugs/application.html.erb +76 -0
  15. data/config/locales/ideasbugs.ar.yml +24 -0
  16. data/config/locales/ideasbugs.bg.yml +24 -0
  17. data/config/locales/ideasbugs.bn.yml +24 -0
  18. data/config/locales/ideasbugs.de.yml +24 -0
  19. data/config/locales/ideasbugs.el.yml +24 -0
  20. data/config/locales/ideasbugs.en.yml +47 -0
  21. data/config/locales/ideasbugs.es.yml +24 -0
  22. data/config/locales/ideasbugs.fr.yml +24 -0
  23. data/config/locales/ideasbugs.hi.yml +24 -0
  24. data/config/locales/ideasbugs.hr.yml +24 -0
  25. data/config/locales/ideasbugs.id.yml +24 -0
  26. data/config/locales/ideasbugs.it.yml +24 -0
  27. data/config/locales/ideasbugs.ja.yml +24 -0
  28. data/config/locales/ideasbugs.ko.yml +24 -0
  29. data/config/locales/ideasbugs.lb.yml +24 -0
  30. data/config/locales/ideasbugs.nl.yml +24 -0
  31. data/config/locales/ideasbugs.pl.yml +24 -0
  32. data/config/locales/ideasbugs.pt.yml +24 -0
  33. data/config/locales/ideasbugs.ro.yml +24 -0
  34. data/config/locales/ideasbugs.ru.yml +24 -0
  35. data/config/locales/ideasbugs.th.yml +24 -0
  36. data/config/locales/ideasbugs.tr.yml +24 -0
  37. data/config/locales/ideasbugs.uk.yml +24 -0
  38. data/config/locales/ideasbugs.ur.yml +24 -0
  39. data/config/locales/ideasbugs.vi.yml +24 -0
  40. data/config/locales/ideasbugs.zh-CN.yml +24 -0
  41. data/config/routes.rb +12 -0
  42. data/lib/generators/ideasbugs/install/install_generator.rb +41 -0
  43. data/lib/generators/ideasbugs/install/templates/create_ideasbugs_feedbacks.rb.tt +21 -0
  44. data/lib/generators/ideasbugs/install/templates/initializer.rb +47 -0
  45. data/lib/ideasbugs/configuration.rb +93 -0
  46. data/lib/ideasbugs/engine.rb +13 -0
  47. data/lib/ideasbugs/version.rb +5 -0
  48. data/lib/ideasbugs/widget.js +387 -0
  49. data/lib/ideasbugs/widget.rb +109 -0
  50. data/lib/ideasbugs.rb +34 -0
  51. metadata +113 -0
@@ -0,0 +1,24 @@
1
+ ja:
2
+ ideasbugs:
3
+ button: "フィードバック"
4
+ title: "バグ報告・機能リクエストを送信"
5
+ kind: "種類"
6
+ kinds:
7
+ bug: "バグ報告"
8
+ feature: "機能リクエスト"
9
+ other: "その他"
10
+ section: "セクション"
11
+ section_any: "全般"
12
+ message: "メッセージ"
13
+ message_placeholder: "ご意見をお聞かせください…"
14
+ screenshots: "スクリーンショット"
15
+ screenshots_hint: "任意、最大%{count}ファイル、各%{size} MB"
16
+ submit: "送信"
17
+ cancel: "キャンセル"
18
+ close: "閉じる"
19
+ thanks: "フィードバックありがとうございます!"
20
+ error_blank: "メッセージを入力してください。"
21
+ error_save: "送信できませんでした。もう一度お試しください。"
22
+ error_too_many: "スクリーンショットが多すぎます(最大%{count}枚)。"
23
+ error_too_large: "スクリーンショットが大きすぎます(最大%{size} MB)。"
24
+ error_rate_limited: "送信回数が多すぎます。しばらく待ってからもう一度お試しください。"
@@ -0,0 +1,24 @@
1
+ ko:
2
+ ideasbugs:
3
+ button: "피드백"
4
+ title: "버그 신고 / 기능 요청 보내기"
5
+ kind: "유형"
6
+ kinds:
7
+ bug: "버그 신고"
8
+ feature: "기능 요청"
9
+ other: "기타"
10
+ section: "섹션"
11
+ section_any: "일반"
12
+ message: "메시지"
13
+ message_placeholder: "의견을 들려주세요…"
14
+ screenshots: "스크린샷"
15
+ screenshots_hint: "선택 사항, 최대 %{count}개 파일, 각 %{size} MB"
16
+ submit: "피드백 보내기"
17
+ cancel: "취소"
18
+ close: "닫기"
19
+ thanks: "피드백 감사합니다!"
20
+ error_blank: "메시지를 입력해 주세요."
21
+ error_save: "피드백을 보낼 수 없습니다. 다시 시도해 주세요."
22
+ error_too_many: "스크린샷이 너무 많습니다 (최대 %{count}개)."
23
+ error_too_large: "스크린샷이 너무 큽니다 (최대 %{size} MB)."
24
+ error_rate_limited: "제출이 너무 많습니다. 잠시 후 다시 시도해 주세요."
@@ -0,0 +1,24 @@
1
+ lb:
2
+ ideasbugs:
3
+ button: "Feedback"
4
+ title: "Feeler mellen / Funktioun ufroen"
5
+ kind: "Typ"
6
+ kinds:
7
+ bug: "Feeler mellen"
8
+ feature: "Funktioun ufroen"
9
+ other: "Aneres"
10
+ section: "Beräich"
11
+ section_any: "Allgemeng"
12
+ message: "Är Noriicht"
13
+ message_placeholder: "Sot eis, wat Iech um Häerz läit…"
14
+ screenshots: "Screenshots"
15
+ screenshots_hint: "optional, bis zu %{count} Fichieren, all %{size} MB"
16
+ submit: "Feedback schécken"
17
+ cancel: "Ofbriechen"
18
+ close: "Zoumaachen"
19
+ thanks: "Merci fir Äre Feedback!"
20
+ error_blank: "Gitt w.e.g. eng Noriicht an."
21
+ error_save: "Konnt net geschéckt ginn. Probéiert w.e.g. nach eng Kéier."
22
+ error_too_many: "Ze vill Screenshots (max. %{count})."
23
+ error_too_large: "E Screenshot ass ze grouss (max. %{size} MB)."
24
+ error_rate_limited: "Ze vill Envoien. Waart w.e.g. e Moment a probéiert nach eng Kéier."
@@ -0,0 +1,24 @@
1
+ nl:
2
+ ideasbugs:
3
+ button: "Feedback"
4
+ title: "Fout melden / functie aanvragen"
5
+ kind: "Type"
6
+ kinds:
7
+ bug: "Fout melden"
8
+ feature: "Functieverzoek"
9
+ other: "Overig"
10
+ section: "Sectie"
11
+ section_any: "Algemeen"
12
+ message: "Je bericht"
13
+ message_placeholder: "Vertel ons wat je bezighoudt…"
14
+ screenshots: "Schermafbeeldingen"
15
+ screenshots_hint: "optioneel, maximaal %{count} bestanden, elk %{size} MB"
16
+ submit: "Feedback versturen"
17
+ cancel: "Annuleren"
18
+ close: "Sluiten"
19
+ thanks: "Bedankt voor je feedback!"
20
+ error_blank: "Voer een bericht in."
21
+ error_save: "Versturen mislukt. Probeer het opnieuw."
22
+ error_too_many: "Te veel schermafbeeldingen (max. %{count})."
23
+ error_too_large: "Een schermafbeelding is te groot (max. %{size} MB)."
24
+ error_rate_limited: "Te veel inzendingen. Wacht even en probeer het opnieuw."
@@ -0,0 +1,24 @@
1
+ pl:
2
+ ideasbugs:
3
+ button: "Opinie"
4
+ title: "Zgłoś błąd / zaproponuj funkcję"
5
+ kind: "Typ"
6
+ kinds:
7
+ bug: "Zgłoszenie błędu"
8
+ feature: "Propozycja funkcji"
9
+ other: "Inne"
10
+ section: "Sekcja"
11
+ section_any: "Ogólne"
12
+ message: "Twoja wiadomość"
13
+ message_placeholder: "Powiedz nam, co myślisz…"
14
+ screenshots: "Zrzuty ekranu"
15
+ screenshots_hint: "opcjonalnie, do %{count} plików, po %{size} MB każdy"
16
+ submit: "Wyślij opinię"
17
+ cancel: "Anuluj"
18
+ close: "Zamknij"
19
+ thanks: "Dziękujemy za opinię!"
20
+ error_blank: "Wpisz wiadomość."
21
+ error_save: "Nie udało się wysłać opinii. Spróbuj ponownie."
22
+ error_too_many: "Za dużo zrzutów ekranu (maks. %{count})."
23
+ error_too_large: "Zrzut ekranu jest za duży (maks. %{size} MB)."
24
+ error_rate_limited: "Zbyt wiele zgłoszeń. Odczekaj chwilę i spróbuj ponownie."
@@ -0,0 +1,24 @@
1
+ pt:
2
+ ideasbugs:
3
+ button: "Feedback"
4
+ title: "Relatar erro / sugerir funcionalidade"
5
+ kind: "Tipo"
6
+ kinds:
7
+ bug: "Relatar erro"
8
+ feature: "Sugestão de funcionalidade"
9
+ other: "Outro"
10
+ section: "Seção"
11
+ section_any: "Geral"
12
+ message: "Sua mensagem"
13
+ message_placeholder: "Conte-nos o que você pensa…"
14
+ screenshots: "Capturas de tela"
15
+ screenshots_hint: "opcional, até %{count} arquivos, %{size} MB cada"
16
+ submit: "Enviar feedback"
17
+ cancel: "Cancelar"
18
+ close: "Fechar"
19
+ thanks: "Obrigado pelo seu feedback!"
20
+ error_blank: "Por favor, escreva uma mensagem."
21
+ error_save: "Não foi possível enviar. Tente novamente."
22
+ error_too_many: "Muitas capturas de tela (máx. %{count})."
23
+ error_too_large: "Uma captura é grande demais (máx. %{size} MB)."
24
+ error_rate_limited: "Envios demais. Aguarde um momento e tente novamente."
@@ -0,0 +1,24 @@
1
+ ro:
2
+ ideasbugs:
3
+ button: "Feedback"
4
+ title: "Raportează o eroare / cere o funcționalitate"
5
+ kind: "Tip"
6
+ kinds:
7
+ bug: "Raportează o eroare"
8
+ feature: "Cerere de funcționalitate"
9
+ other: "Altele"
10
+ section: "Secțiune"
11
+ section_any: "General"
12
+ message: "Mesajul tău"
13
+ message_placeholder: "Spune-ne ce părere ai…"
14
+ screenshots: "Capturi de ecran"
15
+ screenshots_hint: "opțional, până la %{count} fișiere, fiecare de %{size} MB"
16
+ submit: "Trimite feedback"
17
+ cancel: "Anulează"
18
+ close: "Închide"
19
+ thanks: "Mulțumim pentru feedback!"
20
+ error_blank: "Te rugăm să introduci un mesaj."
21
+ error_save: "Trimiterea a eșuat. Încearcă din nou."
22
+ error_too_many: "Prea multe capturi de ecran (max. %{count})."
23
+ error_too_large: "O captură de ecran este prea mare (max. %{size} MB)."
24
+ error_rate_limited: "Prea multe trimiteri. Așteaptă un moment și încearcă din nou."
@@ -0,0 +1,24 @@
1
+ ru:
2
+ ideasbugs:
3
+ button: "Обратная связь"
4
+ title: "Сообщить об ошибке / предложить функцию"
5
+ kind: "Тип"
6
+ kinds:
7
+ bug: "Сообщить об ошибке"
8
+ feature: "Предложить функцию"
9
+ other: "Другое"
10
+ section: "Раздел"
11
+ section_any: "Общее"
12
+ message: "Ваше сообщение"
13
+ message_placeholder: "Расскажите, что у вас на уме…"
14
+ screenshots: "Скриншоты"
15
+ screenshots_hint: "необязательно, до %{count} файлов, по %{size} МБ"
16
+ submit: "Отправить отзыв"
17
+ cancel: "Отмена"
18
+ close: "Закрыть"
19
+ thanks: "Спасибо за ваш отзыв!"
20
+ error_blank: "Пожалуйста, введите сообщение."
21
+ error_save: "Не удалось отправить. Попробуйте ещё раз."
22
+ error_too_many: "Слишком много скриншотов (макс. %{count})."
23
+ error_too_large: "Скриншот слишком большой (макс. %{size} МБ)."
24
+ error_rate_limited: "Слишком много отправок. Подождите немного и попробуйте ещё раз."
@@ -0,0 +1,24 @@
1
+ th:
2
+ ideasbugs:
3
+ button: "ข้อเสนอแนะ"
4
+ title: "ส่งรายงานข้อบกพร่อง / ขอฟีเจอร์"
5
+ kind: "ประเภท"
6
+ kinds:
7
+ bug: "รายงานข้อบกพร่อง"
8
+ feature: "ขอฟีเจอร์"
9
+ other: "อื่น ๆ"
10
+ section: "ส่วน"
11
+ section_any: "ทั่วไป"
12
+ message: "ข้อความของคุณ"
13
+ message_placeholder: "บอกเราว่าคุณคิดอย่างไร…"
14
+ screenshots: "ภาพหน้าจอ"
15
+ screenshots_hint: "ไม่บังคับ สูงสุด %{count} ไฟล์ ไฟล์ละ %{size} MB"
16
+ submit: "ส่งข้อเสนอแนะ"
17
+ cancel: "ยกเลิก"
18
+ close: "ปิด"
19
+ thanks: "ขอบคุณสำหรับข้อเสนอแนะ!"
20
+ error_blank: "กรุณากรอกข้อความ"
21
+ error_save: "ส่งไม่สำเร็จ กรุณาลองอีกครั้ง"
22
+ error_too_many: "ภาพหน้าจอมากเกินไป (สูงสุด %{count})"
23
+ error_too_large: "ภาพหน้าจอมีขนาดใหญ่เกินไป (สูงสุด %{size} MB)"
24
+ error_rate_limited: "ส่งบ่อยเกินไป กรุณารอสักครู่แล้วลองอีกครั้ง"
@@ -0,0 +1,24 @@
1
+ tr:
2
+ ideasbugs:
3
+ button: "Geri bildirim"
4
+ title: "Hata bildir / özellik iste"
5
+ kind: "Tür"
6
+ kinds:
7
+ bug: "Hata bildirimi"
8
+ feature: "Özellik isteği"
9
+ other: "Diğer"
10
+ section: "Bölüm"
11
+ section_any: "Genel"
12
+ message: "Mesajınız"
13
+ message_placeholder: "Bize düşüncelerinizi anlatın…"
14
+ screenshots: "Ekran görüntüleri"
15
+ screenshots_hint: "isteğe bağlı, en fazla %{count} dosya, her biri %{size} MB"
16
+ submit: "Geri bildirim gönder"
17
+ cancel: "İptal"
18
+ close: "Kapat"
19
+ thanks: "Geri bildiriminiz için teşekkürler!"
20
+ error_blank: "Lütfen bir mesaj girin."
21
+ error_save: "Gönderilemedi. Lütfen tekrar deneyin."
22
+ error_too_many: "Çok fazla ekran görüntüsü (en fazla %{count})."
23
+ error_too_large: "Bir ekran görüntüsü çok büyük (en fazla %{size} MB)."
24
+ error_rate_limited: "Çok fazla gönderim. Lütfen biraz bekleyip tekrar deneyin."
@@ -0,0 +1,24 @@
1
+ uk:
2
+ ideasbugs:
3
+ button: "Відгук"
4
+ title: "Повідомити про помилку / запропонувати функцію"
5
+ kind: "Тип"
6
+ kinds:
7
+ bug: "Повідомити про помилку"
8
+ feature: "Запропонувати функцію"
9
+ other: "Інше"
10
+ section: "Розділ"
11
+ section_any: "Загальне"
12
+ message: "Ваше повідомлення"
13
+ message_placeholder: "Розкажіть, що у вас на думці…"
14
+ screenshots: "Знімки екрана"
15
+ screenshots_hint: "необов'язково, до %{count} файлів, по %{size} МБ"
16
+ submit: "Надіслати відгук"
17
+ cancel: "Скасувати"
18
+ close: "Закрити"
19
+ thanks: "Дякуємо за ваш відгук!"
20
+ error_blank: "Будь ласка, введіть повідомлення."
21
+ error_save: "Не вдалося надіслати. Спробуйте ще раз."
22
+ error_too_many: "Забагато знімків екрана (макс. %{count})."
23
+ error_too_large: "Знімок екрана завеликий (макс. %{size} МБ)."
24
+ error_rate_limited: "Забагато надсилань. Зачекайте хвилинку та спробуйте ще раз."
@@ -0,0 +1,24 @@
1
+ ur:
2
+ ideasbugs:
3
+ button: "رائے"
4
+ title: "خرابی کی اطلاع / فیچر کی درخواست بھیجیں"
5
+ kind: "قسم"
6
+ kinds:
7
+ bug: "خرابی کی اطلاع"
8
+ feature: "فیچر کی درخواست"
9
+ other: "دیگر"
10
+ section: "سیکشن"
11
+ section_any: "عمومی"
12
+ message: "آپ کا پیغام"
13
+ message_placeholder: "ہمیں بتائیں آپ کیا سوچ رہے ہیں…"
14
+ screenshots: "اسکرین شاٹس"
15
+ screenshots_hint: "اختیاری، زیادہ سے زیادہ %{count} فائلیں، ہر ایک %{size} MB"
16
+ submit: "رائے بھیجیں"
17
+ cancel: "منسوخ کریں"
18
+ close: "بند کریں"
19
+ thanks: "آپ کی رائے کا شکریہ!"
20
+ error_blank: "براہ کرم پیغام درج کریں۔"
21
+ error_save: "رائے نہیں بھیجی جا سکی۔ دوبارہ کوشش کریں۔"
22
+ error_too_many: "بہت زیادہ اسکرین شاٹس (زیادہ سے زیادہ %{count})۔"
23
+ error_too_large: "ایک اسکرین شاٹ بہت بڑا ہے (زیادہ سے زیادہ %{size} MB)۔"
24
+ error_rate_limited: "بہت زیادہ ارسالات۔ براہ کرم تھوڑا انتظار کریں اور دوبارہ کوشش کریں۔"
@@ -0,0 +1,24 @@
1
+ vi:
2
+ ideasbugs:
3
+ button: "Phản hồi"
4
+ title: "Gửi báo lỗi / yêu cầu tính năng"
5
+ kind: "Loại"
6
+ kinds:
7
+ bug: "Báo lỗi"
8
+ feature: "Yêu cầu tính năng"
9
+ other: "Khác"
10
+ section: "Mục"
11
+ section_any: "Chung"
12
+ message: "Tin nhắn của bạn"
13
+ message_placeholder: "Hãy cho chúng tôi biết suy nghĩ của bạn…"
14
+ screenshots: "Ảnh chụp màn hình"
15
+ screenshots_hint: "tùy chọn, tối đa %{count} tệp, mỗi tệp %{size} MB"
16
+ submit: "Gửi phản hồi"
17
+ cancel: "Hủy"
18
+ close: "Đóng"
19
+ thanks: "Cảm ơn phản hồi của bạn!"
20
+ error_blank: "Vui lòng nhập tin nhắn."
21
+ error_save: "Không thể gửi phản hồi. Vui lòng thử lại."
22
+ error_too_many: "Quá nhiều ảnh chụp màn hình (tối đa %{count})."
23
+ error_too_large: "Một ảnh chụp màn hình quá lớn (tối đa %{size} MB)."
24
+ error_rate_limited: "Gửi quá nhiều lần. Vui lòng đợi một lát rồi thử lại."
@@ -0,0 +1,24 @@
1
+ zh-CN:
2
+ ideasbugs:
3
+ button: "反馈"
4
+ title: "提交错误报告 / 功能请求"
5
+ kind: "类型"
6
+ kinds:
7
+ bug: "错误报告"
8
+ feature: "功能请求"
9
+ other: "其他"
10
+ section: "板块"
11
+ section_any: "常规"
12
+ message: "您的留言"
13
+ message_placeholder: "告诉我们您的想法……"
14
+ screenshots: "截图"
15
+ screenshots_hint: "可选,最多 %{count} 个文件,每个 %{size} MB"
16
+ submit: "发送反馈"
17
+ cancel: "取消"
18
+ close: "关闭"
19
+ thanks: "感谢您的反馈!"
20
+ error_blank: "请输入留言。"
21
+ error_save: "发送失败,请重试。"
22
+ error_too_many: "截图过多(最多 %{count} 张)。"
23
+ error_too_large: "有一张截图过大(最多 %{size} MB)。"
24
+ error_rate_limited: "提交过于频繁,请稍候再试。"
data/config/routes.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ideasbugs::Engine.routes.draw do
4
+ # create is the public widget endpoint; the rest is the triage dashboard.
5
+ resources :feedbacks, only: %i[create index show update destroy] do
6
+ # Screenshots stream through the dashboard's own gate, never via public
7
+ # Active Storage blob URLs.
8
+ resources :screenshots, only: :show
9
+ end
10
+
11
+ root to: 'feedbacks#index'
12
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/active_record'
5
+
6
+ module Ideasbugs
7
+ module Generators
8
+ class InstallGenerator < Rails::Generators::Base
9
+ include ActiveRecord::Generators::Migration
10
+
11
+ source_root File.expand_path('templates', __dir__)
12
+
13
+ desc 'Installs ideasbugs: config initializer, migration, and engine mount.'
14
+
15
+ def create_initializer
16
+ copy_file 'initializer.rb', 'config/initializers/ideasbugs.rb'
17
+ end
18
+
19
+ def create_feedbacks_migration
20
+ migration_template 'create_ideasbugs_feedbacks.rb.tt',
21
+ 'db/migrate/create_ideasbugs_feedbacks.rb'
22
+ end
23
+
24
+ def mount_engine
25
+ route %(mount Ideasbugs::Engine => "/feedback")
26
+ end
27
+
28
+ def post_install
29
+ say "\nideasbugs installed. Run `rails db:migrate`, then add", :green
30
+ say '`<%= ideasbugs_tag %>` before </body> in your layout.'
31
+ say "Browse submissions at /feedback (development only until you set config.authorize_admin).\n"
32
+ end
33
+
34
+ private
35
+
36
+ def migration_version
37
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateIdeasbugsFeedbacks < ActiveRecord::Migration<%= migration_version %>
4
+ def change
5
+ create_table :ideasbugs_feedbacks do |t|
6
+ t.string :kind, null: false, default: 'other'
7
+ t.string :section
8
+ t.text :message, null: false
9
+ t.string :status, null: false, default: 'open'
10
+ t.string :page_url
11
+ t.string :user_agent
12
+ t.string :author_id
13
+ t.string :author_label
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :ideasbugs_feedbacks, :status
19
+ add_index :ideasbugs_feedbacks, :kind
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ Ideasbugs.configure do |config|
4
+ # Who can send feedback. Return false to hide the widget and reject
5
+ # submissions for this request. Defaults to everyone.
6
+ # config.enabled = ->(request) { true }
7
+
8
+ # Who can browse and triage feedback at the mount path. Defaults to
9
+ # development only — override before deploying.
10
+ # config.authorize_admin = ->(request) { request.env["warden"]&.user&.admin? }
11
+
12
+ # Attribute feedback to a user (optional). Return an object responding to
13
+ # #id, or nil. Receives the request.
14
+ # config.current_user = ->(request) { request.env["warden"]&.user }
15
+
16
+ # Label stored for the author and shown in the dashboard.
17
+ # config.author_label = ->(user) { user.try(:email) }
18
+
19
+ # Feedback types users can pick from. Labels come from I18n
20
+ # (ideasbugs.kinds.<kind>).
21
+ # config.kinds = %w[bug feature other]
22
+
23
+ # App areas shown as a select in the widget. Empty list hides the select.
24
+ # config.sections = ["Dashboard", "Billing", "Settings"]
25
+
26
+ # Screenshot uploads (requires Active Storage).
27
+ # config.screenshots = true
28
+ # config.max_screenshots = 3
29
+ # config.max_screenshot_size = 5.megabytes
30
+
31
+ # Per-IP throttle for the submission endpoint (Rails 7.2+; ignored on 7.1).
32
+ # Keyword arguments for Rails' rate limiter; nil disables throttling.
33
+ # config.rate_limit = { to: 10, within: 1.minute }
34
+
35
+ # Show the floating feedback button. Set false and add
36
+ # `data-ideasbugs-open` to any element to trigger the form yourself.
37
+ # config.show_button = true
38
+
39
+ # Fixed button text; leave nil to use the localized default.
40
+ # config.button_label = nil
41
+
42
+ # Keep in sync with the `mount` in config/routes.rb.
43
+ # config.mount_path = "/feedback"
44
+
45
+ # Called with each saved feedback — notify Slack, send an email, etc.
46
+ # config.on_submit = ->(feedback) { FeedbackMailer.with(feedback:).new_feedback.deliver_later }
47
+ end
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ideasbugs
4
+ # Host-tunable settings. Everything has a safe default, so a fresh install
5
+ # works with zero configuration; the hooks below let an app decide who can
6
+ # send feedback, who can read it, and how submissions are attributed.
7
+ class Configuration
8
+ # Per-request gate for the widget and the submission endpoint. Return false
9
+ # to hide the widget and reject submissions for this request. Receives the
10
+ # request. Defaults to everyone — feedback collection is meant for real
11
+ # users in production.
12
+ attr_accessor :enabled
13
+
14
+ # Per-request gate for the built-in dashboard (browse and triage feedback).
15
+ # Receives the request. Defaults to development only — override it before
16
+ # deploying, e.g. with an admin check.
17
+ attr_accessor :authorize_admin
18
+
19
+ # Resolve the current user for attribution (optional). Return an object
20
+ # responding to #id, or nil. Receives the request.
21
+ attr_accessor :current_user
22
+
23
+ # Turn a resolved user into a short label stored alongside the feedback and
24
+ # shown in the dashboard. Receives whatever #current_user returned.
25
+ attr_accessor :author_label
26
+
27
+ # The feedback types a user can pick from. Labels resolve through I18n
28
+ # (`ideasbugs.kinds.<kind>`), so you can rename or add kinds freely.
29
+ attr_accessor :kinds
30
+
31
+ # Optional list of app areas ("Billing", "Dashboard", …) shown as a select
32
+ # in the widget. Leave empty to hide the select entirely.
33
+ attr_accessor :sections
34
+
35
+ # Allow screenshot uploads. Requires Active Storage in the host app; the
36
+ # widget hides the upload control when this is false or Active Storage is
37
+ # not set up.
38
+ attr_accessor :screenshots
39
+
40
+ # Upload limits, enforced server-side and mirrored in the widget.
41
+ attr_accessor :max_screenshots, :max_screenshot_size
42
+
43
+ # Per-IP throttle for the public submission endpoint, as keyword arguments
44
+ # for Rails' rate limiter (Rails 7.2+; ignored on 7.1). Read once when the
45
+ # controller loads — set it in an initializer. nil disables throttling.
46
+ attr_accessor :rate_limit
47
+
48
+ # Show the floating feedback button. Set false to trigger the widget from
49
+ # your own UI instead: any element with a `data-ideasbugs-open`
50
+ # attribute opens the form.
51
+ attr_accessor :show_button
52
+
53
+ # Text on the floating button. Leave nil to use the localized default
54
+ # (the `ideasbugs.button` I18n key).
55
+ attr_accessor :button_label
56
+
57
+ # Where the engine is mounted. The widget posts to
58
+ # "#{mount_path}/feedbacks", so keep this in sync with the `mount` line in
59
+ # your routes.
60
+ attr_accessor :mount_path
61
+
62
+ # Called with each saved feedback — notify Slack, send an email, open a
63
+ # ticket. Runs inline after save; keep it fast or hand off to a job.
64
+ attr_accessor :on_submit
65
+
66
+ def initialize
67
+ @enabled = ->(_request) { true }
68
+ @authorize_admin = ->(_request) { Rails.env.development? }
69
+ @current_user = ->(_request) {}
70
+ @author_label = ->(user) { user.respond_to?(:email) ? user.email : user&.to_s }
71
+ @kinds = %w[bug feature other]
72
+ @sections = []
73
+ @screenshots = true
74
+ @max_screenshots = 3
75
+ @max_screenshot_size = 5 * 1024 * 1024
76
+ @rate_limit = { to: 10, within: 60 }
77
+ @show_button = true
78
+ @button_label = nil
79
+ @mount_path = '/feedback'
80
+ @on_submit = ->(_feedback) {}
81
+ end
82
+
83
+ def feedbacks_endpoint
84
+ "#{mount_path.chomp('/')}/feedbacks"
85
+ end
86
+
87
+ # Screenshots need Active Storage — both the config switch and the host
88
+ # actually having it loaded.
89
+ def screenshots_enabled?
90
+ screenshots && defined?(::ActiveStorage) ? true : false
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ideasbugs
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Ideasbugs
6
+
7
+ initializer 'ideasbugs.helper' do
8
+ ActiveSupport.on_load(:action_view) do
9
+ include Ideasbugs::WidgetHelper
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ideasbugs
4
+ VERSION = '0.5.0'
5
+ end