Project

General

Profile

Revision fe8bb25c

Added by Dmitri Dolguikh over 8 years ago

Fixes #7870: support for auto-complete in image search

View differences:

app/assets/javascripts/foreman_docker/image_step.js
1
$(document).ready(function() {
2
    var tag = $('#local_tag');
3
    tag.autocomplete({
4
        source: [],
5
        minLength: 0
6
    }).focus( function() {
7
        $(this).data("uiAutocomplete").search($(this).val());
8
    });
9

  
10
    var target = $('#search');
11
    target.autocomplete({
12
        source: function( request, response ) {
13
            $.getJSON( target.data("url"), { search: request.term }, response );
14
        },
15
        select: function( event, ui ) {
16
            tag.val('');
17
            var source = [];
18
            $.getJSON( tag.data("url"), { search: ui.item.value }, function(data) {
19
                $.each( data, function(index, value) {
20
                    source.push({label: value.label, value: value.value});
21
                });
22
            });
23
            tag.autocomplete('option', 'source', source);
24
        },
25
        minLength: 1
26
    });
27
});
app/controllers/containers_controller.rb
1 1
class ContainersController < ::ApplicationController
2
  before_filter :find_resource, :only => [:show]
2
  before_filter :find_resource, :only => [:show, :auto_complete_image, :auto_complete_image_tags]
3 3

  
4 4
  def index
5 5
    @container_resources = allowed_resources.select { |cr| cr.provider == 'Docker' }
......
32 32
  def show
33 33
  end
34 34

  
35
  def auto_complete_image
36
    images = @container.compute_resource.all_images(params[:search]).map do |image|
37
      image.info['RepoTags'].map do |image_tag|
38
        name, _ = image_tag.split(':')
39
        name
40
      end
41
    end
42
    render :json => images.flatten.uniq.map do |n|
43
      { :label => CGI.escapeHTML(n), :value => CGI.escapeHTML(n) }
44
    end
45
  end
46

  
47
  def auto_complete_image_tags
48
    images = @container.compute_resource.all_images(params[:search]).map do |image|
49
      image.info['RepoTags'].map do |image_tag|
50
        _, tag = image_tag.split(':')
51
        { :label => CGI.escapeHTML(tag), :value => CGI.escapeHTML(tag) }
52
      end
53
    end
54
    render :json => images.flatten
55
  end
56

  
35 57
  private
36 58

  
59
  def action_permission
60
    case params[:action]
61
    when 'auto_complete_image', 'auto_complete_image_tags'
62
      'view'
63
    else
64
      super
65
    end
66
  end
67

  
37 68
  def resource_deletion
38 69
    # Unmanaged container - only present in Compute Resource
39 70
    if params[:compute_resource_id].present?
app/helpers/containers_helper.rb
51 51
        )
52 52
    )
53 53
  end
54

  
55
  def auto_complete_search(name, val, options = {})
56
    options.merge!(:class => "form-control", :'data-url' => options.delete(:path))
57
    text_field_tag(name, val, options)
58
  end
54 59
end
app/models/foreman_docker/docker.rb
30 30
    end
31 31

  
32 32
    def available_images
33
      client.images
33
      client.images.all
34
    end
35

  
36
    def all_images(filter = '')
37
      client # initialize Docker-Api
38
      # we are using an older version of docker-api, which differs from the current
39
      ::Docker::Image.all('filter' => filter)
34 40
    end
35 41

  
36 42
    def image(id)
37 43
      client.image.get(id) || fail(ActiveRecord::RecordNotFound)
38 44
    end
39 45

  
46
    def search(term = '')
47
      client.images.image_search(:term => term)
48
    end
49

  
40 50
    def provider_friendly_name
41 51
      'Docker'
42 52
    end
app/views/containers/steps/image.html.erb
1
<%= javascript 'foreman_docker/image_step' %>
2

  
1 3
<%= render :layout => 'title', :locals => { :step => 2 } do %>
4
  <%= form_for @container, :url => wizard_path, :method => :put do |f| %>
5

  
2 6
  <ul class="nav nav-tabs" data-tabs="tabs">
3 7
    <li class="active"><a href="#primary" data-toggle="tab">
4 8
      <span class="glyphicon glyphicon-cloud-download"></span>
5 9
      <%= _("Docker hub") %>
6 10
    </a></li>
7
    <li><a href="#others" data-toggle="tab">
11
    <li><a href="#local" data-toggle="tab">
8 12
      <span class="glyphicon glyphicon-globe"></span>
9
      <%= _("Others") %>
13
      <%= _("Local") %>
10 14
    </a></li>
11 15
  </ul>
16

  
12 17
  <div class="tab-content">
13
    <%= form_for @container, :url => wizard_path, :method => :put do |f| %>
14
      <div class="tab-pane active" id="primary">
15
        <div class="input-group col-md-6">
16
          <%= auto_complete_search(:image, '',
17
                                   :path  => 'containers_path',
18
                                   :value =>  f.object.image.present? ? f.object.image.image_id : '',
19
                                   :placeholder => ('Find your favorite container, e.g: centos:latest')) %>
20
          <span class="input-group-btn">
21
          <%= button_tag(:class => 'btn btn-default') do %>
18
    <div class="tab-pane active" id="primary">
19
      <div class="input-group col-md-6">
20
        <%= auto_complete_search(:image, '',
21
                                 :path  => 'containers_path',
22
                                 :value =>  f.object.image.present? ? f.object.image.image_id : '',
23
                                 :placeholder => _('Find your favorite container, e.g: centos:latest')) %>
24
        <span class="input-group-btn">
25
            <%= button_tag(:class => 'btn btn-default') do %>
26
              <span class="glyphicon glyphicon-search"></span>
27
              <%= _("Search") %>
28
            <% end %>
29
          </span>
30
      </div>
31
      <hr>
32
      <%= text_f f, :tag, :size => 'col-md-4' %>
33
    </div>
34
    <div class="tab-pane" id="local">
35
      <div class="input-group col-md-6">
36
        <%= auto_complete_search(:image, '',
37
                                 :path => auto_complete_image_container_path(@container),
38
                                 :id => :search,
39
                                 :placeholder => _('Find your favorite container, e.g: centos:latest')) %>
40
        <span class="input-group-btn">
41
          <%= button_tag(:class => 'btn btn-default',
42
                         :type => 'button',
43
                         :onclick => "$('#search').trigger('focus')") do %>
22 44
            <span class="glyphicon glyphicon-search"></span>
23 45
            <%= _("Search") %>
24 46
          <% end %>
25
          </span>
26
        </div>
27
        <hr>
28
        <%= text_f f, :tag, :value => f.object.tag.present? ? f.object.tag.tag : '', :size => 'col-md-4' %>
47
        </span>
29 48
      </div>
30
      <%= render :partial => 'form_buttons' %>
31
    <% end %>
49
      <hr/>
50
      <%= text_f f, :tag, :size => 'col-md-4',
51
                 :id => 'local_tag', 'data-url' => auto_complete_image_tags_container_path(@container) %>
52
    </div>
53
    <%= render :partial => 'form_buttons' %>
32 54
  </div>
55

  
56
  <% end %>
33 57
<% end %>
config/routes.rb
1 1
Rails.application.routes.draw do
2 2
  resources :containers, :only => [:index, :new, :show, :destroy] do
3 3
    resources :steps, :controller => 'containers/steps', :only => [:show, :update]
4
    get :auto_complete_image, :on => :member
5
    get :auto_complete_image_tags, :on => :member
4 6
  end
5 7
end
lib/foreman_docker/engine.rb
13 13
    end
14 14

  
15 15
    initializer "foreman_docker.assets.precompile" do |app|
16
      app.config.assets.precompile += ['foreman_docker/terminal.css']
16
      app.config.assets.precompile += %w(foreman_docker/terminal.css foreman_docker/image_step.js)
17 17
    end
18 18

  
19 19
    initializer 'foreman_docker.configure_assets', :group => :assets do
20 20
      SETTINGS[:foreman_docker_engine] =
21
        { :assets => { :precompile => ['foreman_docker/terminal.css'] } }
21
        { :assets => { :precompile => ['foreman_docker/terminal.css',
22
                                       'foreman_docker/image_step.js'] } }
22 23
    end
23 24

  
24 25
    initializer 'foreman_docker.register_gettext', :after => :load_config_initializers do
......
44 45
        end
45 46

  
46 47
        security_block :containers do
47
          permission :view_containers,    :containers         => [:index, :show]
48
          permission :view_containers,    :containers         => [:index, :show,
49
                                                                  :auto_complete_image,
50
                                                                  :auto_complete_image_tags]
48 51
          permission :create_containers,  :'containers/steps' => [:show, :update],
49 52
                                          :containers         => [:new]
50 53
          permission :destroy_containers, :containers         => [:destroy]

Also available in: Unified diff