1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-19 13:54:25 +01:00

frontend openlab search view, ctrl, services

This commit is contained in:
Nicolas Florentin 2016-04-22 18:17:55 +02:00
parent 5ee27da51e
commit 1a446bf646
19 changed files with 203 additions and 65 deletions

View File

@ -245,7 +245,7 @@ GEM
omniauth-oauth2 (1.3.1)
oauth2 (~> 1.0)
omniauth (~> 1.2)
openlab_ruby (0.0.2)
openlab_ruby (0.0.3)
httparty (~> 0.13)
orm_adapter (0.5.0)
pdf-core (0.5.1)

View File

@ -144,12 +144,12 @@ class ProjectsController
##
# Controller used on projects listing page
##
Application.Controllers.controller "ProjectsController", ["$scope", "$state", 'Project', 'machinesPromise', 'themesPromise', 'componentsPromise'
, ($scope, $state, Project, machinesPromise, themesPromise, componentsPromise) ->
Application.Controllers.controller "ProjectsController", ["$scope", "$state", 'Project', 'machinesPromise', 'themesPromise', 'componentsPromise', 'paginationService', 'OpenlabProject', '$window', 'growl'
, ($scope, $state, Project, machinesPromise, themesPromise, componentsPromise, paginationService, OpenlabProject, $window, growl) ->
### PRIVATE STATIC CONSTANTS ###
# Number of notifications added to the page when the user clicks on 'load next notifications'
# Number of projects added to the page when the user clicks on 'load more projects'
PROJECTS_PER_PAGE = 12
### PUBLIC SCOPE ###
@ -167,11 +167,34 @@ Application.Controllers.controller "ProjectsController", ["$scope", "$state", 'P
## list of components / used for filtering
$scope.components = componentsPromise
## By default, the pagination mode is activated to limit the page size
$scope.paginateActive = true
$scope.openlab = {}
$scope.openlab.projectsActive = Fablab.openlabProjectsActive
$scope.openlab.searchOverWholeNetwork = $scope.openlab.projectsActive || false
normalizeProjectsAttrs = (projects)->
projects.map((project)->
project.project_image = project.image_url
return project
)
$scope.searchOverWholeNetworkChanged = ->
setTimeout ->
$scope.triggerSearch()
, 150
loadMoreCallback = (projectsPromise)->
$scope.projects = $scope.projects.concat(projectsPromise.projects)
loadMoreOpenlabCallback = (projectsPromise)->
$scope.projects = $scope.projects.concat(normalizeProjectsAttrs(projectsPromise.projects))
$scope.loadMore = ->
if $scope.openlab.searchOverWholeNetwork is true
$scope.projectsPagination.loadMore(q: $scope.search.q)
else
$scope.projectsPagination.loadMore(search: $scope.search)
## The currently displayed page number
$scope.page = 1
$scope.resetFilters = ->
$scope.search.q = ""
@ -182,22 +205,22 @@ Application.Controllers.controller "ProjectsController", ["$scope", "$state", 'P
$scope.triggerSearch()
$scope.triggerSearch = ->
Project.search { search: $scope.search, page: 1 }, (projects)->
$scope.projects = projects
if projects.length < PROJECTS_PER_PAGE
$scope.paginateActive = false
else
$scope.paginateActive = true
$scope.page = 2
if $scope.openlab.searchOverWholeNetwork is true
$scope.projectsPagination = new paginationService.Instance(OpenlabProject, 1, PROJECTS_PER_PAGE, null, { }, loadMoreOpenlabCallback)
OpenlabProject.query { q: $scope.search.q, page: 1, per_page: PROJECTS_PER_PAGE }, (projectsPromise)->
if projectsPromise.errors?
# AJOUTER UN MESSAGE GROWL INTERNATIONALISER
$scope.openlab.searchOverWholeNetwork = false
$scope.triggerSearch()
else
$scope.projectsPagination.totalCount = projectsPromise.meta.total
$scope.projects = normalizeProjectsAttrs(projectsPromise.projects)
$scope.loadMoreProjects = ->
# Project.query {page: $scope.page}, (projects) ->
# $scope.projects = $scope.projects.concat projects
# $scope.paginateActive = false if projects.length < PROJECTS_PER_PAGE
Project.search { search: $scope.search, page: $scope.page }, (projects)->
$scope.projects = $scope.projects.concat projects
$scope.paginateActive = false if projects.length < PROJECTS_PER_PAGE
$scope.page += 1
else
$scope.projectsPagination = new paginationService.Instance(Project, 1, PROJECTS_PER_PAGE, null, { }, loadMoreCallback, 'search')
Project.search { search: $scope.search, page: 1, per_page: PROJECTS_PER_PAGE }, (projectsPromise)->
$scope.projectsPagination.totalCount = projectsPromise.meta.total
$scope.projects = projectsPromise.projects
##
@ -205,8 +228,11 @@ Application.Controllers.controller "ProjectsController", ["$scope", "$state", 'P
# @param project {{slug:string}} The project to display
##
$scope.showProject = (project) ->
$state.go('app.public.projects_show', {id: project.slug})
if ($scope.openlab.searchOverWholeNetwork is true) and (project.app_id isnt Fablab.openlabAppId)
$window.open(project.project_url, '_blank')
return true
else
$state.go('app.public.projects_show', {id: project.slug})
## initialization

View File

@ -0,0 +1,9 @@
'use strict'
Application.Services.factory 'OpenlabProject', ["$resource", ($resource)->
$resource "/api/openlab_projects/:id",
{id: "@id"},
query:
method: 'GET'
isArray: false
]

View File

@ -0,0 +1,50 @@
'use strict'
Application.Services.factory("paginationService", [->
helpers = {}
helpers.pageCount = (totalCount, perPage)->
Math.ceil(totalCount/perPage)
helpers.hasNextPage = (currentPage, totalCount, perPage)->
_pageCount = helpers.pageCount(totalCount, perPage)
(_pageCount != currentPage) and (_pageCount != 0)
Instance = (resourceService, currentPage, perPage, totalCount, defaultQueryParams, callback, functionName)->
@resourceService = resourceService
@currentPage = currentPage
@perPage = perPage
@totalCount = totalCount
@defaultQueryParams = defaultQueryParams
@callback = callback
@functionName = functionName || 'query'
@loading = false
@pageCount = ->
helpers.pageCount(@totalCount, @perPage)
@hasNextPage = ->
helpers.hasNextPage(@currentPage, @totalCount, @perPage)
@loadMore = (queryParams)->
@currentPage += 1
@loading = true
_queryParams = { page: @currentPage, per_page: @perPage }
if queryParams
for k,v of queryParams
_queryParams[k] = v
for k,v of @defaultQueryParams
_queryParams[k] = v
@resourceService[@functionName](_queryParams, (dataPromise)=>
@callback(dataPromise)
@loading = false
)
return
return { Instance: Instance }
])

View File

@ -10,5 +10,5 @@ Application.Services.factory 'Project', ["$resource", ($resource)->
search:
method: 'GET'
url: '/api/projects/search'
isArray: true
isArray: false
]

View File

@ -23,9 +23,22 @@
<section class="m-lg">
<div class="row m-b-md">
<div class="col-md-12"><h3 class="m-t-xs">{{ 'filter_projects' | translate }}
<a href="" class="text-sm pull-right" name="button" ng-click="resetFilters()"><i class="fa fa-refresh"></i> {{ 'reset_all_filters' | translate }}</a></h3>
<a href="javascript:void(0);" class="text-sm pull-right" name="button" ng-click="resetFilters()" ng-show="!openlab.searchOverWholeNetwork"><i class="fa fa-refresh"></i> {{ 'reset_all_filters' | translate }}</a></h3>
</div>
<div class="col-md-12 m-b">
<span ng-if="openlab.projectsActive">
<label for="searchOverWholeNetwork" class="control-label m-r" translate>{{ 'search_over_the_whole_network' }}</label>
<input bs-switch
ng-model="openlab.searchOverWholeNetwork"
type="checkbox"
class="form-control"
switch-on-text="{{ 'yes' | translate }}"
switch-off-text="{{ 'no' | translate }}"
switch-animate="true"
ng-change="searchOverWholeNetworkChanged()"
/>
{{ searchOverWholeNetwork }}
</span>
<form class="form-inline">
<div class="form-group">
<div class="input-group">
@ -35,35 +48,37 @@
<button ng-click="triggerSearch()" type="button" class="btn btn-warning" translate>{{ 'search' }}</button>
</div>
</div>
</div>
</form>
</div>
<div class="col-md-3 m-b" ng-show="isAuthenticated()">
<select ng-model="search.from" ng-change="triggerSearch()" class="form-control">
<option value="" translate>{{ 'all_projects' }}</option>
<option value="mine" translate>{{ 'my_projects' }}</option>
<option value="collaboration" translate>{{ 'projects_to_whom_i_take_part_in' }}</option>
</select>
</div>
<span ng-if="!openlab.searchOverWholeNetwork">
<div class="col-md-3 m-b" ng-show="isAuthenticated()">
<select ng-model="search.from" ng-change="triggerSearch()" class="form-control">
<option value="" translate>{{ 'all_projects' }}</option>
<option value="mine" translate>{{ 'my_projects' }}</option>
<option value="collaboration" translate>{{ 'projects_to_whom_i_take_part_in' }}</option>
</select>
</div>
<div class="col-md-3 m-b">
<select ng-model="search.machine_id" ng-change="triggerSearch()" class="form-control" ng-options="m.id as m.name for m in machines">
<option value="" translate>{{ 'all_machines' }}</option>
</select>
</div>
<div class="col-md-3 m-b">
<select ng-model="search.machine_id" ng-change="triggerSearch()" class="form-control" ng-options="m.id as m.name for m in machines">
<option value="" translate>{{ 'all_machines' }}</option>
</select>
</div>
<div class="col-md-3 m-b">
<select ng-model="search.theme_id" ng-change="triggerSearch()" class="form-control" ng-options="t.id as t.name for t in themes">
<option value="" translate>{{ 'all_themes' }}</option>
</select>
</div>
<div class="col-md-3 m-b">
<select ng-model="search.theme_id" ng-change="triggerSearch()" class="form-control" ng-options="t.id as t.name for t in themes">
<option value="" translate>{{ 'all_themes' }}</option>
</select>
</div>
<div class="col-md-3 m-b">
<select ng-model="search.component_id" ng-change="triggerSearch()" class="form-control" ng-options="t.id as t.name for t in components">
<option value="" translate>{{ 'all_materials' }}</option>
</select>
</div>
<div class="col-md-3 m-b">
<select ng-model="search.component_id" ng-change="triggerSearch()" class="form-control" ng-options="t.id as t.name for t in components">
<option value="" translate>{{ 'all_materials' }}</option>
</select>
</div>
</span>
</div>
@ -75,10 +90,11 @@
<div class="box-content project-caption">
<h1>{{project.name}}</h1>
<h3>{{ project.app_name }}</h3>
</div>
<div class="box-footer">
<div class="btn-group">
<div class="btn btn-default" ui-sref="app.logged.projects_edit({id:project.id})" ng-if="projectEditableBy(currentUser) || isAuthorized('admin')">
<div class="btn btn-default" ui-sref="app.logged.projects_edit({id:project.id})" ng-if="isAuthorized('admin') && !openlab.searchOverWholeNetwork">
<i class="fa fa-edit"></i> {{ 'edit' | translate }}
</div>
<div class="btn btn-default" ng-click="showProject(project)">
@ -92,7 +108,7 @@
<div class="row">
<div class="col-lg-12 text-center">
<a class="btn btn-warning" ng-click="loadMoreProjects()" ng-if="paginateActive" translate>{{ 'load_next_projects' }}</a>
<a class="btn btn-warning" ng-click="loadMore()" ng-if="projectsPagination.hasNextPage()" translate>{{ 'load_next_projects' }}</a>
</div>
</div>
</section>

View File

@ -0,0 +1,11 @@
class API::OpenlabProjectsController < API::ApiController
PROJECTS = Openlab::Projects.new
def index
begin
render json: PROJECTS.search(params[:q], page: params[:page], per_page: params[:per_page]).response.body
rescue Errno::ECONNREFUSED
render json: { errors: ['service unavailable'] } and return
end
end
end

View File

@ -51,7 +51,9 @@ class API::ProjectsController < API::ApiController
def search
query_params = JSON.parse(params[:search])
@projects = Project.search(query_params, current_user).page(params[:page]).records
records = Project.search(query_params, current_user).page(params[:page]).records
@total = records.total
@projects = records.includes(:users, :project_image)
render :index
end

View File

@ -108,7 +108,7 @@ class Project < ActiveRecord::Base
}
}
if params['q'].empty? # we sort by created_at if there isn't a query
if params['q'].blank? # we sort by created_at if there isn't a query
search[:sort] = { created_at: { order: :desc } }
else # otherwise we search for the word (q) in various fields
search[:query][:filtered][:query] = {

View File

@ -1,10 +1,11 @@
json.array!(@projects) do |project|
json.projects @projects do |project|
json.extract! project, :id, :name, :description, :author_id, :licence_id, :slug
json.url project_url(project, format: :json)
json.project_image project.project_image.attachment.medium.url if project.project_image
json.machine_ids project.machine_ids
json.author_id project.author_id
json.user_ids project.user_ids
json.theme_ids project.theme_ids
json.component_ids project.component_ids
end
json.meta do
json.total @total if @total
end

View File

@ -45,6 +45,12 @@
Fablab.weekStartingDay = <%= Date.parse(Rails.application.secrets.week_starting_day).strftime('%w') %>;
Fablab.d3DateFormat = "<%= Rails.application.secrets.d3_date_format %>";
Fablab.uibDateFormat = "<%= Rails.application.secrets.uib_date_format %>";
Fablab.openlabProjectsActive = <%= Rails.application.secrets.openlab_app_secret.present? %>;
<% if Rails.application.secrets.openlab_app_id.present? %>
Fablab.openlabAppId = "<%= Rails.application.secrets.openlab_app_id %>";
<% else %>
Fablab.openlabAppId = null;
<% end %>
</script>
<%= stylesheet_link_tag 'application', media: 'all' %>

View File

@ -48,4 +48,6 @@ WEEK_STARTING_DAY: 'monday'
D3_DATE_FORMAT: '%d/%m/%y'
UIB_DATE_FORMAT: 'dd/MM/yyyy'
OPENLAB_APP_SECRET: 'fSF9jZEWxjHyqjAzzg34jd92'
OPENLAB_APP_SECRET:
OPENLAB_APP_ID:
OPENLAB_BASE_URI: 'https://openlab-projects.com'

View File

@ -1,4 +1,4 @@
Openlab.configure do |config|
config.app_secret = Rails.application.secrets.openlab_app_secret
config.base_uri = Rails.env.production? ? "https://urltochange.nawak" : "localhost:3300/api/v1"
config.base_uri = Rails.application.secrets.openlab_base_uri
end

View File

@ -118,6 +118,7 @@ en:
projects_list:
# projects gallery
the_fablab_projects: "The Fab Lab projects"
search_over_the_whole_network: "Search over the whole network"
add_a_project: "Add a project"
filter_projects: "Filter projects:"
reset_all_filters: "Reset all filters"
@ -212,4 +213,4 @@ en:
you_booked_(DATE): "You booked ({{DATE}}):" # angular interpolation
book: "Book"
change_the_reservation: "Change the reservation"
you_can_shift_this_reservation_on_the_following_slots: "You can shift this reservation on the following slots:"
you_can_shift_this_reservation_on_the_following_slots: "You can shift this reservation on the following slots:"

View File

@ -118,6 +118,7 @@ fr:
projects_list:
# galerie des projets
the_fablab_projects: "Les projets du FabLab"
search_over_the_whole_network: "Chercher sur tout le réseau"
add_a_project: "Ajouter un projet"
filter_projects: "Filtrer les projets :"
reset_all_filters: "Réinitialiser tous les filtres"
@ -212,4 +213,4 @@ fr:
you_booked_(DATE): "Vous avez réservé ({{DATE}}) :" # angular interpolation
book: "Réserver"
change_the_reservation: "Modifier la réservation"
you_can_shift_this_reservation_on_the_following_slots: "Vous pouvez déplacer cette réservation sur les créneaux suivants :"
you_can_shift_this_reservation_on_the_following_slots: "Vous pouvez déplacer cette réservation sur les créneaux suivants :"

View File

@ -27,6 +27,7 @@ Rails.application.routes.draw do
get :search
end
end
resources :openlab_projects, only: :index
resources :machines
resources :components
resources :themes

View File

@ -29,6 +29,8 @@ development:
fullcalendar_locale: <%= ENV["FULLCALENDAR_LOCALE"] %>
elasticsearch_language_analyzer: <%= ENV["ELASTICSEARCH_LANGUAGE_ANALYZER"] %>
openlab_app_secret: <%= ENV["OPENLAB_APP_SECRET"] %>
openlab_app_id: <%= ENV["OPENLAB_APP_ID"] %>
openlab_base_uri: <%= ENV["OPENLAB_BASE_URI"] %>
test:
secret_key_base: 83daf5e7b80d990f037407bab78dff9904aaf3c195a50f84fa8695a22287e707dfbd9524b403b1dcf116ae1d8c06844c3d7ed942564e5b46be6ae3ead93a9d30
@ -49,6 +51,8 @@ test:
fullcalendar_locale: en
elasticsearch_language_analyzer: french
openlab_app_secret:
openlab_app_id:
openlab_base_uri:
staging:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@ -76,6 +80,8 @@ staging:
fullcalendar_locale: <%= ENV["FULLCALENDAR_LOCALE"] %>
elasticsearch_language_analyzer: <%= ENV["ELASTICSEARCH_LANGUAGE_ANALYZER"] %>
openlab_app_secret: <%= ENV["OPENLAB_APP_SECRET"] %>
openlab_app_id: <%= ENV["OPENLAB_APP_ID"] %>
openlab_base_uri: <%= ENV["OPENLAB_BASE_URI"] %>
# Do not keep production secrets in the repository,
# instead read values from the environment.
@ -105,3 +111,5 @@ production:
fullcalendar_locale: <%= ENV["FULLCALENDAR_LOCALE"] %>
elasticsearch_language_analyzer: <%= ENV["ELASTICSEARCH_LANGUAGE_ANALYZER"] %>
openlab_app_secret: <%= ENV["OPENLAB_APP_SECRET"] %>
openlab_app_id: <%= ENV["OPENLAB_APP_ID"] %>
openlab_base_uri: <%= ENV["OPENLAB_BASE_URI"] %>

View File

@ -43,4 +43,7 @@ ELASTICSEARCH_LANGUAGE_ANALYZER=french
TIME_ZONE=Paris
WEEK_STARTING_DAY=monday
D3_DATE_FORMAT=%d/%m/%y
UIB_DATE_FORMAT=dd/MM/yyyy
UIB_DATE_FORMAT=dd/MM/yyyy
OPENLAB_APP_SECRET: 'fSF9jZEWxjHyqjAzzg34jd92'
OPENLAB_APP_ID: 'xLn9CmryyURNNHZiDRYVRXbv'

View File

@ -76,9 +76,10 @@ namespace :fablab do
desc "sync all/one project in elastic search index"
task :es_build_projects_index, [:id] => :environment do |task, args|
unless Project.__elasticsearch__.client.indices.exists? index: 'fablab'
Project.__elasticsearch__.client.indices.create index: Project.index_name, body: { settings: Project.settings.to_hash, mappings: Project.mappings.to_hash }
if Project.__elasticsearch__.client.indices.exists? index: 'fablab'
Project.__elasticsearch__.client.indices.delete index: 'fablab'
end
Project.__elasticsearch__.client.indices.create index: Project.index_name, body: { settings: Project.settings.to_hash, mappings: Project.mappings.to_hash }
if args.id
IndexerWorker.perform_async(:index, id)
else