1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-17 06:52:27 +01:00

Merge branch 'dev' for release 2.4.1

This commit is contained in:
Sylvain 2016-10-11 16:12:33 +02:00
commit ddde96f5ed
31 changed files with 138 additions and 96 deletions

View File

@ -1 +1 @@
2.4.0
2.4.1

View File

@ -1,5 +1,12 @@
# Changelog Fab Manager
## v2.4.1 2016 October 11
- Fix a bug: unable to share a project/event without image on social networks
- Fix a bug: after creating an element in the admin calendar, browsing through the calendar and coming back cause the element to appear duplicated
- Fix a bug: after deleting an element in the admin calendar, the confirmation message is wrong and an error is logged in the console
- Fix a bug: erroneous syntax in docker env example file
## v2.4.0 2016 October 4
- RSS feeds to follow new projects and events published

View File

@ -39,7 +39,7 @@ Some other used libraries/components are licenced under the terms of the
Errors and omissions excepted, the other external libraries used in this
project are licenced under the terms of the [MIT Licence](https://opensource.org/licenses/MIT).
Please refer to the libraries documentation for more informations about
Please refer to the libraries documentation for more information about
their licences.
Complete lists of used libraries are available in `bower.json` for the

View File

@ -159,7 +159,7 @@ This value is only used when deploying with Docker, otherwise this is configured
POSTGRES_PASSWORD
Password for the PostgreSQL user, as specified in `database.yml`.
Please see [Setup the FabManager database in PostgreSQL](#setup-fabmanager-in-postgresql) for informations on how to create a user and set his password.
Please see [Setup the FabManager database in PostgreSQL](#setup-fabmanager-in-postgresql) for information on how to create a user and set his password.
This value is only used when deploying with Docker, otherwise this is configured in `config/database.yml`.
REDIS_HOST
@ -222,7 +222,7 @@ Identifier of your Google Analytics account.
Unique identifier of your [Disqus](http://www.disqus.com) forum.
Disqus forums are used to allow visitors to comment on projects.
See https://help.disqus.com/customer/portal/articles/466208-what-s-a-shortname- for more informations.
See https://help.disqus.com/customer/portal/articles/466208-what-s-a-shortname- for more information.
TWITTER_NAME
@ -387,7 +387,7 @@ To create it, please follow these instructions:
- `db/migrate/20160915105234_add_transformation_to_o_auth2_mapping.rb` is using [jsonb](https://www.postgresql.org/docs/9.4/static/datatype-json.html), a PostgreSQL 9.4+ datatype.
- If you intend to contribute to the project code, you will need to run the test suite with `rake test`.
This also requires your user to have the _SUPERUSER_ role.
Please see the [known issues](#known-issues) section for more informations about this.
Please see the [known issues](#known-issues) section for more information about this.
<a name="elasticsearch"></a>
## ElasticSearch
@ -518,7 +518,7 @@ Back-end translations uses the [Ruby on Rails syntax](http://guides.rubyonrails.
In each cases, some inline comments are included in the localisation files.
They can be recognized as they start with the sharp character (#).
These comments are not required to be translated, they are intended to help the translator to have some context informations about the sentence to translate.
These comments are not required to be translated, they are intended to help the translator to have some context information about the sentence to translate.
<a name="i18n-configuration"></a>
@ -652,7 +652,7 @@ Fab-manager can be connected to a [Single Sign-On](https://en.wikipedia.org/wiki
Currently OAuth 2 is the only supported protocol for SSO authentication.
For an example of how to use configure a SSO in Fab-manager, please read [sso_with_github.md](doc/sso_with_github.md).
Developers may find informations on how to implement their own authentication protocol in [sso_authentication.md](doc/sso_authentication.md).
Developers may find information on how to implement their own authentication protocol in [sso_authentication.md](doc/sso_authentication.md).
<a name="known-issues"></a>
## Known issues

View File

@ -71,7 +71,7 @@ config(['$httpProvider', 'AuthProvider', "growlProvider", "unsavedWarningsConfig
// Angular-xeditable (click-to-edit elements, used in admin backoffice)
editableOptions.theme = 'bs3';
// Alter the UI-Router's $state, registering into some informations concerning the previous $state.
// Alter the UI-Router's $state, registering into some information concerning the previous $state.
// This is used to allow the user to navigate to the previous state
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
$state.prevState = fromState;

View File

@ -50,6 +50,8 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
calendarEventClickCb(event, jsEvent, view)
eventRender: (event, element, view) ->
eventRenderCb(event, element)
loading: (isLoading, view ) ->
loadingCb(isLoading, view)
@ -181,11 +183,8 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
if ($(jsEvent.target).hasClass('remove-event'))
Availability.delete id: event.id, ->
uiCalendarConfig.calendars.calendar.fullCalendar 'removeEvents', event.id
for _event, i in $scope.eventSources[0].events
if _event.id == event.id
$scope.eventSources[0].events.splice(i,1)
growl.success(_t('the_slot_START-END_has_been_successfully_deleted', {START:+moment(event.start).format('LL LT'), END:moment(event.end).format('LT')}))
growl.success(_t('the_slot_START-END_has_been_successfully_deleted', {START:moment(event.start).format('LL LT'), END:moment(event.end).format('LT')}))
,->
growl.error(_t('unable_to_delete_the_slot_START-END_because_it_s_already_reserved_by_a_member', {START:+moment(event.start).format('LL LT'), END:moment(event.end).format('LT')}))
# if the user has only clicked on the event, display its reservations
@ -207,8 +206,20 @@ Application.Controllers.controller "AdminCalendarController", ["$scope", "$state
for tag in event.tags
html += "<span class='label label-success text-white'>#{tag.name}</span> "
element.find('.fc-title').append("<br/>"+html)
# force return to prevent coffee-script auto-return to return random value (possiblity falsy)
return
##
# Triggered when resource fetching starts/stops.
# @see https://fullcalendar.io/docs/resource_data/loading/
##
loadingCb = (isLoading, view) ->
if (isLoading)
# we remove existing events when fetching starts to prevent duplicates
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents')
]

View File

@ -217,7 +217,7 @@ Application.Controllers.controller "GraphsController", ["$scope", "$state", "$ro
for it_st in [0.. cur_type.subtypes.length-1] by 1 # when we've found it, iterate over its subtypes ...
cur_subtype = cur_type.subtypes[it_st]
if subgroup.key == cur_subtype.key # ... which match $SUBTYPE
# then we construct NVD3 dataSource according to these informations
# then we construct NVD3 dataSource according to these information
dataSource =
values: []
key: cur_subtype.label

View File

@ -125,7 +125,7 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
sample = sample.replace(/y+(?![^\[]*])/g, (match, offset, string) ->
padWithZeros(8, match.length)
)
# date informations
# date information
sample = sample.replace(/[YMD]+(?![^\[]*])/g, (match, offset, string) ->
$scope.today.format(match)
)
@ -163,7 +163,7 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
sample = sample.replace(/d+(?![^\[]*])/g, (match, offset, string) ->
padWithZeros(2, match.length)
)
# date informations
# date information
sample = sample.replace(/[YMD]+(?![^\[]*])/g, (match, offset, string) ->
$scope.today.format(match)
)
@ -334,7 +334,7 @@ Application.Controllers.controller "InvoicesController", ["$scope", "$state", 'I
##
# Callback to save the value of the legal informations zone when editing is done
# Callback to save the value of the legal information zone when editing is done
##
$scope.legalsEditEnd = (event) ->
parsed = parseHtml($scope.invoice.legals.content)

View File

@ -303,7 +303,7 @@ Application.Controllers.controller "ReserveMachineController", ["$scope", "$stat
## fullCalendar event. An already booked slot that the user want to modify
$scope.slotToModify = null
## indicates the state of the current view : calendar or plans informations
## indicates the state of the current view : calendar or plans information
$scope.plansAreShown = false
## will store the user's plan if he choosed to buy one

View File

@ -260,7 +260,7 @@ Application.Controllers.controller "EditProfileController", ["$scope", "$rootSco
##
Application.Controllers.controller "ShowProfileController", ["$scope", 'memberPromise', 'SocialNetworks', ($scope, memberPromise, SocialNetworks) ->
## Selected user's informations
## Selected user's information
$scope.user = memberPromise # DEPENDENCY WITH NAVINUM GAMIFICATION PLUGIN !!!!
## List of social networks associated with this user and toggle 'show all' state

View File

@ -20,13 +20,13 @@ Application.Controllers.controller "CompleteProfileController", ["$scope", "$roo
## name of the current fablab application (eg. "Fablab de la Casemate")
$scope.fablabName = settingsPromise.fablab_name
## informations from the current SSO provider
## information from the current SSO provider
$scope.activeProvider = activeProviderPromise
## list of user's groups (student/standard/...)
$scope.groups = groupsPromise
## current user, contains informations retrieved from the SSO
## current user, contains information retrieved from the SSO
$scope.user = memberPromise
## disallow the user to change his password as he connect from SSO

View File

@ -109,7 +109,7 @@ Application.Controllers.controller "ReserveTrainingController", ["$scope", "$sta
groupObj.plans.push(plan) if plan.group_id == group.id
$scope.plansClassifiedByGroup.push(groupObj)
## indicates the state of the current view : calendar or plans informations
## indicates the state of the current view : calendar or plans information
$scope.plansAreShown = false
## indicates if the selected training was validated (ie. added to the shopping cart)

View File

@ -1,4 +1,4 @@
<h2 translate>{{ 'general_informations' }}</h2>
<h2 translate>{{ 'general_information' }}</h2>
<input type="hidden" name="_method" value="{{method}}">
<div class="form-group" ng-class="{'has-error': planForm['plan[base_name]'].$dirty && planForm['plan[base_name]'].$invalid}">

View File

@ -68,7 +68,7 @@
<section class="widget panel b-a m m-t-lg">
<div class="panel-heading b-b small">
<h3 translate>{{ 'informations_and_booking' }}</h3>
<h3 translate>{{ 'information_and_booking' }}</h3>
</div>
<div class="panel-content wrapper">

View File

@ -61,7 +61,7 @@
</div>
<br ng-show="!plan.plan_file_url"> <!-- TODO Refacto with CSS -->
<a ng-href="{{ plan.plan_file_url }}" ng-show="plan.plan_file_url" target="_blank" translate>{{ 'more_informations' }}</a>
<a ng-href="{{ plan.plan_file_url }}" ng-show="plan.plan_file_url" target="_blank" translate>{{ 'more_information' }}</a>
</div>
</div>

View File

@ -313,7 +313,7 @@
<!-- allow receive newsletter -->
<div class="form-group">
<label for="allowNewsletter" translate>{{ 'i_accept_to_receive_informations_from_the_fablab' }}</label>
<label for="allowNewsletter" translate>{{ 'i_accept_to_receive_information_from_the_fablab' }}</label>
<input bs-switch
ng-model="user.is_allow_newsletter"
id="allowNewsletter"

View File

@ -213,7 +213,7 @@ class User < ActiveRecord::Base
where(provider: auth.provider, uid: auth.uid).first_or_create.tap do |user|
# execute this regardless of whether record exists or not (-> User#tap)
# this will init or update the user thanks to the informations retrieved from the SSO
# this will init or update the user thanks to the information retrieved from the SSO
user.profile ||= Profile.new
auth.info.mapping.each do |key, value|
user.set_data_from_sso_mapping(key, value)

View File

@ -27,7 +27,7 @@ module PDF
image StringIO.new( Base64.decode64(img_b64.value) ), :fit => [415,40]
move_down 20
font('Open-Sans', :size => 10) do
# general informations
# general information
if invoice.is_a?(Avoir)
text I18n.t('invoices.refund_invoice_reference', REF:invoice.reference), :leading => 3
else
@ -47,7 +47,7 @@ module PDF
text I18n.t('invoices.invoice_issued_on_DATE', DATE:I18n.l(invoice.created_at.to_date))
end
# user/organization's informations
# user/organization's information
if invoice&.user&.profile&.organization
name = invoice.user.profile.organization.name
else
@ -261,7 +261,7 @@ module PDF
end
text payment_verbose
# important informations
# important information
move_down 40
txt = parse_html(Setting.find_by({name: 'invoice_text'}).value)
txt.each_line do |line|
@ -269,7 +269,7 @@ module PDF
end
# address and legals informations
# address and legals information
move_down 40
txt = parse_html(Setting.find_by({name: 'invoice_legals'}).value)
txt.each_line do |line|

View File

@ -1,5 +1,5 @@
json.title notification.notification_type
json.description t('.account_imported_from_PROVIDER_(UID)_has_completed_its_informations_html',
json.description t('.account_imported_from_PROVIDER_(UID)_has_completed_its_information_html',
PROVIDER: notification.attached_object.provider,
UID: notification.attached_object.uid)
json.url notification_url(notification, format: :json)

View File

@ -4,7 +4,7 @@
<p><%= t('.body.new_account_imported', ID: @attached_object.id, PROVIDER: provider.name) %><br/>
<%= t('.body.provider_uid', UID:@attached_object.uid) %></p>
<% if provider.sso_fields.size > 1 %>
<p><%= t('.body.known_informations') %></p>
<p><%= t('.body.known_information') %></p>
<ul>
<% for field in provider.sso_fields %>
<% value = @attached_object.get_data_from_sso_mapping(field) %>

View File

@ -1,5 +1,9 @@
<% image = @event.event_image.attachment.medium %>
<% width, height = image.dimensions %>
<%
if @event.event_image
image = @event.event_image.attachment.medium
width, height = image.dimensions
end
%>
<!DOCTYPE html>
<html lang="<%= I18n.locale %>">
@ -9,9 +13,11 @@
<!-- Facebook Open Graph -->
<meta property="og:title" content="<%= @event.title %>"/>
<meta property="og:description" content="<%= @event.description %>"/>
<% if @event.event_image %>
<meta property="og:image" content="<%= root_url+image.url %>"/>
<meta property="og:image:width" content="<%= width%>" />
<meta property="og:image:height" content="<%=height%>" />
<% end %>
<meta property="fb:app_id" content="<%= Rails.application.secrets.facebook_app_id%>" />
<meta property="og:url" content="<%= root_url+'#!/events/'+@event.id.to_s %>" />
@ -20,7 +26,9 @@
<meta name="twitter:site" content="<%= ENV['TWITTER_NAME'] %>">
<meta name="twitter:title" content="<%= @event.title %>">
<meta name="twitter:description" content="<%= @event.description %>">
<% if @event.event_image %>
<meta name="twitter:image" content="<%= root_url+image.url %>">
<% end %>
</head>
</html>

View File

@ -1,5 +1,9 @@
<% image = @project.project_image.attachment.medium %>
<% width, height = image.dimensions %>
<%
if @project.project_image
image = @project.project_image.attachment.medium
width, height = image.dimensions
end
%>
<!DOCTYPE html>
<html lang="<%= I18n.locale %>">
@ -9,9 +13,11 @@
<!-- Facebook Open Graph -->
<meta property="og:title" content="<%= @project.name %>"/>
<meta property="og:description" content="<%= strip_tags(@project.description) %>"/>
<% if @project.project_image %>
<meta property="og:image" content="<%= root_url+image.url %>"/>
<meta property="og:image:width" content="<%= width%>" />
<meta property="og:image:height" content="<%=height%>" />
<% end %>
<meta property="fb:app_id" content="<%= Rails.application.secrets.facebook_app_id%>" />
<meta property="og:url" content="<%= root_url+'#!/projects/'+@project.slug %>" />
@ -20,7 +26,9 @@
<meta name="twitter:site" content="<%= ENV['TWITTER_NAME'] %>">
<meta name="twitter:title" content="<%= @project.name %>">
<meta name="twitter:description" content="<%= strip_tags(@project.description) %>">
<% if @project.project_image %>
<meta name="twitter:image" content="<%= root_url+image.url %>">
<% end %>
</head>
</html>

View File

@ -80,7 +80,7 @@ en:
phone_number: "Phone number"
phone_number_is_required: "Phone number is required."
i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "I authorize FabLab users, registered on the site, to contact me"
i_accept_to_receive_informations_from_the_fablab: "I accept to receive informations from the FabLab"
i_accept_to_receive_information_from_the_fablab: "I accept to receive information from the FabLab"
i_ve_read_and_i_accept_: "I've read and I accept"
_the_fablab_policy: "the FabLab policy"
@ -200,7 +200,7 @@ en:
i_choose_that_plan: "I choose that plan"
i_subscribe_online: "I subscribe online"
i_already_subscribed: "I already subscribed"
more_informations: "More informations"
more_information: "More information"
your_subscription_expires_on_the_DATE: "Your subscription expires on the {{DATE}}" # angular interpolation
my_group: "My group"
his_group: "{GENDER, select, male{His} female{Her} other{Its}} group" # messageFormat interpolation

View File

@ -80,7 +80,7 @@ fr:
phone_number: "Numéro de téléphone"
phone_number_is_required: "Le numéro de téléphone est requis."
i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "J'autorise les utilisateurs du Fab Lab inscrits sur le site à me contacter"
i_accept_to_receive_informations_from_the_fablab: "J'accepte de recevoir des informations du Fab Lab"
i_accept_to_receive_information_from_the_fablab: "J'accepte de recevoir des informations du Fab Lab"
i_ve_read_and_i_accept_: "J'ai lu et j'accepte"
_the_fablab_policy: "la charte d'utilisation du Fab Lab"
@ -201,7 +201,7 @@ fr:
i_choose_that_plan: "Je choisis cette formule"
i_subscribe_online: "Je m'abonne en ligne"
i_already_subscribed: "Je suis déjà abonné"
more_informations: "Plus d'infos"
more_information: "Plus d'infos"
your_subscription_expires_on_the_DATE: "Votre abonnement expire au {{DATE}}" # angular interpolation
my_group: "Mon groupe"
his_group: "Son groupe" # messageFormat interpolation
@ -228,7 +228,7 @@ fr:
# détails d'un événement et réservation
event_description: "Description de l'évènement"
downloadable_documents: "Documents à télécharger"
informations_and_booking: "Informations et réservation"
information_and_booking: "Informations et réservation"
beginning: "Début :"
ending: "Fin :"
opening_hours: "Horaires :"

View File

@ -199,7 +199,7 @@ en:
plan:
# subscription plan edition form
general_informations: "General informations"
general_information: "General information"
name_length_must_be_less_than_24_characters: "Name length must be less than 24 characters."
type_is_required: "Type is required."
group: "Group"

View File

@ -186,7 +186,7 @@ en:
notify_admin_member_create_reservation:
a_RESERVABLE_reservation_was_made_by_USER_html: "A <strong><em>%{RESERVABLE}</em></strong> reservation was made by <strong><em>%{USER}</em></strong>."
notify_admin_profile_complete:
account_imported_from_PROVIDER_(UID)_has_completed_its_informations_html: "Account imported from <strong><em>%{PROVIDER} </strong> (%{UID})</em> has completed its informations."
account_imported_from_PROVIDER_(UID)_has_completed_its_information_html: "Account imported from <strong><em>%{PROVIDER} </strong> (%{UID})</em> has completed its information."
notify_admin_slot_is_canceled:
USER_s_reservation_on_the_DATE_was_cancelled_remember_to_generate_a_refund_invoice_if_applicable_html: "<strong><em>%{USER}</em></strong>'s reservation, on the %{DATE}, was cancelled. Remember to generate a refund invoice if applicable."
notify_admin_slot_is_modified:

View File

@ -198,7 +198,7 @@ en:
body:
new_account_imported: "A new user account (ID: %{ID}) has been imported to the website via %{PROVIDER}."
provider_uid: "its provider ID is: "
known_informations: "Here is what we know about this provider:"
known_information: "Here is what we know about this provider:"
address_already_used: "This address is already associated with another user"
no_more_info_available: "No other info about this user can be provided before he completes his profile."

View File

@ -198,7 +198,7 @@ fr:
body:
new_account_imported: "Un nouveau compte utilisateur (ID: %{ID}) vient d'être importé sur la plate-forme via %{PROVIDER}."
provider_uid: "Son identifiant fournisseur est %{UID}."
known_informations: "Voici les informations connues à son propos :"
known_information: "Voici les informations connues à son propos :"
address_already_used: "Cette adresse est déjà associée à un autre utilisateur"
no_more_info_available: "Aucune autre information sur cet utilisateur n'est disponible tant que celui-ci n'aura pas complété son profil."

View File

@ -15,7 +15,7 @@ For this guide, we will use [GitHub](https://developer.github.com/v3/oauth/) as
It is composed of: **SSO's protocol**, _dash_, **slug of the provider's name**.
If you have a doubt about what it will be, start by creating the authentication provider in your fab-manager (see below), then the strategy's name will be shown in the providers list.
- You'll be redirected to a page displaying two important informations: your **Client ID** and your **Client Secret**.
- You'll be redirected to a page displaying two important information: your **Client ID** and your **Client Secret**.
- Now go to your fab-manager's instance, login as an administrator, go to `Users management` and `Authentication`.
Click `Add a new authentication provider`, and select _OAuth 2.0_ in the `Authentication type` drop-down list.

View File

@ -52,8 +52,8 @@ OPENLAB_APP_SECRET=
OPENLAB_APP_ID=
OPENLAB_BASE_URI=https://openprojects.fab-manager.com
NAVINUM_API_LOGIN:
NAVINUM_API_PASSWORD:
NAVINUM_API_LOGIN=
NAVINUM_API_PASSWORD=
LOG_LEVEL=debug

View File

@ -134,6 +134,10 @@ namespace :fablab do
# create doctype
client.indices.put_mapping index: Availability.index_name, type: Availability.document_type, body: Availability.mappings.to_hash
# verify doctype creation was successful
if client.indices.exists_type? index: Availability.index_name, type: Availability.document_type
puts "[ElasticSearch] #{Availability.index_name}/#{Availability.document_type} successfully created with its mapping."
# index requested documents
if args.id
AvailabilityIndexerWorker.perform_async(:index, id)
@ -142,6 +146,10 @@ namespace :fablab do
AvailabilityIndexerWorker.perform_async(:index, availability_id)
end
end
else
puts "[ElasticSearch] An error occurred while creating #{Availability.index_name}/#{Availability.document_type}. Please check your ElasticSearch configuration."
puts "\nCancelling..."
end
end
desc 'recreate every versions of images'