1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-19 13:19:39 +02:00

Feedback page (#1160)

* Add feedback page

* Only show latest release on changelog

* Constrain changelog height

* Ignore sanitization warning for Github content

* Add cassette for Github release notes

* Lint fix
This commit is contained in:
Zach Gollwitzer 2024-09-09 16:54:56 -04:00 committed by GitHub
parent c30c1b9698
commit eebc07d75e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 310 additions and 37 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

View file

@ -31,7 +31,7 @@ class PagesController < ApplicationController
end end
def changelog def changelog
@releases_notes = Provider::Github.new.fetch_latest_releases_notes @release_notes = Provider::Github.new.fetch_latest_release_notes
end end
def feedback def feedback

View file

@ -40,23 +40,24 @@ class Provider::Github
end end
end end
def fetch_latest_releases_notes def fetch_latest_release_notes
begin begin
Rails.cache.fetch("latest_github_releases_notes", expires_in: 2.hours) do Rails.cache.fetch("latest_github_release_notes", expires_in: 2.hours) do
releases = Octokit.releases(repo) release = Octokit.releases(repo).first
releases.map do |release| if release
{ {
avatar: release.author.avatar_url, avatar: release.author.avatar_url,
name: release.name, name: release.name,
published_at: release.published_at, published_at: release.published_at,
body: Octokit.markdown(release.body, mode: "gfm", context: repo) body: Octokit.markdown(release.body, mode: "gfm", context: repo)
} }
else
nil
end end
end end
rescue => e rescue => e
Rails.logger.error "Failed to fetch latest GitHub releases notes: #{e.message}" Rails.logger.error "Failed to fetch latest GitHub release notes: #{e.message}"
[] nil
end end
end end

View file

@ -2,29 +2,29 @@
<%= render "settings/nav" %> <%= render "settings/nav" %>
<% end %> <% end %>
<div class="space-y-4"> <div class="space-y-4 flex flex-col h-full">
<h1 class="text-gray-900 text-xl font-medium mb-4"><%= t(".title") %></h1> <h1 class="text-gray-900 text-xl font-medium mb-4"><%= t(".title") %></h1>
<div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4"> <div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4 flex-grow overflow-y-auto">
<% @releases_notes.each do |release_notes| %> <div class="flex justify-between gap-4 mb-12 last:mb-0">
<div class="flex justify-between gap-4 mb-12 last:mb-0"> <div class="w-1/3">
<div class="w-1/3"> <div class="px-3 flex items-center gap-3">
<div class="px-3 flex items-center gap-3"> <div class="text-white shrink-0 w-9 h-9">
<div class="text-white shrink-0 w-9 h-9"> <%= image_tag @release_notes[:avatar], class: "rounded-full w-full h-full object-cover" %>
<%= image_tag release_notes[:avatar], class: "rounded-full w-full h-full object-cover" %> </div>
</div> <div>
<div> <div class="text-gray-900 font-medium text-sm"><%= @release_notes[:name] %></div>
<div class="text-gray-900 font-medium text-sm"><%= release_notes[:name] %></div> <div class="text-gray-500 text-sm"><%= @release_notes[:published_at].strftime("%B %d, %Y") %></div>
<div class="text-gray-500 text-sm"><%= release_notes[:published_at].strftime("%B %d, %Y") %></div>
</div>
</div> </div>
</div> </div>
<div class="w-2/3 text-gray-500 text-sm prose prose--github-release-notes">
<h2 class="mb-5 text-xl text-gray-900"><%= release_notes[:name] %></h2>
<%= release_notes[:body].html_safe %>
</div>
</div> </div>
<% end %> <div class="w-2/3 text-gray-500 text-sm prose prose--github-release-notes">
<h2 class="mb-5 text-xl text-gray-900"><%= @release_notes[:name] %></h2>
<%= @release_notes[:body].html_safe %>
</div>
</div>
</div> </div>
<%= settings_nav_footer %> <div class="mt-auto">
<%= settings_nav_footer %>
</div>
</div> </div>

View file

@ -5,8 +5,23 @@
<div class="space-y-4"> <div class="space-y-4">
<h1 class="text-gray-900 text-xl font-medium mb-4">Feedback</h1> <h1 class="text-gray-900 text-xl font-medium mb-4">Feedback</h1>
<div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4"> <div class="bg-white shadow-xs border border-alpha-black-25 rounded-xl p-4">
<div class="flex justify-center items-center py-20"> <h2 class="text-lg font-medium text-gray-900 mb-1">Leave feedback</h2>
<p class="text-gray-500">Feedback coming soon...</p> <p class="text-sm text-gray-500 mb-4">Let us know if you have any specific feedback. Feel free to include links to videos or screenshots.</p>
<div class="flex gap-2">
<%= link_to "https://github.com/maybe-finance/maybe/discussions/categories/feature-requests", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.png", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-gray-900">Write a feature request</span>
<% end %>
<%= link_to "https://github.com/maybe-finance/maybe/issues/new?assignees=&labels=bug&template=bug_report.md&title=", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "github-icon.png", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-gray-900">File a bug report</span>
<% end %>
<%= link_to "https://link.maybe.co/discord", target: "_blank", rel: "noopener noreferrer", class: "w-1/3 flex flex-col items-center p-4 border border-alpha-black-25 rounded-xl hover:bg-gray-50" do %>
<%= image_tag "discord-icon.png", class: "w-8 h-8 mb-2" %>
<span class="text-sm font-medium text-gray-900">Discuss Maybe with others</span>
<% end %>
</div> </div>
</div> </div>

View file

@ -23,6 +23,40 @@
], ],
"note": "" "note": ""
}, },
{
"warning_type": "Cross-Site Scripting",
"warning_code": 2,
"fingerprint": "b1f821a5c03b8aa348fb21b9297081a3bf9e954244290e7e511c67213d35f3dc",
"check_name": "CrossSiteScripting",
"message": "Unescaped model attribute",
"file": "app/views/pages/changelog.html.erb",
"line": 22,
"link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
"code": "Provider::Github.new.fetch_latest_release_notes[:body]",
"render_path": [
{
"type": "controller",
"class": "PagesController",
"method": "changelog",
"line": 35,
"file": "app/controllers/pages_controller.rb",
"rendered": {
"name": "pages/changelog",
"file": "app/views/pages/changelog.html.erb"
}
}
],
"location": {
"type": "template",
"template": "pages/changelog"
},
"user_input": null,
"confidence": "High",
"cwe_id": [
79
],
"note": ""
},
{ {
"warning_type": "Dynamic Render Path", "warning_type": "Dynamic Render Path",
"warning_code": 15, "warning_code": 15,
@ -58,6 +92,6 @@
"note": "" "note": ""
} }
], ],
"updated": "2024-08-23 08:29:05 -0400", "updated": "2024-09-09 14:56:48 -0400",
"brakeman_version": "6.2.1" "brakeman_version": "6.2.1"
} }

View file

@ -9,4 +9,11 @@ class PagesControllerTest < ActionDispatch::IntegrationTest
get root_path get root_path
assert_response :ok assert_response :ok
end end
test "changelog" do
VCR.use_cassette("git_repository_provider/fetch_latest_release_notes") do
get changelog_path
assert_response :ok
end
end
end end

View file

@ -18,14 +18,16 @@ class SettingsTest < ApplicationSystemTestCase
end end
test "can access settings from sidebar" do test "can access settings from sidebar" do
open_settings_from_sidebar VCR.use_cassette("git_repository_provider/fetch_latest_release_notes") do
assert_selector "h1", text: "Account" open_settings_from_sidebar
assert_current_path settings_profile_path assert_selector "h1", text: "Account"
assert_current_path settings_profile_path
@settings_links.each do |name, path| @settings_links.each do |name, path|
click_link name click_link name
assert_selector "h1", text: name assert_selector "h1", text: name
assert_current_path path assert_current_path path
end
end end
end end

File diff suppressed because one or more lines are too long