Skip to content

Commit

Permalink
Add notes to urls (#185)
Browse files Browse the repository at this point in the history
  • Loading branch information
jxjj authored Jun 10, 2024
1 parent d52f238 commit 1ec0b3e
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 12 deletions.
16 changes: 14 additions & 2 deletions app/controllers/urls_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
class UrlsController < ApplicationController
before_action :ensure_signed_in
before_action :set_url, only: %i[edit update destroy]
before_action :set_url_friendly, only: [:show]
before_action :set_url_friendly, only: %i[show update_note]
before_action :set_group, only: %i[index create]

# GET /urls
Expand Down Expand Up @@ -111,6 +111,18 @@ def update
end
end

# PUT/PATCH /urls/1/note
def update_note
respond_to do |format|
if @url.update(url_params)
format.html { redirect_to url_path(@url.keyword), notice: 'Note saved.' }
else
flash[:error] = @url.errors.full_messages.join(', ')
format.html { redirect_to url_path(@url.keyword) }
end
end
end

# DELETE /urls/1
# DELETE /urls/1.json
def destroy
Expand Down Expand Up @@ -161,7 +173,7 @@ def set_url_friendly
# Never trust parameters from the scary internet,
# only permit the allowlist through.
def url_params
params.require(:url).permit(:url, :keyword, :group_id, :modified_by)
params.require(:url).permit(:url, :keyword, :group_id, :modified_by, :note)
end

def set_group
Expand Down
1 change: 1 addition & 0 deletions app/datatables/url_datatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def view_columns
group_name: { source: 'Group.name' },
url: { source: 'Url.url' },
keyword: { source: 'Url.keyword' },
note: { source: 'Url.note' },
total_clicks: { source: 'Url.total_clicks', searchable: false },
created_at: { source: 'Url.created_at' },
# needed for actions like edit, delete, etc.
Expand Down
1 change: 1 addition & 0 deletions app/models/url.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Url < ApplicationRecord
multiline: true,
message: 'special characters are not permitted. Only letters, and numbers, dashes ("-") and underscores ("_")'
}
validates :note, length: { maximum: 1000 }, allow_blank: true
validate :check_for_valid_url

before_validation do
Expand Down
4 changes: 4 additions & 0 deletions app/policies/url_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def update?
user_has_access?
end

def update_note?
user_has_access?
end

def destroy?
user_has_access?
end
Expand Down
4 changes: 3 additions & 1 deletion app/views/urls/_short_url_table_cell.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<div class="short-url" data-cy="short-url-table-cell">
<%= link_to(display_keyword_url(url.keyword), full_url(url), target: '_blank') %>
<button class='btn btn-default clipboard-btn' data-clipboard-text="<%= full_url(url) %>">
Expand All @@ -9,3 +8,6 @@
<div class="long-url" data-cy="long-url-table-cell">
<%= link_to(url.url, url.url, target: '_blank') %>
</div>
<% if url.note.present? %>
<div class="tw-text-xs"><%= url.note %></div>
<% end %>
19 changes: 15 additions & 4 deletions app/views/urls/_sleek_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@
</div>
</div>
<%= f.hidden_field :group_id, value: @group.id if @group %>
<button type="submit" class="js-url-submit tw-block !tw-bg-umn-gold tw-py-4 tw-px-8 tw-rounded-b-md md:tw-rounded-r-md md:tw-rounded-bl-none hover:!tw-bg-umn-gold-light active:!tw-bg-umn-neutral-900 active:!tw-text-white focus:tw-ring focus:tw-ring-offset-2 tw-transition-colors">
<%= is_edit ? t('views.urls.sleek_form.edit.submit') : t('views.urls.sleek_form.new.submit') %>
</button>
<% if !is_edit %>
<button type="submit" class="js-url-submit tw-block !tw-bg-umn-gold tw-py-4 tw-px-8 tw-rounded-b-md md:tw-rounded-r-md md:tw-rounded-bl-none hover:!tw-bg-umn-gold-light active:!tw-bg-umn-neutral-900 active:!tw-text-white focus:tw-ring focus:tw-ring-offset-2 tw-transition-colors">
<%= t('views.urls.sleek_form.new.submit') %>
</button>
<% end %>
</div>
</div>
<% if is_edit %>
<a href="#" class='btn btn-default cancel-edit'><%= t('views.urls.sleek_form.edit.cancel')%></a>
<div class="tw-mt-2 tw-relative">
<%= f.label :note, "Note", class: 'tw-text-xs tw-font-bold tw-absolute', style: "top: 0.5rem; left: 1rem;" %>
<%= f.text_area :note, class: "tw-w-full tw-border-none tw-text-sm tw-rounded-lg !tw-text-black", style: "padding-top: 1.5rem; padding-left: 1rem; border-radius: 0.25rem;", data: { cy: 'note-input' } %>
</div>
<div class="tw-flex tw-items-center tw-justify-end tw-mt-2">
<button class='cancel-edit tw-py-2 tw-px-4 tw-rounded !tw-text-black tw-uppercase tw-text-xs' type="button"><%= t('views.urls.sleek_form.edit.cancel')%></button>
<button type="submit" class="js-url-submit tw-block !tw-bg-umn-gold tw-py-2 tw-px-4 tw-rounded hover:!tw-bg-umn-gold-light !tw-text-black focus:tw-ring focus:tw-ring-offset-2 tw-transition-colors">
<%= t('views.urls.sleek_form.edit.submit') %>
</button>
</div>
<% end %>
<div id="url-blurb-container">
</div>
Expand Down
17 changes: 17 additions & 0 deletions app/views/urls/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@
</div>
</div>
<div class="col-md-5">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">Note</div>
<div class="panel-body text-center">
<%= form_with model: @url, url: note_url_path(@url.keyword), method: :patch, data: { cy: 'note-form' } do |form|%>
<%= form.label :note, "Note", class: 'sr-only' %>
<%= form.text_area :note, class: 'form-control', placeholder: 'Add a note', data: { cy: 'note-input' } %>
<div class="tw-mt-2 tw-flex tw-justify-end tw-gap-2 tw-items-center">
<%= button_tag 'Reset', type: 'reset', class: "tw-uppercase tw-text-xs tw-bg-neutral-100 tw-px-4 tw-py-2 tw-rounded hover:tw-bg-neutral-200 tw-transition" %>
<%= form.button "Save", class: "btn btn-primary" %>
</div>
<% end %>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
Expand Down
12 changes: 8 additions & 4 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
on: :collection,
to: "url_csvs#show_aggregated",
as: "csv"
member do
patch :note, to: 'urls#update_note'
end
patch :note, on: :member, to: 'urls#update_note'
end

# transfer_requests transfer_requests index get
Expand Down Expand Up @@ -130,9 +134,9 @@
# admin/urls/create admin::urls create put
resources :urls, only: %i[index edit show update destroy create] do
get "csv/:duration/:time_unit",
on: :collection,
to: "url_csvs#show",
as: "csv"
on: :collection,
to: "url_csvs#show",
as: "csv"
end

# admin/audits/:search admin::urls index get
Expand All @@ -143,7 +147,7 @@
# admin/groups/:id
# admin/groups/:id/urls
# admin/groups/:id/members
resources :groups, only: [:index, :show] do
resources :groups, only: %i[index show] do
resources :urls, only: [:index], controller: "group_urls"
resources :members, only: [:index], controller: "group_members"
end
Expand Down
64 changes: 64 additions & 0 deletions cypress/e2e/urlNotes.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
describe("create zlink in collection", () => {
let url;
beforeEach(() => {
cy.app("clean");
cy.createUser("testuser").then((user) => {
url = cy.createUrl({
keyword: "cla",
url: "https://cla.umn.edu",
group_id: user.context_group_id,
});
});

cy.login("testuser");
});

context("url show page (aka stats page)", () => {
beforeEach(() => {
cy.visit("/shortener/urls/cla");
});

it("adds a note to a url", () => {
cy.get("[data-cy='note-form']").within(() => {
cy.get("[data-cy='note-input']").type("This is a note");
cy.contains("Save").click();
});

cy.contains("Note saved").should("be.visible");

// reload the page
cy.visit("/shortener/urls/cla");
// check that the note is there
cy.get("[data-cy='note-input']").should("contain", "This is a note");
});

it("limits the note contents to 1000 characters", () => {
cy.get("[data-cy='note-form']").within(() => {
cy.get("[data-cy='note-input']").type("a".repeat(1001), { delay: 0 });
cy.contains("Save").click();
});

cy.contains("Note is too long").should("be.visible");
});
});

context("url index page", () => {
beforeEach(() => {
cy.visit("/shortener/urls");
});

it("edits a note and shows it in the table", () => {
cy.get("#urls-table").contains("cla").closest("tr").as("claRow");
cy.get("@claRow").find(".dropdown").as("claDropdown");
cy.get("@claDropdown").find(".actions-dropdown-button").click();
cy.get("@claDropdown").contains("Edit").click();

cy.get("[data-cy='note-input']").type("edited note");

cy.contains("Submit").click();

// check that the note is in the table row
cy.get("@claRow").contains("edited note").should("be.visible");
});
});
});
5 changes: 5 additions & 0 deletions db/migrate/20240605133839_add_url_note.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddUrlNote < ActiveRecord::Migration[7.1]
def change
add_column :urls, :note, :text, null: true, default: nil
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_01_10_212461) do
ActiveRecord::Schema[7.1].define(version: 2024_06_05_133839) do
create_table "clicks", id: :integer, charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.string "country_code"
t.integer "url_id"
Expand Down Expand Up @@ -104,6 +104,7 @@
t.integer "modified_by"
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.text "note"
t.index ["group_id"], name: "index_urls_on_group_id"
t.index ["keyword"], name: "index_urls_on_keyword", unique: true
end
Expand Down

0 comments on commit 1ec0b3e

Please sign in to comment.