From 438a7b4eeff8f92e5dbf1d1ee18ded12deb29f38 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Wed, 10 Jun 2020 15:04:51 -0500 Subject: [PATCH] timelines#index --- app/controllers/timelines_controller.rb | 101 ++++++++++++++++++ app/helpers/timelines_helper.rb | 2 + app/models/concerns/has_content.rb | 1 + app/models/page_types/universe.rb | 2 +- app/models/timeline.rb | 28 +++++ app/views/layouts/_sidenav.html.erb | 23 ++-- app/views/timelines/_form.html.erb | 17 +++ app/views/timelines/edit.html.erb | 6 ++ app/views/timelines/index.html.erb | 92 ++++++++++++++++ app/views/timelines/new.html.erb | 5 + app/views/timelines/show.html.erb | 4 + config/routes.rb | 6 +- test/controllers/timelines_controller_test.rb | 48 +++++++++ test/system/timelines_test.rb | 41 +++++++ 14 files changed, 364 insertions(+), 12 deletions(-) create mode 100644 app/controllers/timelines_controller.rb create mode 100644 app/helpers/timelines_helper.rb create mode 100644 app/views/timelines/_form.html.erb create mode 100644 app/views/timelines/edit.html.erb create mode 100644 app/views/timelines/index.html.erb create mode 100644 app/views/timelines/new.html.erb create mode 100644 app/views/timelines/show.html.erb create mode 100644 test/controllers/timelines_controller_test.rb create mode 100644 test/system/timelines_test.rb diff --git a/app/controllers/timelines_controller.rb b/app/controllers/timelines_controller.rb new file mode 100644 index 00000000..bcf2f7e7 --- /dev/null +++ b/app/controllers/timelines_controller.rb @@ -0,0 +1,101 @@ +class TimelinesController < ApplicationController + before_action :set_timeline, only: [:show, :edit, :update, :destroy] + + before_action :set_navbar_color + before_action :set_navbar_actions + before_action :set_sidenav_expansion + + # GET /timelines + def index + @timelines = current_user.timelines + end + + # GET /timelines/1 + def show + end + + # GET /timelines/new + def new + @timeline = Timeline.new + end + + # GET /timelines/1/edit + def edit + end + + # POST /timelines + def create + @timeline = Timeline.new(timeline_params) + + if @timeline.save + redirect_to @timeline, notice: 'Timeline was successfully created.' + else + render :new + end + end + + # PATCH/PUT /timelines/1 + def update + if @timeline.update(timeline_params) + redirect_to @timeline, notice: 'Timeline was successfully updated.' + else + render :edit + end + end + + # DELETE /timelines/1 + def destroy + @timeline.destroy + redirect_to timelines_url, notice: 'Timeline was successfully destroyed.' + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_timeline + @timeline = Timeline.find(params[:id]) + end + + # Only allow a trusted parameter "white list" through. + def timeline_params + params.fetch(:timeline, {}) + end + + def set_navbar_color + @navbar_color = Timeline.hex_color.presence || '#2196F3' + end + + def set_navbar_actions + # content_type = @content_type_class || content_type_from_controller(self.class) + # @navbar_actions = [] + + # return if [AttributeCategory, AttributeField].include?(content_type) + + # if user_signed_in? + # if @current_user_content + # @navbar_actions << { + # label: "Your #{view_context.pluralize @current_user_content.fetch(content_type.name, []).count, content_type.name.downcase}", + # href: main_app.polymorphic_path(content_type) + # } + # end + + # @navbar_actions << { + # label: "New #{content_type.name.downcase}", + # href: main_app.new_polymorphic_path(content_type), + # class: 'right' + # } + # end + + # discussions_link = ForumsLinkbuilderService.worldbuilding_url(content_type) + # if discussions_link.present? + # @navbar_actions << { + # label: 'Discussions', + # href: discussions_link + # } + # end + end + + def set_sidenav_expansion + @sidenav_expansion = 'writing' + end +end diff --git a/app/helpers/timelines_helper.rb b/app/helpers/timelines_helper.rb new file mode 100644 index 00000000..1f1a4f07 --- /dev/null +++ b/app/helpers/timelines_helper.rb @@ -0,0 +1,2 @@ +module TimelinesHelper +end diff --git a/app/models/concerns/has_content.rb b/app/models/concerns/has_content.rb index 689a5ad0..7448fb6b 100644 --- a/app/models/concerns/has_content.rb +++ b/app/models/concerns/has_content.rb @@ -10,6 +10,7 @@ module HasContent #has_many :characters, :locations, etc has_many content_type_sym, dependent: :destroy end + has_many :timelines has_many :attribute_fields has_many :attribute_categories diff --git a/app/models/page_types/universe.rb b/app/models/page_types/universe.rb index bb20c232..ca6d4884 100644 --- a/app/models/page_types/universe.rb +++ b/app/models/page_types/universe.rb @@ -15,7 +15,7 @@ class Universe < ApplicationRecord include Authority::Abilities self.authorizer_name = 'UniverseCoreContentAuthorizer' - validates :name, presence: true + validates :name, presence: true validates :user_id, presence: true belongs_to :user diff --git a/app/models/timeline.rb b/app/models/timeline.rb index 608e663b..083fc77b 100644 --- a/app/models/timeline.rb +++ b/app/models/timeline.rb @@ -1,4 +1,32 @@ class Timeline < ApplicationRecord + acts_as_paranoid + + include IsContentPage + include Authority::Abilities + self.authorizer_name = 'ExtendedContentAuthorizer' + belongs_to :universe belongs_to :user + + validates :user_id, presence: true + + def self.content_name + 'timeline' + end + + def description + 'A timeline' + end + + def self.color + 'green' + end + + def self.hex_color + '#4CAF50' + end + + def self.icon + 'timeline' + end end diff --git a/app/views/layouts/_sidenav.html.erb b/app/views/layouts/_sidenav.html.erb index 67666fb3..c398c6ed 100644 --- a/app/views/layouts/_sidenav.html.erb +++ b/app/views/layouts/_sidenav.html.erb @@ -96,12 +96,6 @@
diff --git a/app/views/timelines/_form.html.erb b/app/views/timelines/_form.html.erb new file mode 100644 index 00000000..a9c5c179 --- /dev/null +++ b/app/views/timelines/_form.html.erb @@ -0,0 +1,17 @@ +<%= form_with(model: timeline, local: true) do |form| %> + <% if timeline.errors.any? %> +
+

<%= pluralize(timeline.errors.count, "error") %> prohibited this timeline from being saved:

+ + +
+ <% end %> + +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/timelines/edit.html.erb b/app/views/timelines/edit.html.erb new file mode 100644 index 00000000..aa01817f --- /dev/null +++ b/app/views/timelines/edit.html.erb @@ -0,0 +1,6 @@ +

Editing Timeline

+ +<%= render 'form', timeline: @timeline %> + +<%= link_to 'Show', @timeline %> | +<%= link_to 'Back', timelines_path %> diff --git a/app/views/timelines/index.html.erb b/app/views/timelines/index.html.erb new file mode 100644 index 00000000..3a2dfbd5 --- /dev/null +++ b/app/views/timelines/index.html.erb @@ -0,0 +1,92 @@ +<%= content_for :full_width_page_header do %> + <%= render partial: 'content/components/parallax_header', locals: { content_type: 'Timeline', content_class: Timeline } %> +<% end %> + +<% if @timelines.any? %> + +
+
+ <%# render partial: 'content/components/list_filter_bar', locals: { content_type: Timeline } %> +
+ <%# render partial: 'content/list/cards', locals: { content_list: @content, content_type: @content_type_class, show_add_another_form: true, show_template_editor_form: true } %> +
+ + <% if @show_scope_notice %> +

+ Only showing timelines + in the <%= link_to @universe_scope.name, @universe_scope, class: Universe.color + '-text' %> universe. + <%= link_to( + "See timelines from all universes.", + '?universe=all', + class: Timeline.color + '-text') + %> +

+ <% end %> + +<% elsif @timelines.empty? %> + +
+ <% if @current_user_content.fetch('Timeline', []).count > 0 %> +
+ <%# render partial: 'content/components/list_filter_bar', locals: { content_type: Timeline } %> +
+ <% end %> + +
+
+

+ You haven't created any timelines + <% if @universe_scope %> + in the <%= link_to @universe_scope.name, @universe_scope %> universe + <% end %> + <% if params.key?(:favorite_only) || params.key?(:slug) %> + that match these filters + <% end %> + yet! +

+

+ + <%= Timeline.icon %> + +

+

+ <%= t("content_descriptions.timelines") %> +

+ + <% if current_user.can_create?(Timeline) || PermissionService.user_has_active_promotion_for_this_content_type(user: current_user, content_type: 'Timeline') %> + <%= link_to "Create your first timeline", new_timeline_path(), class: "btn-large #{Timeline.color} darken-1" %> + <% else %> + <%= link_to "Upgrade to Premium to create your first timeline", subscription_path %> + <% end %> + +

+ <% 5.times { %><%= Timeline.icon %>    <%}%> +

+
+
+
+ +
+ <% if @universe_scope %> +
+
+
+
+ Focus on another universe +
+

+ You're currently focused on the + <%= link_to @universe_scope.name, @universe_scope, class: Universe.color + '-text' %> + universe and only seeing timelines in that + universe. +

+
+

+ You can change what universe you're focused on by selecting a different one in the sidebar. +

+
+
+
+ <% end %> +
+<% end %> diff --git a/app/views/timelines/new.html.erb b/app/views/timelines/new.html.erb new file mode 100644 index 00000000..8b2d8518 --- /dev/null +++ b/app/views/timelines/new.html.erb @@ -0,0 +1,5 @@ +

New Timeline

+ +<%= render 'form', timeline: @timeline %> + +<%= link_to 'Back', timelines_path %> diff --git a/app/views/timelines/show.html.erb b/app/views/timelines/show.html.erb new file mode 100644 index 00000000..290d3824 --- /dev/null +++ b/app/views/timelines/show.html.erb @@ -0,0 +1,4 @@ +

<%= notice %>

+ +<%= link_to 'Edit', edit_timeline_path(@timeline) %> | +<%= link_to 'Back', timelines_path %> diff --git a/config/routes.rb b/config/routes.rb index 69b54c8b..d03a97de 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -73,7 +73,7 @@ Rails.application.routes.draw do get '/scratchpad', to: 'main#notes', as: :notes - # Legacy routes: left intact so /my/documents/X URLs continue to work for everyone's bookmarks + # Legacy route: left intact so /my/documents/X URLs continue to work for everyone's bookmarks resources :documents # Billing @@ -184,6 +184,7 @@ end get '/tagged/:slug', action: :index, on: :collection, as: :page_tag end end + resources :timelines # Content attributes put '/content/sort', to: 'content#api_sort' @@ -195,9 +196,6 @@ end # Attributes get ':content_type/attributes', to: 'content#attributes', as: :attribute_customization - - # Coming Soon TM - get '/plots', to: 'main#comingsoon' end get 'search/', to: 'search#results' diff --git a/test/controllers/timelines_controller_test.rb b/test/controllers/timelines_controller_test.rb new file mode 100644 index 00000000..edad3334 --- /dev/null +++ b/test/controllers/timelines_controller_test.rb @@ -0,0 +1,48 @@ +require 'test_helper' + +class TimelinesControllerTest < ActionDispatch::IntegrationTest + setup do + @timeline = timelines(:one) + end + + test "should get index" do + get timelines_url + assert_response :success + end + + test "should get new" do + get new_timeline_url + assert_response :success + end + + test "should create timeline" do + assert_difference('Timeline.count') do + post timelines_url, params: { timeline: { } } + end + + assert_redirected_to timeline_url(Timeline.last) + end + + test "should show timeline" do + get timeline_url(@timeline) + assert_response :success + end + + test "should get edit" do + get edit_timeline_url(@timeline) + assert_response :success + end + + test "should update timeline" do + patch timeline_url(@timeline), params: { timeline: { } } + assert_redirected_to timeline_url(@timeline) + end + + test "should destroy timeline" do + assert_difference('Timeline.count', -1) do + delete timeline_url(@timeline) + end + + assert_redirected_to timelines_url + end +end diff --git a/test/system/timelines_test.rb b/test/system/timelines_test.rb new file mode 100644 index 00000000..32305373 --- /dev/null +++ b/test/system/timelines_test.rb @@ -0,0 +1,41 @@ +require "application_system_test_case" + +class TimelinesTest < ApplicationSystemTestCase + setup do + @timeline = timelines(:one) + end + + test "visiting the index" do + visit timelines_url + assert_selector "h1", text: "Timelines" + end + + test "creating a Timeline" do + visit timelines_url + click_on "New Timeline" + + click_on "Create Timeline" + + assert_text "Timeline was successfully created" + click_on "Back" + end + + test "updating a Timeline" do + visit timelines_url + click_on "Edit", match: :first + + click_on "Update Timeline" + + assert_text "Timeline was successfully updated" + click_on "Back" + end + + test "destroying a Timeline" do + visit timelines_url + page.accept_confirm do + click_on "Destroy", match: :first + end + + assert_text "Timeline was successfully destroyed" + end +end