Browse Source

Implement `stimulus_reflex`

pull/11/head
alexdbondoc17 4 years ago
parent
commit
7948c9036f
  1. 14
      app/channels/application_cable/connection.rb
  2. 6
      app/components/annotation_marks_modal_form_component/annotation_marks_modal_form_component.html.erb
  3. 9
      app/components/desicions_index_component.rb
  4. 5
      app/components/doctrine_modal_form_component.rb
  5. 4
      app/components/doctrine_modal_form_component/doctrine_modal_form_component.html.erb
  6. 7
      app/components/document_doctrine_show_component.rb
  7. 69
      app/components/document_doctrine_show_component/document_doctrine_show_component.html.erb
  8. 31
      app/components/document_index_table_body_component.rb
  9. 5
      app/components/document_index_table_body_component/document_index_table_body_component.html.erb
  10. 4
      app/components/document_index_table_component.rb
  11. 57
      app/components/document_index_table_component/document_index_table_component.html.erb
  12. 20
      app/components/sidenav_component/sidenav_component.html.erb
  13. 18
      app/components/subjects_sidenav_sub_menu_component/subjects_sidenav_sub_menu_component.html.erb
  14. 4
      app/controllers/concerns/jurisprudence_search.rb
  15. 1
      app/controllers/documents_controller.rb
  16. 11
      app/controllers/subject_indexes_controller.rb
  17. 66
      app/javascript/controllers/application_controller.js
  18. 17
      app/javascript/controllers/document_controller.js
  19. 73
      app/javascript/controllers/example_controller.js
  20. 18
      app/javascript/controllers/hello_controller.js
  21. 14
      app/javascript/controllers/index.js
  22. 11
      app/javascript/controllers/select2_controller.js
  23. 10
      app/javascript/controllers/subjects_controller.js
  24. 4
      app/javascript/packs/application.js
  25. 1
      app/models/cdao/subject.rb
  26. 12
      app/reflexes/application_reflex.rb
  27. 12
      app/reflexes/document_reflex.rb
  28. 35
      app/reflexes/example_reflex.rb
  29. 7
      app/reflexes/subjects_reflex.rb
  30. 2
      app/views/document/doctrines/show.html.erb
  31. 2
      app/views/documents/show.html.erb
  32. 1
      app/views/layouts/application.html.erb
  33. 5
      config/routes.rb
  34. 2
      package.json
  35. 12
      yarn.lock

14
app/channels/application_cable/connection.rb

@ -1,4 +1,18 @@
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
private
def find_verified_user
if verified_user = User.find_by(id: cookies.encrypted[:user_id])
verified_user
else
reject_unauthorized_connection
end
end
end
end

6
app/components/annotation_marks_modal_form_component/annotation_marks_modal_form_component.html.erb

@ -8,10 +8,10 @@
<div class="modal-body">
<div class="row">
<div class="col-sm-12 p-2">
<div class="col-sm-12 p-2" data-controller="select2">
<%= label_tag :annotation_marks %>
<%= hidden_field_tag :document_id, opts[:document_id] %>
<%= select_tag "annomark_ids[]", options_from_collection_for_select(Annomark.all, :id, :name, annotation.annomark_ids), class: "form-select i-chosen", multiple: true, prompt: "Please select" %>
<%= select_tag "annomark_ids[]", options_from_collection_for_select(Annomark.all, :id, :name, annotation.annomark_ids), class: "form-select annomark-ids-select2", multiple: true, prompt: "Please select" %>
</div>
</div>
<div class="row">
@ -31,7 +31,7 @@
<div class="row">
<div class="col-sm-12 p-2">
<%= label_tag :editor_notes %>
<trix-editor id="editor_notes" placeholder="Editor Notes"> <%= editor_notes %> </trix-editor>
<trix-editor id="editor_notes" placeholder="Editor Notes"> <%= annotation.editor_notes %> </trix-editor>
</div>
</div>
</div>

9
app/components/desicions_index_component.rb

@ -0,0 +1,9 @@
class DesicionsIndexComponent < BaseComponent
with_collection_parameter :search_result
attr_reader :search_result, :opts
def initialize(search_result:, current_user:, opts: {})
@search_result = search_result
@opts = opts
end
end

5
app/components/doctrine_modal_form_component.rb

@ -1,8 +1,9 @@
class DoctrineModalFormComponent < BaseComponent
attr_reader :doctrine, :opts
attr_reader :doctrine, :subjects, :opts
def initialize(current_user:, doctrine:, opts:)
def initialize(current_user:, doctrine:, subjects:, opts:)
@doctrine = doctrine
@subjects = subjects
@opts = opts
end

4
app/components/doctrine_modal_form_component/doctrine_modal_form_component.html.erb

@ -9,9 +9,9 @@
<div class="modal-body">
<div class="row">
<div class="col-sm-12 p-2">
<div class="col-sm-12 p-2" data-controller="select2">
<strong> <%= label_tag :subjects %> </strong>
<%= select_tag "subject_ids[]", options_from_collection_for_select(Cdao::Subject.all, :id, :lineage_name, doctrine.subject_ids), class: "form-select i-chosen", multiple: true, prompt: "Please select" %>
<%= select_tag "subject_ids[]", options_from_collection_for_select(subjects, :id, :lineage_name, doctrine.subject_ids), class: "form-select subject-ids-modal-select2", multiple: true, prompt: "Please select" %>
</div>
</div>

7
app/components/document_doctrine_show_component.rb

@ -1,9 +1,10 @@
class DocumentDoctrineShowComponent < BaseComponent
attr_reader :current_user, :doctrine
attr_reader :current_user, :doctrine, :subjects
def initialize(current_user:, doctrine:, opts: {})
def initialize(current_user:, doctrine:, subjects:, opts: {})
@doctrine = doctrine
@current_user = current_user
@subjects = subjects
end
delegate :id, to: :doctrine
@ -23,6 +24,6 @@ class DocumentDoctrineShowComponent < BaseComponent
end
def annotation_form_url
doctrine_annotations_path(doctrine_id: id)
doctrine_annotations_path(doctrine_id: id,)
end
end

69
app/components/document_doctrine_show_component/document_doctrine_show_component.html.erb

@ -1,22 +1,26 @@
<div class="card clickable">
<h5 class="card-header">
Doctrine Details
<a class="btn btn-sm btn-primary justify-content-end" data-bs-toggle="modal" data-bs-target="#doctrineModal">
<i class="fas fa-edit" data-toggle="tooltip" data-placement="bottom" title="Edit Doctrine"></i>
</a>
</h5>
<div class="card-body">
<div class="card">
<div class="card-header">
<div class="row">
<div class="container-sm row-flex col-sm-12 mt-2">
<%= render(DoctrineModalFormComponent.new(current_user: current_user, doctrine: doctrine, opts: { form_url: jurisprudence_doctrine_path(jurisprudence_id: document_id, id: doctrine.id), form_method: "PUT" })) %>
<div class="col-sm-10">
<h5> Doctrine Details </h5>
</div>
<div class="col-sm-2 justify-content-end">
<a class="btn btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#doctrineModal"> Edit </a>
<a class="btn btn-sm btn-danger" href="<%= jurisprudence_doctrine_path(document_id, id) %>" data-confirm="Are you sure to delete this record?" data-method="DELETE"> Delete </a>
</div>
</div>
<%= form_tag(doctrine_form_url, method: :patch) do %>
<div class="row">
<div class="container-sm row-flex col-sm-12 mt-2">
<%= render(DoctrineModalFormComponent.new(current_user: current_user, doctrine: doctrine, subjects: subjects, opts: { form_url: jurisprudence_doctrine_path(jurisprudence_id: document_id, id: doctrine.id), form_method: "PUT" })) %>
</div>
</div>
<div class="card-body">
<%= form_tag(doctrine_form_url, method: :patch, local: true) do %>
<div class="row" data-controller="select2">
<strong> <%= label_tag :subjects %> </strong>
<%= select_tag "subject_ids[]", options_from_collection_for_select(Cdao::Subject.all, :id, :lineage_name, subject_ids), class: "form-select i-chosen", multiple: true, prompt: "Please select" %>
<%= select_tag "subjects_ids[]", options_from_collection_for_select(Cdao::Subject.all, :id, :lineage_name, subject_ids), class: "form-select subjects-select2", multiple: true, prompt: "Please select" %>
</div>
<div class="row">
@ -35,13 +39,12 @@
</div>
<div class="collapse mb-3" id="caseListsCollapse">
<div class="row">
<div class="row" data-controller="document" data-document-id="<%= document_id %>" data-doctrine-id="<%= id %>">
<div class="col-sm-10 p-2">
<%= text_field_tag :q, nil, class: "form-control", placeholder: "Search GR Number" %>
<%= text_field_tag :q, nil, class: "form-control", placeholder: "Search GR Number", data: { target: "document.input" } %>
</div>
<div class="col-sm-1 p-2">
<%= button_tag "search", class: "btn btn-primary" %>
<%= button_tag "Search", class: "btn btn-primary", data: { action: "click->document#search" } %>
</div>
</div>
@ -54,9 +57,7 @@
<th class="bg-light"> </th>
</thead>
<tbody>
<%= render(DocumentIndexTableComponent.with_collection(Cdao::Jurisprudence.first(5), current_user: current_user, opts: { is_case_lists: true, form_url: annotation_form_url, form_method: :post, document_id: document_id })) %>
</tbody>
<tbody id="documentIndexTable"> </tbody>
</table>
</div>
</div>
@ -66,19 +67,27 @@
<div class="card-body">
<% doctrine.annotations.order(rank: :asc).each do |annotation| %>
<div class="container-sm ms-1">
<p>
<strong> <%= "#{annotation.annomarks.map { |annomark| "(#{annomark.code})" }.join(" ")}" %> </strong>
<%= raw [annotation.document.title, annotation.document.reference_number, annotation.document.docdate.strftime("%B %d, %Y"), annotation.phil_rep].join(', ').html_safe %>
<a class="btn btn-sm btn-primary justify-content-end" data-bs-toggle="modal" data-bs-target="#editAnnotationModal<%= annotation.id %>">
<i class="fas fa-edit" data-toggle="tooltip" data-placement="bottom" title="Edit Annotation Marks"></i>
</a>
</p>
<div class="row">
<div class="col-sm-10">
<p>
<strong> <%= "#{annotation.annomarks.map { |annomark| "(#{annomark.code})" }.join(" ")}" %> </strong>
<%= raw [annotation.document.title, annotation.document.reference_number, annotation.document.docdate.strftime("%B %d, %Y"), annotation.phil_rep].join(', ').html_safe %>
</p>
</div>
<div class="col-sm-2">
<a class="btn btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#editAnnotationModal<%= annotation.id %>"> Edit </a>
<a class="btn btn-sm btn-danger" href="<%= doctrine_annotation_path(doctrine.id, annotation.id) %>" data-confirm="Are you sure to delete this record?" data-method="DELETE"> Delete </a>
</div>
<div>
<% if annotation.editor_notes.present? %>
<span class="ms-3"> Editors Note: <%= annotation.editor_notes %> </span>
<% end %>
</div>
<div class="row">
<div class="row annotation-marks-modal-container">
<div class="modal fade" id="editAnnotationModal<%= annotation.id %>" tabindex="-1" aria-labelledby="annotationModal" aria-hidden="true">
<%= render AnnotationMarksModalFormComponent.new(current_user: current_user, document: document, annotation: annotation, opts: { form_url: doctrine_annotation_path(id, annotation.id), form_method: "PUT" }) %>
</div>

31
app/components/document_index_table_body_component.rb

@ -0,0 +1,31 @@
class DocumentIndexTableBodyComponent < BaseComponent
with_collection_parameter :search_result
attr_reader :search_result, :opts
def initialize(search_result:, current_user:, opts: {})
@search_result = search_result
@opts = opts
end
def reference_number
search_result["reference_number"]
end
def title
search_result["title"]
end
def date_or_year
return search_result["docdate"].to_date.strftime("%m/%d/%Y") if search_result["docdate"].present?
search_result["year"]
end
def form_url
doctrine_annotations_path(doctrine_id: opts[:doctrine_id])
end
def render?
search_result.present?
end
end

5
app/components/document_index_table_body_component/document_index_table_body_component.html.erb

@ -0,0 +1,5 @@
<tr>
<td> <%= reference_number %> </td>
<td> <%= title %> </td>
<td> <%= date_or_year %> </td>
</tr>

4
app/components/document_index_table_component.rb

@ -15,4 +15,8 @@ class DocumentIndexTableComponent < BaseComponent
search_result.year
end
def doctrine_annotations_path(doctrine_id)
doctrine_annotations_path(doctrine_id: doctrine_id)
end
end

57
app/components/document_index_table_component/document_index_table_component.html.erb

@ -1,60 +1,5 @@
<tr href="<%= document_path(search_result) %>" class="<%= opts.reject{ |k, v| v.blank? }.blank? ? 'clickable-tr' : ''%>">
<tr href="<%= document_path(search_result.id) %>" class="<%= opts.reject{ |k, v| v.blank? }.blank? ? 'clickable-tr' : ''%>">
<td> <%= reference_number %> </td>
<td> <%= title %> </td>
<td> <%= date_or_year %> </td>
<% if opts[:is_case_lists].present? && opts[:form_url].present? && opts[:document_id].present? %>
<td>
<a class="btn btn-sm btn-primary" data-bs-toggle="modal" data-bs-target="#annotationModal<%= search_result.id %>">
<i class="fas fa-plus-circle" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Add"></i>
</a>
<div class="modal fade" id="annotationModal<%= search_result.id %>" tabindex="-1" aria-labelledby="annotationModal" aria-hidden="true">
<%= form_tag(opts[:form_url], method: :post) do%>
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">New Annotation Marks</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-sm-12 p-2">
<%= label_tag :annotation_marks %>
<%= hidden_field_tag :document_id, opts[:document_id] %>
<%= select_tag "annomark_ids[]", options_from_collection_for_select(Annomark.all, :id, :name, params[:annomark_ids]), class: "form-select i-chosen", multiple: true, prompt: "Please select" %>
</div>
</div>
<div class="row">
<div class="col-sm-12 p-2">
<%= label_tag :document_title %>
<%= text_area_tag :document_title, [title, reference_number, date_or_year].join(", "), class: "form-control" %>
</div>
</div>
<div class="row">
<div class="col-sm-12 p-2">
<%= label_tag :phil_rep %>
<%= text_field_tag :phil_rep, params[:phil_rep], class: "form-control" %>
</div>
</div>
<div class="row">
<div class="col-sm-12 p-2">
<%= label_tag :editor_notes %>
<trix-editor id="editor_notes" placeholder="Doctrine Content"> <%= params[:editor_notes] %> </trix-editor>
</div>
</div>
</div>
<div class="modal-footer">
<%= submit_tag "Save", class: "btn btn-primary" %>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
<% end %>
</div>
</td>
<% end %>
</tr>

20
app/components/sidenav_component/sidenav_component.html.erb

@ -10,7 +10,25 @@
</button>
</div>
<%= render(SubjectsSidenavSubMenuComponent.new(current_user: current_user, opts: { main_sub_menu: "mainSubjectIndexSubMenu", second_sub_menu: "secondSubjectIndexSubMenu", third_sub_menu: "thirdSubjectIndexSubMenu", fourth_sub_menu: "fourthSubjectIndexSubMenu", fifth_sub_menu: "fifthSubjectIndexSubMenu" })) %>
<div class="accordion-collapse collapse" id="mainSubjectIndexSubMenu" data-bs-parent="#sidenav">
<div class="accordion-body pb-0 pe-0 pt-0">
<% Cdao::Subject.roots.each do |root| %>
<div class="accordion accordion-flush ps-20" id="firstLevelSubMenu">
<div class="accordion-item">
<div class="accordion-header">
<% if root.children.present? %>
<button class="<%= root.children.present? ? 'accordion-button' : '' %> collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#<%= ["sub2", root.id].join %>">
<h5> <%= link_to root.name, search_subject_indexes_path(subject_ids: root.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
</button>
<% else %>
<h5> <%= link_to root.name, search_documensearch_subject_indexes_pathts_path(subject_ids: root.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
<div class="accordion-item">

18
app/components/subjects_sidenav_sub_menu_component/subjects_sidenav_sub_menu_component.html.erb

@ -6,10 +6,10 @@
<div class="accordion-header">
<% if root.children.present? %>
<button class="<%= root.children.present? ? 'accordion-button' : '' %> collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#<%= [opts[:second_sub_menu], root.id].join %>">
<h5> <%= link_to root.name, search_documents_path(subject_ids: root.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to root.name, search_documents_path(subject_ids: root.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
</button>
<% else %>
<h5> <%= link_to root.name, search_documents_path(subject_ids: root.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to root.name, search_documents_path(subject_ids: root.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
<% end %>
</div>
@ -22,10 +22,10 @@
<div class="accordion-header">
<% if sub1.children.present? %>
<button class="<%= sub1.children.present? ? 'accordion-button' : '' %> collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#<%= [opts[:third_sub_menu], sub1.id].join %>">
<h5> <%= link_to sub1.name, search_documents_path(subject_ids: sub1.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to sub1.name, search_documents_path(subject_ids: sub1.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
</button>
<% else %>
<h5> <%= link_to sub1.name, search_documents_path(subject_ids: sub1.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to sub1.name, search_documents_path(subject_ids: sub1.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
<% end %>
</div>
@ -37,10 +37,10 @@
<h5 class="accordion-header">
<% if sub2.children.present? %>
<button class="<%= sub2.children.present? ? 'accordion-button' : '' %> collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#<%= [opts[:fourth_sub_menu], sub2.id].join %>">
<h5> <%= link_to sub2.name, search_documents_path(subject_ids: sub2.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to sub2.name, search_documents_path(subject_ids: sub2.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
</button>
<% else %>
<h5> <%= link_to sub2.name, search_documents_path(subject_ids: sub2.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to sub2.name, search_documents_path(subject_ids: sub2.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
<% end %>
</h5>
@ -52,10 +52,10 @@
<h5 class="accordion-header">
<% if sub3.children.present? %>
<button class="<%= sub2.children.present? ? 'accordion-button' : '' %> collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#<%= [opts[:fifth_sub_menu], sub3.id].join %>">
<h5> <%= link_to sub3.name, search_documents_path(subject_ids: sub3.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to sub3.name, search_documents_path(subject_ids: sub3.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
</button>
<% else%>
<h5> <%= link_to sub3.name, search_documents_path(subject_ids: sub3.id), class: "accordion-link text-decoration-none text-dark" %> </h5>
<h5> <%= link_to sub3.name, search_documents_path(subject_ids: sub3.id), class: "accordion-link text-decoration-none text-dark clickable-link" %> </h5>
<% end %>
</h5>
@ -64,7 +64,7 @@
<% sub3.children.each do |sub4| %>
<div class="accordion-item">
<h5 class="accordion-header">
<%= link_to sub4.name, doctrines_path(subject_ids: [sub4.id]), class: "accordion-link text-decoration-none text-dark" %>
<%= link_to sub4.name, doctrines_path(subject_ids: [sub4.id]), class: "accordion-link text-decoration-none text-dark clickable-link" %>
</h5>
</div>
<% end if sub3.children.present? %>

4
app/controllers/concerns/jurisprudence_search.rb

@ -1,7 +1,5 @@
module JurisprudenceSearch
def jurisprudence_search(search_params)
attrs = %i[id reference_number title docdate ponente edited short_title year].freeze
fulltext_fields = %i[reference_number title short_title].freeze
search = Cdao::Jurisprudence.search do
@ -11,6 +9,8 @@ module JurisprudenceSearch
fulltext search_params[field], fields: [field] if search_params[field].present?
end
with(:year, search_params[:year].to_i) if search_params[:year].present?
with(:subject_ids).any_of(search_params[:subject_ids].split(",").map(&:strip).map(&:to_i)) if search_params[:subject_ids].present?
order_by :doc_date, :desc

1
app/controllers/documents_controller.rb

@ -14,6 +14,7 @@ class DocumentsController < ApplicationController
end
def show
@subjects = Cdao::Subject.all
@doctrines = @document.doctrines
where = { enabled: true, state: "published" }

11
app/controllers/subject_indexes_controller.rb

@ -11,6 +11,15 @@ class SubjectIndexesController < ApplicationController
def show; end
def search
@search = search_subject(search_params)
@subjects = @search.results
respond_to do |format|
format.html
end
end
def create
respond_to do |format|
if @subject_index.save
@ -73,6 +82,6 @@ class SubjectIndexesController < ApplicationController
end
def search_params
params.permit(:name, :parent_id, :state)
params.permit(:name, :parent_id, :state, doctrine_ids: [])
end
end

66
app/javascript/controllers/application_controller.js

@ -0,0 +1,66 @@
import { Controller } from 'stimulus'
import StimulusReflex from 'stimulus_reflex'
import $ from 'jquery';
require("select2/dist/css/select2")
require("select2-bootstrap-theme/dist/select2-bootstrap")
import Select2 from "select2"
/* This is your ApplicationController.
* All StimulusReflex controllers should inherit from this class.
*
* Example:
*
* import ApplicationController from './application_controller'
*
* export default class extends ApplicationController { ... }
*
* Learn more at: https://docs.stimulusreflex.com
*/
export default class extends Controller {
connect () {
StimulusReflex.register(this)
}
/* Application-wide lifecycle methods
*
* Use these methods to handle lifecycle concerns for the entire application.
* Using the lifecycle is optional, so feel free to delete these stubs if you don't need them.
*
* Arguments:
*
* element - the element that triggered the reflex
* may be different than the Stimulus controller's this.element
*
* reflex - the name of the reflex e.g. "Example#demo"
*
* error/noop - the error message (for reflexError), otherwise null
*
* reflexId - a UUID4 or developer-provided unique identifier for each Reflex
*/
beforeReflex (element, reflex, noop, reflexId) {
// document.body.classList.add('wait')
}
reflexSuccess (element, reflex, noop, reflexId) {
// show success message
}
reflexError (element, reflex, error, reflexId) {
// show error message
}
reflexHalted (element, reflex, error, reflexId) {
// handle aborted Reflex action
}
afterReflex (element, reflex, noop, reflexId) {
// document.body.classList.remove('wait')
}
finalizeReflex (element, reflex, noop, reflexId) {
// all operations have completed, animation etc is now safe
}
}

17
app/javascript/controllers/document_controller.js

@ -0,0 +1,17 @@
import { end } from '@popperjs/core'
import ApplicationController from './application_controller'
export default class extends ApplicationController {
static targets = ["input"]
connect () {
super.connect()
}
search () {
const $this = this
$.get("/api/jurisprudences/", { q: this.inputTarget.value }, function (data, status) {
if (status === "success") {
$this.stimulate("DocumentReflex#render_index_table", data)
}
});
}
}

73
app/javascript/controllers/example_controller.js

@ -0,0 +1,73 @@
import ApplicationController from './application_controller'
/* This is the custom StimulusReflex controller for the Example Reflex.
* Learn more at: https://docs.stimulusreflex.com
*/
export default class extends ApplicationController {
/*
* Regular Stimulus lifecycle methods
* Learn more at: https://stimulusjs.org/reference/lifecycle-callbacks
*
* If you intend to use this controller as a regular stimulus controller as well,
* make sure any Stimulus lifecycle methods overridden in ApplicationController call super.
*
* Important:
* By default, StimulusReflex overrides the -connect- method so make sure you
* call super if you intend to do anything else when this controller connects.
*/
connect () {
super.connect()
// add your code here, if applicable
}
/* Reflex specific lifecycle methods.
*
* For every method defined in your Reflex class, a matching set of lifecycle methods become available
* in this javascript controller. These are optional, so feel free to delete these stubs if you don't
* need them.
*
* Important:
* Make sure to add data-controller="example" to your markup alongside
* data-reflex="Example#dance" for the lifecycle methods to fire properly.
*
* Example:
*
* <a href="#" data-reflex="click->Example#dance" data-controller="example">Dance!</a>
*
* Arguments:
*
* element - the element that triggered the reflex
* may be different than the Stimulus controller's this.element
*
* reflex - the name of the reflex e.g. "Example#dance"
*
* error/noop - the error message (for reflexError), otherwise null
*
* reflexId - a UUID4 or developer-provided unique identifier for each Reflex
*/
// Assuming you create a "Example#dance" action in your Reflex class
// you'll be able to use the following lifecycle methods:
// beforeDance(element, reflex, noop, reflexId) {
// element.innerText = 'Putting dance shoes on...'
// }
// danceSuccess(element, reflex, noop, reflexId) {
// element.innerText = '\nDanced like no one was watching! Was someone watching?'
// }
// danceError(element, reflex, error, reflexId) {
// console.error('danceError', error);
// element.innerText = "\nCouldn\'t dance!"
// }
// afterDance(element, reflex, noop, reflexId) {
// element.innerText = '\nWhatever that was, it\'s over now.'
// }
// finalizeDance(element, reflex, noop, reflexId) {
// element.innerText = '\nNow, the cleanup can begin!'
// }
}

18
app/javascript/controllers/hello_controller.js

@ -0,0 +1,18 @@
// Visit The Stimulus Handbook for more details
// https://stimulusjs.org/handbook/introduction
//
// This example controller works with specially annotated HTML like:
//
// <div data-controller="hello">
// <h1 data-target="hello.output"></h1>
// </div>
import { Controller } from "stimulus"
export default class extends Controller {
static targets = [ "output" ]
connect() {
this.outputTarget.textContent = 'Hello, Stimulus!'
}
}

14
app/javascript/controllers/index.js

@ -0,0 +1,14 @@
// Load all the controllers within this directory and all subdirectories.
// Controller files must be named *_controller.js.
import { Application } from "stimulus"
import { definitionsFromContext } from "stimulus/webpack-helpers"
import StimulusReflex from 'stimulus_reflex'
import consumer from '../channels/consumer'
import controller from '../controllers/application_controller'
const application = Application.start()
const context = require.context("controllers", true, /_controller\.js$/)
application.load(definitionsFromContext(context))
StimulusReflex.initialize(application, { consumer, controller })
StimulusReflex.debug = process.env.RAILS_ENV === 'development'

11
app/javascript/controllers/select2_controller.js

@ -0,0 +1,11 @@
import ApplicationController from './application_controller'
export default class extends ApplicationController {
connect() {
super.connect()
$(".subjects-select2").select2({ tags: true, width: "100%" })
$(".annomark-ids-select2").select2({ width: "100%", dropdownParent: $("#editAnnotation11") })
$(".subject-ids-modal-select2").select2({ width: "100%", dropdownParent: $("#doctrineModal") })
}
}

10
app/javascript/controllers/subjects_controller.js

@ -0,0 +1,10 @@
import ApplicationController from './application_controller'
export default class extends ApplicationController {
connect () {
super.connect()
}
load_roots() {
this.stimulate("SubjectsReflex#load_roots")
}
}

4
app/javascript/packs/application.js

@ -19,6 +19,7 @@ import "select2";
import "chosen-js";
import 'trix/dist/trix.css';
import 'trix/dist/trix.js';
import "cable_ready";
window.jQuery = $;
window.$ = $;
@ -49,3 +50,6 @@ $(document).ready(function () {
}
})
});
import "channels"
import "controllers"

1
app/models/cdao/subject.rb

@ -50,6 +50,7 @@ class Cdao::Subject < Cdao::Base
searchable do
integer :parent_id
integer :doctrine_ids, multiple: true
text :name

12
app/reflexes/application_reflex.rb

@ -0,0 +1,12 @@
# frozen_string_literal: true
class ApplicationReflex < StimulusReflex::Reflex
# Put application-wide Reflex behavior and callbacks in this file.
#
# Example:
#
# # If your ActionCable connection is: `identified_by :current_user`
# delegate :current_user, to: :connection
#
# Learn more at: https://docs.stimulusreflex.com/reflexes#reflex-classes
end

12
app/reflexes/document_reflex.rb

@ -0,0 +1,12 @@
# frozen_string_literal: true
class DocumentReflex < ApplicationReflex
include JurisprudenceSearch
def render_index_table(results)
@results = results
morph "tbody#documentIndexTable", render(DocumentIndexTableBodyComponent.with_collection(@results, current_user: User.first, opts: { is_case_lists: true }))
# render(DocumentIndexTableBodyComponent.with_collection(@results, current_user: current_user, opts: { is_case_lists: true }))
# "<tr> <td> 1 </td> <td> 2 </td> <td> 3</td> </tr>"
end
end

35
app/reflexes/example_reflex.rb

@ -0,0 +1,35 @@
# frozen_string_literal: true
class ExampleReflex < ApplicationReflex
# Add Reflex methods in this file.
#
# All Reflex instances include CableReady::Broadcaster and expose the following properties:
#
# - connection - the ActionCable connection
# - channel - the ActionCable channel
# - request - an ActionDispatch::Request proxy for the socket connection
# - session - the ActionDispatch::Session store for the current visitor
# - flash - the ActionDispatch::Flash::FlashHash for the current request
# - url - the URL of the page that triggered the reflex
# - params - parameters from the element's closest form (if any)
# - element - a Hash like object that represents the HTML element that triggered the reflex
# - signed - use a signed Global ID to map dataset attribute to a model eg. element.signed[:foo]
# - unsigned - use an unsigned Global ID to map dataset attribute to a model eg. element.unsigned[:foo]
# - cable_ready - a special cable_ready that can broadcast to the current visitor (no brackets needed)
# - reflex_id - a UUIDv4 that uniquely identies each Reflex
#
# Example:
#
# before_reflex do
# # throw :abort # this will prevent the Reflex from continuing
# # learn more about callbacks at https://docs.stimulusreflex.com/lifecycle
# end
#
# def example(argument=true)
# # Your logic here...
# # Any declared instance variables will be made available to the Rails controller and view.
# end
#
# Learn more at: https://docs.stimulusreflex.com/reflexes#reflex-classes
end

7
app/reflexes/subjects_reflex.rb

@ -0,0 +1,7 @@
# frozen_string_literal: true
class SubjectsReflex < ApplicationReflex
def load_roots
@roots = "Hello!!!"
end
end

2
app/views/document/doctrines/show.html.erb

@ -18,6 +18,6 @@
</div>
<div class="card-body">
<%= render(DocumentDoctrineShowComponent.new(current_user: current_user, doctrine: @doctrine)) %>
<%= render(DocumentDoctrineShowComponent.new(current_user: current_user, doctrine: @doctrine, subjects: @subjects)) %>
</div>
</div>

2
app/views/documents/show.html.erb

@ -44,7 +44,7 @@
<div class="container-sm row-flex col-sm-12 mt-2">
<%= render(DoctrineModalFormComponent.new(current_user: current_user, doctrine: @document.doctrines.new, opts: { form_url: jurisprudence_doctrines_path(jurisprudence_id: @document.id), form_method: :post })) %>
<%= render(DoctrineModalFormComponent.new(current_user: current_user, doctrine: @document.doctrines.new, subjects: @subjects, opts: { form_url: jurisprudence_doctrines_path(jurisprudence_id: @document.id), form_method: :post })) %>
</div>
<div class="container-sm row-flex col-sm-12 mt-2">

1
app/views/layouts/application.html.erb

@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= action_cable_meta_tag %>
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

5
config/routes.rb

@ -23,7 +23,10 @@ Rails.application.routes.draw do
end
end
resources :decisions, only: %i[index]
resources :subject_indexes
resources :subject_indexes do
get :search, on: :collection
end
namespace :api, defaults: { format: :json } do
resources :jurisprudences, only: %i[index show] do

2
package.json

@ -9,6 +9,7 @@
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "5.4.3",
"bootstrap": "^5.1.3",
"cable_ready": "^5.0.0-pre8",
"chosen-js": "^1.8.7",
"flatpickr": "^4.6.9",
"font-awesome": "^4.7.0",
@ -16,6 +17,7 @@
"moment": "^2.29.1",
"popper.js": "^1.16.1",
"select2": "^4.1.0-rc.0",
"select2-bootstrap-theme": "^0.1.0-beta.10",
"stimulus": "^3.0.1",
"stimulus_reflex": "3.4.1",
"trix": "^2.0.0-alpha.0",

12
yarn.lock generated

@ -1696,6 +1696,13 @@ [email protected]:
dependencies:
morphdom "^2.6.1"
cable_ready@^5.0.0-pre8:
version "5.0.0-pre8"
resolved "https://registry.yarnpkg.com/cable_ready/-/cable_ready-5.0.0-pre8.tgz#fa1b4d6f980f631ff3c895f3007a6789b2e47de7"
integrity sha512-5TyAp0DcYiv15YGlAI4WqEBw8Mz/lARSz/pIwEEVWWUnqWQhbsMqCIYIsQoV3IXudKOowaSbukbPRYFN0PYzKg==
dependencies:
morphdom "^2.6.1"
cacache@^12.0.2:
version "12.0.4"
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c"
@ -5952,6 +5959,11 @@ select-hose@^2.0.0:
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
select2-bootstrap-theme@^0.1.0-beta.10:
version "0.1.0-beta.10"
resolved "https://registry.yarnpkg.com/select2-bootstrap-theme/-/select2-bootstrap-theme-0.1.0-beta.10.tgz#b9426ecfc03bf4a235e76a132377574310469ac0"
integrity sha1-uUJuz8A79KI152oTI3dXQxBGmsA=
select2@^4.1.0-rc.0:
version "4.1.0-rc.0"
resolved "https://registry.yarnpkg.com/select2/-/select2-4.1.0-rc.0.tgz#ba3cd3901dda0155e1c0219ab41b74ba51ea22d8"

Loading…
Cancel
Save