indentlabs/notebook

View on GitHub
app/views/timelines/edit.html.erb

Summary

Maintainability
Test Coverage
<%= render partial: 'notice_dismissal/messages/13' %>
<br />
<%= form_for @timeline, html: { class: 'autosave-form timeline-meta-form' }, remote: true do |f| %>
  <div class="row">
    <div class="col s12 m7 l9">
      <div class="input-field">
        <%= f.text_field :name, class: 'materialize-textarea js-trigger-autosave-on-change' %>
        <%= f.label :name, 'Timeline name' %>
      </div>
    </div>
    <div class="col s12 m4 l3 right">
      <!--
      <%= link_to '#', class: 'hoverable btn right ' + Timeline.color do %>
        <i class="material-icons small">star</i>
      <% end %>
      <%= link_to '#', class: 'hoverable btn right ' + Timeline.color do %>
        <i class="material-icons small"><%= Universe.icon %></i>
      <% end %>
      -->
      <%= link_to '#', class: 'share hoverable btn right ' + Timeline.color do %>
        <i class="material-icons small">share</i>
      <% end %>
    </div>
    <div class="col s12">
      <ul class="collapsible">
        <li>
          <div class="collapsible-header">
            <i class="material-icons <%= Timeline.text_color %>"><%= Timeline.icon %></i>
            About this timeline
          </div>
          <div class="collapsible-body">
            <div class="input-field">
              <%= f.text_area :subtitle, class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label :subtitle, 'Subtitle' %>
            </div>
            <div class="input-field">
              <%= f.text_area :description, class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label :description, 'Description' %>
            </div>
            <div class="input-field">
              <%= f.select :universe_id, current_user.universes.pluck(:name, :id), { include_blank: true }, class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label 'Universe' %>
            </div>
            <!--
            <div class="input-field">
              <%= f.select :privacy, [['Private', 'private'], ['Public', 'public']], class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label :privacy %>
            </div>
            -->
            
            <div class="input-field">
              <div class="input-field">
                <small><%= f.label :tags %></small>
                <div class="chips chips-autocomplete chips-initial"></div>
                <%= f.hidden_field :page_tags, value: @timeline.page_tags.join(PageTag::SUBMISSION_DELIMITER), 
                                               id: 'hidden_page_tags_value'
                %>

                <div class="help-text show-when-focused">
                  <i class="material-icons tiny"><%= PageTag.icon %></i>
                  Type and press enter to create a new tag.
                </div>
                <div class="tags-container show-when-focused">
                  <% @suggested_page_tags.each do |tag| %>
                    <%=
                      link_to '#', class: 'js-add-tag' do
                    %>
                      <span class="new badge grey left hoverable" data-badge-caption="<%= tag %>"></span>
                    <% end %>
                  <% end %>
                </div>
                <div class="clearfix"></div>
              </div>
            </div>
            <%= content_for :javascript do %>
              function update_hidden_page_tag_value(e) {
                var chips = M.Chips.getInstance($('.chips')).chipsData.map(function (c) {
                  return c['tag'];
                });

                var hidden_input = $('#hidden_page_tags_value').first();
                hidden_input.val(chips.join('<%= PageTag::SUBMISSION_DELIMITER %>'));
                $('form.timeline-meta-form').submit();

                M.toast({ html: 'Saving changes...' });
              }

              var chips = $('.chips-autocomplete').chips({
                placeholder: 'Tag this page',
                secondaryPlaceholder: '+ Tag',
                autocompleteOptions: {
                  data: {
                    <% @timeline.page_tags.pluck(:tag).each do |tag| %>
                      '<%= tag %>': null,
                    <% end %>
                  },
                  limit: 100,
                  minLength: 1
                },
                data: [
                  <% @timeline.page_tags.pluck(:tag).each do |tag| %>
                    {tag: '<%= tag %>'},
                  <% end %>
                ],
                onChipAdd:    update_hidden_page_tag_value,
                onChipDelete: update_hidden_page_tag_value
              });
            <% end %>
            
            <div class="input-field">
              <%= f.text_area :notes, class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label :notes %>
            </div>
            <div class="input-field">
              <%= f.text_area :private_notes, class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label :private_notes %>
            </div>
            <!--
            <div>
              Relevant links (view, edit, wiki view)
            </div>
            -->

            <div class="right">
              <%= link_to timeline_path(@timeline), method: :delete, data: { confirm: "Are you sure you want to delete this timeline? This cannot be undone!" } do %>
                <i class="material-icons left red-text">delete</i>
                <span class="red-text">Delete this timeline</span>
              <% end %>
            </div>
            <div class="clearfix"></div>
          </div>
        </li>
      </ul>
        
    </div>
  </div>
<% end %>

<div class="timeline-editor" data-timeline-id="<%= @timeline.id %>">
  <!--
  <div class="filter-bar">
    (filter events by character, location, etc)
  </div>
  -->

  <div class="timeline-events-container" data-timeline-id="<%= @timeline.id %>">
    <% @timeline.timeline_events.includes(:timeline_event_entities).each do |event| %>
      <div class="timeline-event-container" data-event-id="<%= event.id %>"  data-timeline-id="<%= @timeline.id %>">
        <%= form_for event, html: { class: 'autosave-form' }, remote: true do |f| %>
          <%= f.hidden_field :timeline_id %>
          <div class="row">
            <div class="col l2">
              <div class="input-field align-right">
                <%= f.text_area :time_label, class: 'materialize-textarea js-trigger-autosave-on-change' %>
                <%= f.label :time_label, 'Time label' %>
              </div>
              <div class="clearfix"></div>
              <ul>
                <li class="grey-text">Move this...</li>
                <li>
                  <%= link_to '#', class: 'js-move-event-to-top' do %>
                    <i class="material-icons tiny left">arrow_upward</i>
                    top
                  <% end %>
                </li>
                <li>
                  <%= link_to '#', class: 'js-move-event-up' do %>
                    <i class="material-icons tiny left">keyboard_arrow_up</i>
                    up
                  <% end %>
                </li>
                <li>
                  <%= link_to '#', class: 'js-move-event-down' do %>
                    <i class="material-icons tiny left">keyboard_arrow_down</i>
                    down
                  <% end %>
                </li>
                <li>
                  <%= link_to '#', class: 'js-move-event-to-bottom' do %>
                    <i class="material-icons tiny left">arrow_downward</i>
                    bottom
                  <% end %>
                </li>
              </ul>
            </div>
            <div class="col l1 cfenter" style="margin-bottom: -60px; margin-left: -7px; margin-right: -40px;">
              <%= image_tag 'graphics/timeline-line.webp' %>
            </div>
            <div class="col l6">
              <!--
              <div class="grey-text center">
                #<%= event.position %>
              </div>
              -->
              <div class="hoverable clearfix card <%# Timeline.color %>" style="border-top: 5px solid <%= Timeline.hex_color %>">
                <div class="card-content white-text">
                  <span class="card-title">
                    <div class="input-field">
                      <%= f.text_field :title, class: 'materialize-textarea js-trigger-autosave-on-change', id: "timeline-event-title-#{event.id}" %>
                      <%= f.label :title, 'Event Title', for: "timeline-event-title-#{event.id}" %>
                    </div>
                  </span>
                  <div class="input-field">
                    <%= f.text_area :description, class: 'materialize-textarea js-trigger-autosave-on-change', id: "timeline-event-description-#{event.id}" %>
                    <%= f.label :description, for: "timeline-event-description-#{event.id}" %>
                  </div>
                  <div class="input-field">
                    <%= f.text_area :notes, class: 'materialize-textarea js-trigger-autosave-on-change', id: "timeline-event-notes-#{event.id}" %>
                    <%= f.label :notes, for: "timeline-event-notes-#{event.id}" %>
                  </div>
                </div>
                <!--
                <div class="card-action">
                  <a href="#" class="left">Manage changes</a>
                  <a href="#" class="right">This is a link</a>
                  <div class="clearfix"></div>
                </div>
                -->
              </div>
              <div class="right">
                <%= link_to timeline_event_path(event), class: 'red-text', method: :delete, data: { confirm: "Are you sure you want to delete this event? It cannot be recovered!" } do %>
                  <small>Delete this event</small>
                <% end %>
              </div>
            </div>
            <div class="col l3">
              <div class="grey-text uppercase">
                In this event
              </div>
              <ul class="collapsible">
                <% event.timeline_event_entities.order('entity_type').preload(:entity).group_by(&:entity_type).each do |entity_type, entity_list| %>
                  <% entity_list.reject! { |te_entity| te_entity.entity.nil? } %>
                  <li>
                    <% klass = content_class_from_name(entity_type) %>
                    <div class="collapsible-header">
                      <i class="material-icons <%= klass.text_color %>"><%= klass.icon %></i>
                      <%= entity_type.pluralize %>
                      <span class="badge"><%= entity_list.count %></span>
                    </div>
                    <div class="collapsible-body">
                      <% entity_list.each do |te_entity| %>
                        <div class="chip">
                          <%= link_to(te_entity.entity.name.presence || "Untitled #{te_entity.entity_type}", te_entity.entity) %>
                          <%= link_to unlink_entity_timeline_event_path(id: event.id, entity_id: te_entity.id), method: :POST, remote: true do %>
                            <i class="close material-icons">close</i>
                          <% end %>
                        </div>
                      <% end %>
                    </div>
                  </li>
                <% end %>
              </ul>
              <p class="center">
                <small>
                  <%= link_to 'Link a page', '#', class: 'js-link-entity' %>
                </small>
              </p>

            </div>
          </div>
        <% end %>
      </div>
    <% end %>
  </div>

  <div class="timeline-event-template">
  
    <% event = TimelineEvent.new %>
    <div class="timeline-event-container" data-event-id="-1" data-timeline-id="<%= @timeline.id %>">
      <%# we have to do method: :patch in the template since event isn't persisted; we don't want it to POST instead %>
      <%= form_for event, html: { class: 'autosave-form' }, remote: true, method: :patch do |f| %>
        <%= f.hidden_field :timeline_id, value: @timeline.id %>
        <div class="row">
          <div class="col l2">
            <div class="input-field align-right">
              <%= f.text_area :time_label, class: 'materialize-textarea js-trigger-autosave-on-change' %>
              <%= f.label :time_label, 'Time label' %>
            </div>
            <div class="clearfix"></div>
            <ul>
              <li class="grey-text">Move this...</li>
              <li>
                <%= link_to '#', class: 'js-move-event-to-top' do %>
                  <i class="material-icons tiny left">arrow_upward</i>
                  top
                <% end %>
              </li>
              <li>
                <%= link_to '#', class: 'js-move-event-up' do %>
                  <i class="material-icons tiny left">keyboard_arrow_up</i>
                  up
                <% end %>
              </li>
              <li>
                <%= link_to '#', class: 'js-move-event-down' do %>
                  <i class="material-icons tiny left">keyboard_arrow_down</i>
                  down
                <% end %>
              </li>
              <li>
                <%= link_to '#', class: 'js-move-event-to-bottom' do %>
                  <i class="material-icons tiny left">arrow_downward</i>
                  bottom
                <% end %>
              </li>
            </ul>
          </div>
          <div class="col l1 cfenter" style="margin-bottom: -60px; margin-left: -7px; margin-right: -40px;">
            <%= image_tag 'graphics/timeline-line.webp' %>
          </div>
          <div class="col l6">
            <div class="hoverable clearfix card" style="border-top: 5px solid <%= Timeline.hex_color %>">
              <div class="card-content white-text">
                <span class="card-title">
                  <div class="input-field ref-title">
                    <%= f.text_field :title, class: 'materialize-textarea js-trigger-autosave-on-change' %>
                    <%= f.label :title, 'Event Title', for: "timeline-event-title-[[tid]]" %>
                  </div>
                </span>
                <div class="input-field ref-description">
                  <%= f.text_area :description, class: 'materialize-textarea js-trigger-autosave-on-change' %>
                  <%= f.label :description %>
                </div>
                <div class="input-field ref-notes">
                  <%= f.text_area :notes, class: 'materialize-textarea js-trigger-autosave-on-change' %>
                  <%= f.label :notes %>
                </div>
              </div>
            </div>
            <div class="right">
              <%= link_to timeline_event_path(id: event.id || 0), class: 'js-delete-timeline-event red-text', method: :delete, data: { confirm: "Are you sure you want to delete this event? It cannot be recovered!" } do %>
                <small>Delete this event</small>
              <% end %>
            </div>
          </div>
          <div class="col l3">
            <div class="grey-text uppercase">
              In this event
            </div>
            <ul class="collapsible">
              <% event.timeline_event_entities.order('entity_type').preload(:entity).group_by(&:entity_type).each do |entity_type, entity_list| %>
                <li>
                  <% klass = content_class_from_name(entity_type) %>
                  <div class="collapsible-header">
                    <i class="material-icons <%= klass.text_color %>"><%= klass.icon %></i>
                    <%= entity_type.pluralize %>
                    <span class="badge"><%= entity_list.count %></span>
                  </div>
                  <div class="collapsible-body">
                    <% entity_list.each do |te_entity| %>
                      <div class="chip">
                        <%= link_to("test", te_entity.entity) %>
                        <%= link_to unlink_entity_timeline_event_path(id: event.id, entity_id: te_entity.id), method: :POST, remote: true do %>
                          <i class="close material-icons">close</i>
                        <% end %>
                      </div>
                    <% end %>
                  </div>
                </li>
              <% end %>
            </ul>
            <p class="center">
              <small>
                <%= link_to 'Link a page', '#', class: 'js-link-entity' %>
              </small>
            </p>

          </div>
        </div>
      <% end %>
    </div>



  </div>
    
  <div class="row">
    <div class="col s12 center">
      <div class="loading-indicator">
        <div class="preloader-wrapper small active">
          <div class="spinner-layer spinner-green-only">
            <div class="circle-clipper left">
              <div class="circle"></div>
            </div><div class="gap-patch">
              <div class="circle"></div>
            </div><div class="circle-clipper right">
              <div class="circle"></div>
            </div>
          </div>
        </div>
      </div>

      <%= link_to 'Add an event', '#', class: 'btn black white-text', id: 'js-create-timeline-event' %>
    </div>
  </div>

</div>

<div id="entity-link-modal" class="modal">
  <input type="hidden" id="linking-event-id" value="-1" />
  <div class="modal-content">
    <h4>Link a page to this event</h4>
    <p>
      Select from your pages below.
    </p>
    <%= form_with url: '#', method: :post do |f| %>
      <%= f.hidden_field :timeline_id,          value: @timeline.id %>
      <%= f.hidden_field :entity_type,          value: nil %>
      <%= f.hidden_field :entity_id,            value: nil %>

      <% @current_user_content.each do |content_type, content_list| %>
        <% content_type_class = content_class_from_name(content_type) %>
        <h5><%= content_type.pluralize %></h5>
        <ul class="collection">
          <% content_list.each do |content| %>
            <a href="#" 
               class="<%= content_type_class.text_color %> js-link-entity-selection modal-close" 
               data-id="<%= content.id %>"
               data-type="<%= content_type %>">
              <li class="collection-item hoverable">
                <i class="material-icons left"><%= content_type_class.icon %></i>
                <%= content.name.presence || "Untitled #{content_type}" %>
                <span class="secondary-content">
                  <i class="material-icons">link</i>
                </span>
              </li>
            </a>
          <% end %>
        </ul>
      <% end %>
    <% end %>
  </div>
  <div class="modal-footer">
    <a href="#!" class="modal-close waves-effect waves-green btn-flat">Cancel</a>
  </div>
</div>

<%= render partial: 'content/share', locals: { shared_content: @timeline } %>

<%= content_for :javascript do %>
  $('.js-link-entity').click(function () {
    // Store the linking event ID for reference
    var event_id = $(this).closest('.timeline-event-container').data('event-id');
    $('#linking-event-id').val(event_id);

    // Open the modal
    $('#entity-link-modal').modal('open');
    return false;
  });

  $('.js-link-entity-selection').click(function () {
    var entity      = $(this);
    var entity_type = entity.data('type');
    var entity_id   = entity.data('id');

    var event_id = $('#linking-event-id').val();
    
    $.post(
      "/plan/timeline_events/" + event_id + "/link",
      {
        "entity_type": entity_type,
        "entity_id":   entity_id
      }
    ).done(function () {
      // todo update the UI somehow
      M.toast({
        html: 'Your ' + entity_type + ' was added successfully and will be visible the next time you reload this page.'
      });

      $('.modal').close();

      return false;
    }).fail(function() {
      alert("Something went wrong and your change didn't save. Please try again.");
    });

    // todo close the modal
  });
<% end %>