Commit 2cbe945bf61499a8ad7f38934122046bfa44108a

Authored by Victor Costa
2 parents d333a169 b1d29dcd

Merge branch 'virtuoso_integration' into stable

Showing 25 changed files with 485 additions and 6 deletions   Show diff stats
plugins/virtuoso/Gemfile
... ... @@ -2,3 +2,5 @@ gem 'rdf'
2 2 gem 'rdf-virtuoso'
3 3 gem 'oai'
4 4 gem 'liquid'
  5 +gem 'roadie'
  6 +gem 'roadie-rails'
... ...
plugins/virtuoso/controllers/admin/virtuoso_plugin_custom_queries_controller.rb 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +class VirtuosoPluginCustomQueriesController < AdminController
  2 +
  3 + def index
  4 + @custom_queries = environment.virtuoso_plugin_custom_queries.all
  5 + end
  6 +
  7 + def new
  8 + @custom_query = VirtuosoPlugin::CustomQuery.new
  9 + end
  10 +
  11 + def edit
  12 + @custom_query = VirtuosoPlugin::CustomQuery.find(params[:id])
  13 + end
  14 +
  15 + def create
  16 + @custom_query = VirtuosoPlugin::CustomQuery.new(params[:custom_query])
  17 + @custom_query.environment = environment
  18 +
  19 + if @custom_query.save
  20 + session[:notice] = _('Custom query was successfully created.')
  21 + redirect_to :action => :index
  22 + else
  23 + render action: "new"
  24 + end
  25 + end
  26 +
  27 + def update
  28 + @custom_query = VirtuosoPlugin::CustomQuery.find(params[:id])
  29 +
  30 + if @custom_query.update_attributes(params[:custom_query])
  31 + session[:notice] = 'Custom query was successfully updated.'
  32 + redirect_to :action => :index
  33 + else
  34 + render action: "edit"
  35 + end
  36 + end
  37 +
  38 + def destroy
  39 + @custom_query = VirtuosoPlugin::CustomQuery.find(params[:id])
  40 + @custom_query.destroy
  41 +
  42 + redirect_to :action => :index
  43 + end
  44 +
  45 +end
... ...
plugins/virtuoso/controllers/public/virtuoso_plugin_public_controller.rb 0 → 100644
... ... @@ -0,0 +1,7 @@
  1 +class VirtuosoPluginPublicController < PublicController
  2 +
  3 + def custom_query
  4 + render :json => environment.virtuoso_plugin_custom_queries.find(params[:id])
  5 + end
  6 +
  7 +end
... ...
plugins/virtuoso/controllers/virtuoso_plugin_admin_controller.rb
... ... @@ -20,4 +20,29 @@ class VirtuosoPluginAdminController &lt; AdminController
20 20 redirect_to :action => :index
21 21 end
22 22  
  23 + def triple_management
  24 + triples_management = VirtuosoPlugin::TriplesManagement.new(environment)
  25 + @triples = []
  26 + if request.post?
  27 + @query = params[:query]
  28 + @graph_uri = params[:graph_uri]
  29 + @triples = triples_management.search_triples(@graph_uri, @query)
  30 + end
  31 + render :action => 'triple_management'
  32 + end
  33 +
  34 + def triple_update
  35 + graph_uri = params[:graph_uri]
  36 + triples = params[:triples]
  37 +
  38 + triples_management = VirtuosoPlugin::TriplesManagement.new(environment)
  39 +
  40 + triples.each { |triple_key, triple_content|
  41 + triples_management.update_triple(graph_uri, triple_content[:from], triple_content[:to])
  42 + }
  43 +
  44 + session[:notice] = _('Triple(s) succesfully updated.')
  45 + redirect_to :action => :triple_management
  46 + end
  47 +
23 48 end
... ...
plugins/virtuoso/db/migrate/20141113131439_create_custom_queries.rb 0 → 100644
... ... @@ -0,0 +1,15 @@
  1 +class CreateCustomQueries < ActiveRecord::Migration
  2 +
  3 + def change
  4 + create_table :virtuoso_plugin_custom_queries do |t|
  5 + t.integer "environment_id", :null => false
  6 + t.string :name
  7 + t.text :query
  8 + t.text :template
  9 + t.text :stylesheet
  10 + t.boolean :enabled, :default => true
  11 + t.timestamps
  12 + end
  13 + end
  14 +
  15 +end
... ...
plugins/virtuoso/features/edit_template.feature 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +Feature: edit template
  2 + As a noosfero user
  3 + I want to create and edit templates
  4 +
  5 + Background:
  6 + Given I am on the homepage
  7 + And plugin Virtuoso is enabled on environment
  8 + And the following users
  9 + | login | name |
  10 + | joaosilva | Joao Silva |
  11 + And I am logged in as "joaosilva"
  12 + And the following custom queries
  13 + | name | query | template |
  14 + | Default | query-1 | template-1 |
  15 +
  16 + @selenium
  17 + Scenario:
  18 + Given I am on joaosilva's control panel
  19 + And I follow "Manage Content"
  20 + And I should see "New content"
  21 + And I follow "New content"
  22 + And I should see "Triples template" within ".article-types"
  23 + When I follow "Triples template" within ".article-types"
  24 + And I follow "Copy" within ".custom-query"
  25 + Then the "SPARQL Query" field should contain "query-1"
... ...
plugins/virtuoso/features/step_definitions/virtuoso_plugin_steps.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +Given /^the following custom queries$/ do |table|
  2 + table.hashes.map{|item| item.dup}.each do |item|
  3 + VirtuosoPlugin::CustomQuery.create!(item.merge(:environment => Environment.default))
  4 + end
  5 +end
... ...
plugins/virtuoso/lib/ext/environment.rb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +class Environment
  2 +
  3 + has_many :virtuoso_plugin_custom_queries, :class_name => "VirtuosoPlugin::CustomQuery"
  4 +
  5 +end
... ...
plugins/virtuoso/lib/virtuoso_plugin.rb
... ... @@ -19,6 +19,10 @@ class VirtuosoPlugin &lt; Noosfero::Plugin
19 19 def virtuoso_client
20 20 @virtuoso_client ||= RDF::Virtuoso::Repository.new("#{settings.virtuoso_uri}/sparql", :update_uri => "#{settings.virtuoso_uri}/sparql-auth", :username => settings.virtuoso_username, :password => settings.virtuoso_password, :auth_method => 'digest', :timeout => 30)
21 21 end
  22 +
  23 + def js_files
  24 + ['edit-server-list']
  25 + end
22 26  
23 27 def stylesheet?
24 28 true
... ...
plugins/virtuoso/lib/virtuoso_plugin/custom_query.rb 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +class VirtuosoPlugin::CustomQuery < Noosfero::Plugin::ActiveRecord
  2 +
  3 + belongs_to :environment
  4 +
  5 + attr_accessible :enabled, :environment, :query, :template, :name, :stylesheet
  6 +
  7 + validates_presence_of :name
  8 +
  9 +end
... ...
plugins/virtuoso/lib/virtuoso_plugin/triples_management.rb 0 → 100644
... ... @@ -0,0 +1,32 @@
  1 +class VirtuosoPlugin::TriplesManagement
  2 +
  3 + def initialize(environment)
  4 + @environment = environment
  5 + end
  6 +
  7 + attr_reader :environment
  8 +
  9 + def plugin
  10 + @plugin ||= VirtuosoPlugin.new(self)
  11 + end
  12 +
  13 + def search_triples(graph_uri, query_sparql)
  14 + query = "WITH <#{graph_uri}> #{query_sparql}"
  15 + plugin.virtuoso_client.query(query)
  16 + end
  17 +
  18 + def update_triple(graph_uri, from_triple, to_triple)
  19 + from_subject = from_triple[:subject]
  20 + from_predicate = from_triple[:predicate]
  21 + from_object = from_triple[:object]
  22 +
  23 + to_subject = to_triple[:subject]
  24 + to_predicate = to_triple[:predicate]
  25 + to_object = to_triple[:object]
  26 +
  27 + query = "WITH <#{graph_uri}> DELETE { <#{from_subject}> <#{from_predicate}> '#{from_object}' } INSERT { <#{to_subject}> <#{to_predicate}> '#{to_object}' }"
  28 +
  29 + plugin.virtuoso_client.query(query)
  30 + end
  31 +
  32 +end
... ...
plugins/virtuoso/lib/virtuoso_plugin/triples_template.rb
... ... @@ -10,8 +10,9 @@ class VirtuosoPlugin::TriplesTemplate &lt; Article
10 10  
11 11 settings_items :query, :type => :string
12 12 settings_items :template, :type => :string
  13 + settings_items :stylesheet, :type => :string
13 14  
14   - attr_accessible :query, :template
  15 + attr_accessible :query, :template, :stylesheet
15 16  
16 17 def to_html(options = {})
17 18 article = self
... ... @@ -28,11 +29,20 @@ class VirtuosoPlugin::TriplesTemplate &lt; Article
28 29 begin
29 30 results = plugin.virtuoso_client.query(query)
30 31 liquid_template = Liquid::Template.parse("{% for row in results %}#{template}{% endfor %}")
31   - liquid_template.render('results' => results)
  32 + page = liquid_template.render('results' => results)
  33 + transform_html(page)
32 34 rescue => ex
33 35 logger.info ex.to_s
34 36 "Failed to process the template"
35 37 end
36 38 end
37 39  
  40 + protected
  41 +
  42 + def transform_html(html)
  43 + document = Roadie::Document.new(html)
  44 + document.add_css(stylesheet) if stylesheet.present?
  45 + document.transform
  46 + end
  47 +
38 48 end
... ...
plugins/virtuoso/public/custom_query.js 0 → 100644
... ... @@ -0,0 +1,9 @@
  1 +jQuery(document).ready(function($) {
  2 + $('#copy_custom_query').on('click', function() {
  3 + $.getJSON("/plugin/virtuoso/public/custom_query", {id: $('#select_custom_query').val()}, function(data) {
  4 + $('#article_query').val(data.custom_query.query);
  5 + $('#article_stylesheet').val(data.custom_query.stylesheet);
  6 + tinymce.get('article_template').setContent(data.custom_query.template);
  7 + });
  8 + });
  9 +});
... ...
plugins/virtuoso/public/edit-server-list.js 0 → 100644
... ... @@ -0,0 +1,46 @@
  1 +function send_ajax(source_url) {
  2 + jQuery(".server-address").autocomplete({
  3 + source : function(request, response){
  4 + jQuery.ajax({
  5 + type: "GET",
  6 + url: source_url,
  7 + data: {query: request.term},
  8 + success: function(result){
  9 + response(result);
  10 + },
  11 + error: function(ajax, stat, errorThrown) {
  12 + console.log('Server not found : ' + errorThrown);
  13 + }
  14 + });
  15 + },
  16 +
  17 + minLength: 3
  18 + });
  19 +}
  20 +
  21 +function new_server_action(){
  22 + send_ajax(jQuery("#page_url").val());
  23 +
  24 + jQuery(".delete-server-list-row").click(function(){
  25 + jQuery(this).parent().parent().remove();
  26 + return false;
  27 + });
  28 +
  29 + jQuery(document).scrollTop(jQuery('#dropable-server-list').scrollTop());
  30 +}
  31 +
  32 +function add_new_server() {
  33 + var new_server = jQuery('#edit-server-list-block #new-template>li').clone();
  34 + new_server.show();
  35 + jQuery('#dropable-server-list').append(new_server);
  36 + new_server_action();
  37 +}
  38 +
  39 +jQuery(document).ready(function(){
  40 + new_server_action();
  41 +
  42 + jQuery("#dropable-server-list").sortable({
  43 + revert: true,
  44 + axis: "y"
  45 + });
  46 +});
... ...
plugins/virtuoso/public/style.css
1 1 .virtuoso-triples-template .template {
2 2 margin: 10px 0;
3 3 }
  4 +
  5 +#virtuoso-triples-management input[type="text"] {
  6 + width: 100%
  7 +}
  8 +
  9 +#virtuoso-triples-management textarea {
  10 + width: 99%;
  11 +}
  12 +
  13 +#virtuoso-triples-management ul {
  14 + list-style-type: none;
  15 + padding: 0;
  16 +}
  17 +
  18 +#virtuoso-triples-management #triples-list {
  19 + border-top: 1px solid #CCC;
  20 + padding-top: 15px;
  21 +}
  22 +
  23 +#triples-list > li + li {
  24 + border-top: 1px solid #CCC;
  25 + margin-top: 20px;
  26 + padding-top: 15px;
  27 +}
... ...
plugins/virtuoso/test/functional/virtuoso_plugin_custom_queries_controller_test.rb 0 → 100644
... ... @@ -0,0 +1,45 @@
  1 +require 'test_helper'
  2 +
  3 +class VirtuosoPluginCustomQueriesControllerTest < ActionController::TestCase
  4 + setup do
  5 + @custom_query = VirtuosoPlugin::CustomQuery.create!(:name => 'name', :query => 'query', :template => 'template', :stylesheet => 'stylesheet', :environment => Environment.default)
  6 + login_as(create_admin_user(Environment.default))
  7 + end
  8 +
  9 + should "get index" do
  10 + get :index
  11 + assert_response :success
  12 + assert_not_nil assigns(:custom_queries)
  13 + end
  14 +
  15 + should "get new" do
  16 + get :new
  17 + assert_response :success
  18 + end
  19 +
  20 + should "create custom_query" do
  21 + assert_difference('VirtuosoPlugin::CustomQuery.count') do
  22 + post :create, custom_query: { name: @custom_query.name, enabled: @custom_query.enabled, query: @custom_query.query, template: @custom_query.template, stylesheet: @custom_query.stylesheet }
  23 + end
  24 +
  25 + assert_redirected_to :action => :index
  26 + end
  27 +
  28 + should "get edit" do
  29 + get :edit, id: @custom_query
  30 + assert_response :success
  31 + end
  32 +
  33 + should "update custom_query" do
  34 + put :update, id: @custom_query, custom_query: { name: @custom_query.name, enabled: @custom_query.enabled, query: @custom_query.query, template: @custom_query.template, stylesheet: @custom_query.stylesheet }
  35 + assert_redirected_to :action => :index
  36 + end
  37 +
  38 + should "destroy custom_query" do
  39 + assert_difference('VirtuosoPlugin::CustomQuery.count', -1) do
  40 + delete :destroy, id: @custom_query
  41 + end
  42 +
  43 + assert_redirected_to :action => :index
  44 + end
  45 +end
... ...
plugins/virtuoso/test/unit/triples_template_test.rb
... ... @@ -14,7 +14,7 @@ class TriplesTemplateTest &lt; ActiveSupport::TestCase
14 14 article.plugin.virtuoso_client.expects(:query).returns([{'var' => 'Hello '}, {'var' => 'World'}])
15 15 article.template = "{{row.var}}"
16 16  
17   - assert_equal 'Hello World', article.template_content
  17 + assert_match /Hello World/, article.template_content
18 18 end
19 19  
20 20 should 'display error message when failed to execute the query' do
... ... @@ -26,4 +26,16 @@ class TriplesTemplateTest &lt; ActiveSupport::TestCase
26 26 assert_equal "Failed to process the template", article.template_content
27 27 end
28 28  
  29 + should 'transform css into inline stylesheet' do
  30 + article.stubs(:plugin).returns(mock)
  31 + article.plugin.expects(:virtuoso_client).at_least_once.returns(mock)
  32 + article.plugin.virtuoso_client.expects(:query).returns([{'var' => 'Hello '}, {'var' => 'World'}])
  33 + article.template = "<p>{{row.var}}</p>"
  34 + article.stylesheet = "p {color: red}"
  35 +
  36 + content = article.template_content
  37 + assert_match /<p style="color:red">Hello <\/p>/, content
  38 + assert_match /<p style="color:red">World<\/p>/, content
  39 + end
  40 +
29 41 end
... ...
plugins/virtuoso/views/cms/virtuoso_plugin/_tinymce_template_editor.html.erb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +<% extend TinymceHelper %>
  2 +
  3 +<%= tinymce_js %>
  4 +
  5 +<script>
  6 + function tinymce_macros_setup(editor) {}
  7 +
  8 + jQuery(document).ready(function($) {
  9 + <%= tinymce_init_js(:valid_children => "+body[style]") %>
  10 + });
  11 +</script>
... ...
plugins/virtuoso/views/cms/virtuoso_plugin/_triples_template.html.erb
1 1 <div class="virtuoso-triples-template">
2 2 <%= required_fields_message %>
3 3  
4   - <%= render :file => 'shared/tiny_mce' %>
  4 + <%= render :partial => 'cms/virtuoso_plugin/tinymce_template_editor' %>
5 5  
6 6 <%= required labelled_form_field(_('Title'), text_field(:article, 'name', :size => '64', :maxlength => 150)) %>
7   - <%= labelled_form_field(_('SPARQL Query'), text_area(:article, :query, :style => 'width: 98%; height: 120px;')) %>
8 7  
  8 + <div class="custom-query">
  9 + <span class="label"><%= _('Custom Query/Template selection: ') %></span>
  10 + <%= select_tag :select_custom_query, options_from_collection_for_select(environment.virtuoso_plugin_custom_queries, :id, :name) %>
  11 + <%= button :clone, _('Copy'), '#', :id => 'copy_custom_query' %>
  12 + </div>
  13 +
  14 + <%= labelled_form_field(_('SPARQL Query'), text_area(:article, :query, :style => 'width: 98%; height: 120px;')) %>
9 15 <div class="template">
10 16 <span class="label"><%= _('Template') %></span>
11 17 <span class="reference" style="float: right;"><a href="https://github.com/Shopify/liquid/wiki/Liquid-for-Designers"><%= _('Template reference') %></a></span>
... ... @@ -14,6 +20,14 @@
14 20 </span>
15 21 </div>
16 22  
  23 + <div class="stylesheet">
  24 + <span class="label"><%= _('Stylesheet') %></span>
  25 + <span>
  26 + <%= text_area(:article, :stylesheet, :style => 'width: 98%; height: 100px;') %>
  27 + </span>
  28 + </div>
  29 +
17 30 <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true} %>
18 31 <%= render :partial => 'general_fields' %>
19 32 </div>
  33 +<%= javascript_include_tag '/plugins/virtuoso/custom_query.js' %>
... ...
plugins/virtuoso/views/virtuoso_plugin_admin/index.html.erb
  1 +<%= javascript_include_tag '/plugins/virtuoso/edit-server-list' %>
  2 +
1 3 <h1><%= _('Virtuoso settings')%></h1>
2 4  
3 5 <%= form_for(:settings) do |f| %>
... ... @@ -23,7 +25,6 @@
23 25 <span class="value"><%= time_ago_as_sentence @settings.last_harvest %></span>
24 26 </div>
25 27 <% end %>
26   - <br/>
27 28 <div class="actions">
28 29 <% if @harvest_running %>
29 30 <%= _('Running...') %>
... ... @@ -33,3 +34,12 @@
33 34 <% end %>
34 35 </div>
35 36 </div>
  37 +
  38 +<hr />
  39 +
  40 +<div class="triple-management">
  41 + <div class="actions">
  42 + <%= button :edit, _('Triple management'), :action => :triple_management %>
  43 + <%= button :edit, _('Custom Queries'), :action => :index, :controller => 'virtuoso_plugin_custom_queries' %>
  44 + </div>
  45 +</div>
... ...
plugins/virtuoso/views/virtuoso_plugin_admin/triple_management.html.erb 0 → 100644
... ... @@ -0,0 +1,54 @@
  1 +<div id="virtuoso-triples-management">
  2 + <h1><%= _('Virtuoso settings &raquo; Triples Management')%></h1>
  3 +
  4 + <%= form_tag('/admin/plugin/virtuoso/triple_management', :method => 'post') do %>
  5 + <%= labelled_form_field(_('Default Graph IRI:'), text_field_tag(:graph_uri, @graph_uri) ) %>
  6 + <%= labelled_form_field(_('Query SPARQL:'), text_area_tag(:query, @query, :rows => 7)) %>
  7 + <% button_bar do %>
  8 + <%= submit_button(:search, _('Search')) %>
  9 + <% end %>
  10 + <% end %>
  11 +
  12 + <% unless @triples.empty? %>
  13 +
  14 + <%= form_tag('/admin/plugin/virtuoso/triple_update', :method => 'post') do %>
  15 + <%= hidden_field_tag(:graph_uri, @graph_uri) %>
  16 +
  17 + <ul id="triples-list">
  18 +
  19 + <% triple_counter = 1 %>
  20 +
  21 + <% @triples.each { |triple| %>
  22 +
  23 + <li>
  24 + <ul class="triple">
  25 + <li>
  26 + <%= hidden_field_tag("triples[triple#{triple_counter}[from][subject]]", triple[:s].to_s) %>
  27 + <%= labelled_form_field(_('Subject:'), text_field_tag("triples[triple#{triple_counter}[to][subject]]", triple[:s].to_s) ) %>
  28 + </li>
  29 + <li>
  30 + <%= hidden_field_tag("triples[triple#{triple_counter}[from][predicate]]", triple[:p].to_s) %>
  31 + <%= labelled_form_field(_('Predicate:'), text_field_tag("triples[triple#{triple_counter}[to][predicate]]", triple[:p].to_s) ) %>
  32 + </li>
  33 + <li>
  34 + <%= hidden_field_tag("triples[triple#{triple_counter}[from][object]]", triple[:o].to_s) %>
  35 + <%= labelled_form_field(_('Object:'), text_field_tag("triples[triple#{triple_counter}[to][object]]", triple[:o].to_s) ) %>
  36 + </li>
  37 + </ul>
  38 + </li>
  39 +
  40 + <% triple_counter += 1 %>
  41 +
  42 + <% } %>
  43 +
  44 + </ul>
  45 +
  46 + <% button_bar do %>
  47 + <%= submit_button(:save, _('Save')) %>
  48 + <% end %>
  49 +
  50 + <% end %>
  51 +
  52 + <% end %>
  53 +
  54 +</div>
... ...
plugins/virtuoso/views/virtuoso_plugin_custom_queries/_form.html.erb 0 → 100644
... ... @@ -0,0 +1,37 @@
  1 +<%= form_for(:custom_query, :url => {:action => @custom_query.persisted? ? :update : :create, :id => @custom_query.id}) do |f| %>
  2 + <% if @custom_query.errors.any? %>
  3 + <div id="error_explanation">
  4 + <h2><%= pluralize(@custom_query.errors.count, "error") %>:</h2>
  5 +
  6 + <ul>
  7 + <% @custom_query.errors.full_messages.each do |msg| %>
  8 + <li><%= msg %></li>
  9 + <% end %>
  10 + </ul>
  11 + </div>
  12 + <% end %>
  13 +
  14 + <div class="field">
  15 + <%= f.label :name %><br />
  16 + <%= f.text_field :name %>
  17 + </div>
  18 + <div class="field">
  19 + <%= f.label :query %><br />
  20 + <%= f.text_area :query %>
  21 + </div>
  22 + <div class="field">
  23 + <%= f.label :template %><br />
  24 + <%= f.text_area :template %>
  25 + </div>
  26 + <div class="field">
  27 + <%= f.label :stylesheet %><br />
  28 + <%= f.text_area :stylesheet %>
  29 + </div>
  30 + <div class="field">
  31 + <%= f.label :enabled %><br />
  32 + <%= f.check_box :enabled %>
  33 + </div>
  34 + <div class="actions">
  35 + <%= f.submit %>
  36 + </div>
  37 +<% end %>
... ...
plugins/virtuoso/views/virtuoso_plugin_custom_queries/edit.html.erb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<h1><%= _('Manage Custom Queries - Edit') %></h1>
  2 +
  3 +<%= render 'form' %>
  4 +
  5 +<%= link_to 'Back', :action => :index %>
... ...
plugins/virtuoso/views/virtuoso_plugin_custom_queries/index.html.erb 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<h1><%= _('Manage Custom Queries') %></h1>
  2 +
  3 +<table>
  4 + <tr>
  5 + <th>Name</th>
  6 + <th>Enabled</th>
  7 + <th></th>
  8 + <th></th>
  9 + </tr>
  10 +
  11 +<% @custom_queries.each do |custom_query| %>
  12 + <tr>
  13 + <td><%= custom_query.name %></td>
  14 + <td><%= custom_query.enabled %></td>
  15 + <td><%= link_to 'Edit', :action => :edit, :id => custom_query.id %></td>
  16 + <td><%= link_to 'Destroy', :action => :destroy, :id => custom_query.id, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  17 + </tr>
  18 +<% end %>
  19 +</table>
  20 +
  21 +<br />
  22 +
  23 +<%= button :new, _('New'), :action => :new %>
... ...
plugins/virtuoso/views/virtuoso_plugin_custom_queries/new.html.erb 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +<h1><%= _('Manage Custom Queries - New') %></h1>
  2 +
  3 +<%= render 'form' %>
  4 +
  5 +<%= link_to 'Back', :action => :index %>
... ...