mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-12-01 12:24:28 +01:00
merge
This commit is contained in:
parent
c16150d7cc
commit
f25fdd4091
@ -1 +0,0 @@
|
||||
defaults
|
@ -13,9 +13,11 @@
|
||||
"angular": true,
|
||||
"Fablab": true,
|
||||
"moment": true,
|
||||
"_": true
|
||||
"_": true,
|
||||
"Humanize": true,
|
||||
"GTM": true
|
||||
},
|
||||
"plugins": ["lint-erb"],
|
||||
"plugins": ["html-erb"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/*.ts", "**/*.tsx"],
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -65,3 +65,10 @@ yarn-error.log
|
||||
/yarn-error.log
|
||||
yarn-debug.log*
|
||||
.yarn-integrity
|
||||
|
||||
/public/packs
|
||||
/public/packs-test
|
||||
/node_modules
|
||||
/yarn-error.log
|
||||
yarn-debug.log*
|
||||
.yarn-integrity
|
||||
|
77
CHANGELOG.md
77
CHANGELOG.md
@ -1,8 +1,77 @@
|
||||
# Changelog Fab-manager
|
||||
|
||||
- Updated Node to 16.13.2
|
||||
- Updated eslint to v8 and eslint related packages to their latest versions
|
||||
- Updated typescript to v4.6.3
|
||||
- Webpack overlay will now report eslint issues
|
||||
- Linted all code according to eslint rules
|
||||
|
||||
# v5.3.2 2022 January 19
|
||||
## v5.3.7 2022 March 28
|
||||
|
||||
- Updated Spanish translations (thanks to [@altieriranedo](https://crowdin.com/profile/altieriranedo))
|
||||
- Fix a security issue: updated minimist to 1.2.6 to fix [CVE-2021-44906](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44906)
|
||||
- Fix a security issue: updated node-forge to 1.3.0 to fix [CVE-2022-24771](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24771), [CVE-2022-24772](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24772) and [CVE-2022-24773](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24773)
|
||||
|
||||
## v5.3.6 2022 March 24
|
||||
|
||||
- Support for Google Analytics V4
|
||||
- OAuth2 scopes are now configurable from the interface
|
||||
- Prepaid-packs purchases are exported to the accounting CSV file
|
||||
- Updated environment documentation
|
||||
- Updated react-i18next to 11.15.6
|
||||
- Updated i18next to 21.6.13
|
||||
- Updated i18next-icu to 2.0.3
|
||||
- Updated sidekiq-unique-jobs to 7.1.15
|
||||
- Updated @uirouter/angularjs to 1.0.30
|
||||
- Updated bootstrap-sass to 3.4.3
|
||||
- Removed unmaintained gem sidekiq-cron and replaced it with sidekiq-scheduler
|
||||
- Removed unmaintained @rails/webpacker v5 and replaced it with shakapacker v6.2.0
|
||||
- Removed dependency to auto-ngtemplate-loader
|
||||
- Removed support for Universal Analytics
|
||||
- Updated deprecated division operators in sass
|
||||
- Fix a bug: prepaid-packs purchases are reported as subscriptions in the statistics
|
||||
- Fix a bug: error Couldn't find the binary git during assets compilation
|
||||
- Fix a bug: a sentence was not linked to a translation key
|
||||
- Fix a bug: the version check may be scheduled at an invalid time
|
||||
- Fix a bug: the moment-timezone relied on an outdated version of moment with a case-sensitive locale file
|
||||
- Fix a bug: unable to delete an administrator who had closed an accounting period
|
||||
- Fix a bug: captcha keys are not shown in the admin panel, once configured
|
||||
- Fix a bug: help message in upgrade script has a bogus format
|
||||
- Fix a security issue: removed message format in elasticsearch's log4j to fix [CVE-2021-44228](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228)
|
||||
- Fix a security issue: updated image_processing to 1.12.2 to fix [CVE-2022-24720](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-24720)
|
||||
- Fix a security issue: updated url-parse to 1.5.10 to fix [CVE-2022-0686](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0686), [CVE-2022-0691](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0691), [CVE-2022-0639](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0639) and [CVE-2022-0512](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0512)
|
||||
- Fix a security issue: updated rails to 5.2.6.3 to fix [CVE-2022-21831](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-21831), [CVE-2022-23633](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23633)
|
||||
- Fix a security issue: updated sidekiq to 6.4.1 to fix [CVE-2022-23837](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23837)
|
||||
- Fix a security issue: updated nokogiri to 1.13.3 to fix [CVE-2021-30560](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-30560) and [CVE-2022-23308](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23308)
|
||||
- Fix a security issue: updated puma to 4.3.11 to fix [CVE-2022-23634](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23634)
|
||||
- Fix a security issue: updated i18next-http-backend to 1.3.2 to fix [CVE-2022-0235](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0235)
|
||||
- Fix a security issue: updated follow-redirects to 1.18.8 to fix [CVE-2022-0536](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0536)
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_statistics[2021,07]`
|
||||
- [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/cve-2021-44228.sh | bash`
|
||||
- [TODO DEPLOY] update your oAuth2 provider configuration with the scopes previously defined in the OAUTH2_SCOPE environment variable
|
||||
|
||||
## v5.3.5 2022 March 02
|
||||
|
||||
- Added [an option](doc/environment.md#OPENLAB_SSL_VERIFY) to allow set verify ssl option for OpenLab
|
||||
|
||||
## v5.3.4 2022 March 01
|
||||
|
||||
- Fix line break on home events' cards
|
||||
- Fix typo "projets" => "projects"
|
||||
- Removes dead code about OpenAPI (open_api_calls_count_tracings)
|
||||
- Fix a bug: unable to modify OpenLab url for production
|
||||
|
||||
## v5.3.3 2022 February 08
|
||||
|
||||
- Updated german translations
|
||||
- Fix a bug: unable to rebuild the statistics
|
||||
- Fix a bug/regresion: $sce.getTrustedHtml removes all dangerous html like iframe (youtube players, ect), replaced by $sce.trustAsHtml which trusts the content, it creates a security breach but all contents are created by users to we trust them
|
||||
- Fix a bug: in SubscriptionPolicy#show?, was causing an error notice, making user think that the payment was not done, but it was
|
||||
- Fix a bug: destroying a project was impossible
|
||||
- Fix a bug: fix non-blocking js error when there was not payment gateway set
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_statistics[2020,04]`
|
||||
|
||||
## v5.3.2 2022 January 19
|
||||
|
||||
- Add a test for statistics generation
|
||||
- Fix a bug: missing the Other payment method
|
||||
@ -14,7 +83,7 @@
|
||||
- Fix a bug: prepaid-packs without expiration date do not work
|
||||
- [TODO DEPLOY] `rails fablab:maintenance:regenerate_statistics[2020,04]`
|
||||
|
||||
# v5.3.1 2022 January 17
|
||||
## v5.3.1 2022 January 17
|
||||
|
||||
- Definition of extended prices for spaces is now made in hours (previously in minutes)
|
||||
- Support for JSONPath syntax in OAuth2 SSO fields mapping
|
||||
@ -45,12 +114,12 @@
|
||||
- Fix a security issue: updated follow-redirects to 1.14.7 to fix [CVE-2022-0155](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-0155)
|
||||
- [TODO DEPLOY] `rails db:seed`
|
||||
|
||||
# v5.3.0 2021 December 29
|
||||
## v5.3.0 2021 December 29
|
||||
|
||||
- Ability to configure multiple VAT rates, per kind of invoiced item
|
||||
- Ability to export the collected VAT, by rates, to a CSV file
|
||||
- Refactored the extended prices' frontend code to allow future customization
|
||||
- Fix a bug: the amount label in not correctly shown in the extended prices modal
|
||||
- Fix a bug: the amount label in not correctly shown in the extended prices modal
|
||||
- Fix a bug: `extended_prices_in_same_day` apply the extended prices to each day
|
||||
|
||||
## v5.2.0 2021 December 23
|
||||
|
@ -9,6 +9,8 @@ RUN apk update && apk upgrade && \
|
||||
curl \
|
||||
nodejs \
|
||||
yarn \
|
||||
git \
|
||||
openssh \
|
||||
imagemagick \
|
||||
supervisor \
|
||||
tzdata \
|
||||
@ -26,7 +28,6 @@ RUN apk update && apk upgrade && \
|
||||
alpine-sdk \
|
||||
build-base \
|
||||
linux-headers \
|
||||
git \
|
||||
patch
|
||||
|
||||
RUN gem install bundler
|
||||
|
8
Gemfile
8
Gemfile
@ -7,8 +7,8 @@ gem 'rails', '~> 5.2.4'
|
||||
# Used by rails 5.2 to reduce the app boot time by over 50%
|
||||
gem 'bootsnap'
|
||||
# Use Puma as web server
|
||||
gem 'puma', '4.3.9'
|
||||
gem 'webpacker', '~> 5.x'
|
||||
gem 'puma', '4.3.11'
|
||||
gem 'shakapacker', '6.2.0'
|
||||
|
||||
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
||||
gem 'jbuilder', '~> 2.5'
|
||||
@ -90,8 +90,8 @@ gem 'aasm'
|
||||
# Background job processing
|
||||
gem 'sidekiq', '>= 6.0.7'
|
||||
# Recurring jobs for Sidekiq
|
||||
gem 'sidekiq-cron'
|
||||
gem 'sidekiq-unique-jobs', '~> 6.0.22'
|
||||
gem 'sidekiq-scheduler'
|
||||
gem 'sidekiq-unique-jobs', '~> 7.1.15'
|
||||
|
||||
gem 'stripe', '5.29.0'
|
||||
|
||||
|
192
Gemfile.lock
192
Gemfile.lock
@ -4,46 +4,46 @@ GEM
|
||||
Ascii85 (1.0.3)
|
||||
aasm (5.0.8)
|
||||
concurrent-ruby (~> 1.0)
|
||||
actioncable (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
actioncable (5.2.6.3)
|
||||
actionpack (= 5.2.6.3)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailer (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
actionview (= 5.2.6)
|
||||
activejob (= 5.2.6)
|
||||
actionmailer (5.2.6.3)
|
||||
actionpack (= 5.2.6.3)
|
||||
actionview (= 5.2.6.3)
|
||||
activejob (= 5.2.6.3)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.2.6)
|
||||
actionview (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
actionpack (5.2.6.3)
|
||||
actionview (= 5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
rack (~> 2.0, >= 2.0.8)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionpack-page_caching (1.2.2)
|
||||
actionpack (>= 5.0.0)
|
||||
actionview (5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
actionview (5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_record_query_trace (1.7)
|
||||
activejob (5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
activejob (5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
activerecord (5.2.6)
|
||||
activemodel (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
activemodel (5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
activerecord (5.2.6.3)
|
||||
activemodel (= 5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
arel (>= 9.0)
|
||||
activestorage (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
activerecord (= 5.2.6)
|
||||
activestorage (5.2.6.3)
|
||||
actionpack (= 5.2.6.3)
|
||||
activerecord (= 5.2.6.3)
|
||||
marcel (~> 1.0.0)
|
||||
activesupport (5.2.6)
|
||||
activesupport (5.2.6.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
@ -66,6 +66,9 @@ GEM
|
||||
bindex (0.8.1)
|
||||
bootsnap (1.4.6)
|
||||
msgpack (~> 1.0)
|
||||
brpoplpush-redis_script (0.1.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||
redis (>= 1.0, <= 5.0)
|
||||
builder (3.2.4)
|
||||
bullet (7.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@ -91,7 +94,7 @@ GEM
|
||||
cldr-plurals-runtime-rb (1.0.1)
|
||||
coercible (1.0.0)
|
||||
descendants_tracker (~> 0.0.1)
|
||||
concurrent-ruby (1.1.8)
|
||||
concurrent-ruby (1.1.9)
|
||||
connection_pool (2.2.5)
|
||||
coveralls_reborn (0.18.0)
|
||||
simplecov (>= 0.18.1, < 0.20.0)
|
||||
@ -115,6 +118,7 @@ GEM
|
||||
dotenv-rails (2.7.5)
|
||||
dotenv (= 2.7.5)
|
||||
railties (>= 3.2, < 6.1)
|
||||
e2mmap (0.1.0)
|
||||
elasticsearch (5.0.5)
|
||||
elasticsearch-api (= 5.0.5)
|
||||
elasticsearch-transport (= 5.0.5)
|
||||
@ -137,36 +141,36 @@ GEM
|
||||
multi_json
|
||||
equalizer (0.0.11)
|
||||
erubi (1.10.0)
|
||||
et-orbi (1.2.1)
|
||||
et-orbi (1.2.7)
|
||||
tzinfo
|
||||
faker (2.10.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
faraday (0.17.3)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.15.4)
|
||||
ffi (1.15.5)
|
||||
foreman (0.87.0)
|
||||
forgery (0.7.0)
|
||||
friendly_id (5.1.0)
|
||||
activerecord (>= 4.0.0)
|
||||
fugit (1.3.1)
|
||||
fugit (1.5.2)
|
||||
et-orbi (~> 1.1, >= 1.1.8)
|
||||
raabro (~> 1.1)
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
raabro (~> 1.4)
|
||||
globalid (1.0.0)
|
||||
activesupport (>= 5.0)
|
||||
hashdiff (1.0.1)
|
||||
hashery (2.1.2)
|
||||
hashie (4.1.0)
|
||||
htmlentities (4.3.4)
|
||||
httparty (0.18.1)
|
||||
httparty (0.20.0)
|
||||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (1.8.10)
|
||||
i18n (1.10.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
icalendar (2.5.3)
|
||||
ice_cube (~> 0.16)
|
||||
ice_cube (0.16.3)
|
||||
ice_nine (0.11.2)
|
||||
image_processing (1.12.1)
|
||||
image_processing (1.12.2)
|
||||
mini_magick (>= 4.9.5, < 5)
|
||||
ruby-vips (>= 2.0.17, < 3)
|
||||
jaro_winkler (1.5.4)
|
||||
@ -193,25 +197,25 @@ GEM
|
||||
listen (3.0.8)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
loofah (2.9.1)
|
||||
loofah (2.14.0)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (1.0.1)
|
||||
marcel (1.0.2)
|
||||
message_format (0.0.6)
|
||||
twitter_cldr (~> 5.0)
|
||||
method_source (1.0.0)
|
||||
mime-types (3.3.1)
|
||||
mime-types (3.4.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2021.0225)
|
||||
mime-types-data (3.2022.0105)
|
||||
mimemagic (0.4.3)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
mini_magick (4.10.1)
|
||||
mini_mime (1.1.0)
|
||||
mini_portile2 (2.6.1)
|
||||
minitest (5.14.4)
|
||||
mini_mime (1.1.2)
|
||||
mini_portile2 (2.8.0)
|
||||
minitest (5.15.0)
|
||||
minitest-reporters (1.4.2)
|
||||
ansi
|
||||
builder
|
||||
@ -222,8 +226,8 @@ GEM
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.12.5)
|
||||
mini_portile2 (~> 2.6.1)
|
||||
nokogiri (1.13.3)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
notify_with (0.0.2)
|
||||
jbuilder (~> 2.0)
|
||||
@ -245,8 +249,8 @@ GEM
|
||||
omniauth-rails_csrf_protection (0.1.2)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (>= 1.3.1)
|
||||
openlab_ruby (0.0.5)
|
||||
httparty (~> 0.13)
|
||||
openlab_ruby (0.0.7)
|
||||
httparty (~> 0.20)
|
||||
orm_adapter (0.5.0)
|
||||
parallel (1.19.1)
|
||||
parser (2.7.0.4)
|
||||
@ -269,35 +273,35 @@ GEM
|
||||
prawn-table (0.2.2)
|
||||
prawn (>= 1.3.0, < 3.0.0)
|
||||
public_suffix (4.0.6)
|
||||
puma (4.3.9)
|
||||
puma (4.3.11)
|
||||
nio4r (~> 2.0)
|
||||
pundit (2.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
raabro (1.1.6)
|
||||
racc (1.5.2)
|
||||
raabro (1.4.0)
|
||||
racc (1.6.0)
|
||||
rack (2.2.3)
|
||||
rack-proxy (0.6.5)
|
||||
rack-proxy (0.7.2)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
railroady (1.5.3)
|
||||
rails (5.2.6)
|
||||
actioncable (= 5.2.6)
|
||||
actionmailer (= 5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
actionview (= 5.2.6)
|
||||
activejob (= 5.2.6)
|
||||
activemodel (= 5.2.6)
|
||||
activerecord (= 5.2.6)
|
||||
activestorage (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
rails (5.2.6.3)
|
||||
actioncable (= 5.2.6.3)
|
||||
actionmailer (= 5.2.6.3)
|
||||
actionpack (= 5.2.6.3)
|
||||
actionview (= 5.2.6.3)
|
||||
activejob (= 5.2.6.3)
|
||||
activemodel (= 5.2.6.3)
|
||||
activerecord (= 5.2.6.3)
|
||||
activestorage (= 5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.2.6)
|
||||
railties (= 5.2.6.3)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.3.0)
|
||||
rails-html-sanitizer (1.4.2)
|
||||
loofah (~> 2.3)
|
||||
rails-observers (0.1.5)
|
||||
activemodel (>= 4.0)
|
||||
@ -306,14 +310,14 @@ GEM
|
||||
rails_stdout_logging
|
||||
rails_serve_static_assets (0.0.5)
|
||||
rails_stdout_logging (0.0.5)
|
||||
railties (5.2.6)
|
||||
actionpack (= 5.2.6)
|
||||
activesupport (= 5.2.6)
|
||||
railties (5.2.6.3)
|
||||
actionpack (= 5.2.6.3)
|
||||
activesupport (= 5.2.6.3)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.19.0, < 2.0)
|
||||
rainbow (3.0.0)
|
||||
rake (13.0.3)
|
||||
rake (13.0.6)
|
||||
rb-fsevent (0.10.3)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
@ -321,7 +325,7 @@ GEM
|
||||
recurrence (1.3.0)
|
||||
activesupport
|
||||
i18n
|
||||
redis (4.4.0)
|
||||
redis (4.6.0)
|
||||
repost (0.3.2)
|
||||
responders (2.4.1)
|
||||
actionpack (>= 4.2.0, < 6.0)
|
||||
@ -337,31 +341,43 @@ GEM
|
||||
unicode-display_width (~> 1.4.0)
|
||||
ruby-progressbar (1.10.1)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby-vips (2.0.17)
|
||||
ffi (~> 1.9)
|
||||
ruby-vips (2.1.4)
|
||||
ffi (~> 1.12)
|
||||
rubyXL (3.4.14)
|
||||
nokogiri (>= 1.10.8)
|
||||
rubyzip (>= 1.3.0)
|
||||
rubyzip (2.3.0)
|
||||
rufus-scheduler (3.8.1)
|
||||
fugit (~> 1.1, >= 1.1.6)
|
||||
safe_yaml (1.0.5)
|
||||
sassc (2.4.0)
|
||||
ffi (~> 1.9)
|
||||
seed_dump (3.3.1)
|
||||
activerecord (>= 4)
|
||||
activesupport (>= 4)
|
||||
semantic_range (2.3.0)
|
||||
semantic_range (3.0.0)
|
||||
sha3 (1.0.1)
|
||||
sidekiq (6.2.1)
|
||||
shakapacker (6.2.0)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
sidekiq (6.4.1)
|
||||
connection_pool (>= 2.2.2)
|
||||
rack (~> 2.0)
|
||||
redis (>= 4.2.0)
|
||||
sidekiq-cron (1.1.0)
|
||||
fugit (~> 1.1)
|
||||
sidekiq (>= 4.2.1)
|
||||
sidekiq-unique-jobs (6.0.22)
|
||||
sidekiq-scheduler (3.1.1)
|
||||
e2mmap
|
||||
redis (>= 3, < 5)
|
||||
rufus-scheduler (~> 3.2)
|
||||
sidekiq (>= 3)
|
||||
thwait
|
||||
tilt (>= 1.4.0)
|
||||
sidekiq-unique-jobs (7.1.15)
|
||||
brpoplpush-redis_script (> 0.1.1, <= 2.0.0)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||
sidekiq (>= 4.0, < 7.0)
|
||||
thor (~> 0)
|
||||
sidekiq (>= 5.0, < 8.0)
|
||||
thor (>= 0.20, < 3.0)
|
||||
simplecov (0.19.0)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
@ -371,12 +387,12 @@ GEM
|
||||
spring-watcher-listen (2.0.1)
|
||||
listen (>= 2.7, < 4.0)
|
||||
spring (>= 1.2, < 3.0)
|
||||
sprockets (4.0.2)
|
||||
sprockets (4.0.3)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.2)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets-rails (3.4.2)
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
sprockets (>= 3.0.0)
|
||||
ssrf_filter (1.0.7)
|
||||
stripe (5.29.0)
|
||||
@ -387,6 +403,9 @@ GEM
|
||||
tins (~> 1.0)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
thwait (0.2.0)
|
||||
e2mmap
|
||||
tilt (2.0.10)
|
||||
tins (1.25.0)
|
||||
sync
|
||||
ttfunk (1.5.1)
|
||||
@ -417,12 +436,7 @@ GEM
|
||||
addressable (>= 2.3.6)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
webpacker (5.2.1)
|
||||
activesupport (>= 5.2)
|
||||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
websocket-driver (0.7.3)
|
||||
websocket-driver (0.7.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
|
||||
@ -475,7 +489,7 @@ DEPENDENCIES
|
||||
pg_search
|
||||
prawn
|
||||
prawn-table
|
||||
puma (= 4.3.9)
|
||||
puma (= 4.3.11)
|
||||
pundit
|
||||
railroady
|
||||
rails (~> 5.2.4)
|
||||
@ -492,9 +506,10 @@ DEPENDENCIES
|
||||
sassc
|
||||
seed_dump
|
||||
sha3
|
||||
shakapacker (= 6.2.0)
|
||||
sidekiq (>= 6.0.7)
|
||||
sidekiq-cron
|
||||
sidekiq-unique-jobs (~> 6.0.22)
|
||||
sidekiq-scheduler
|
||||
sidekiq-unique-jobs (~> 7.1.15)
|
||||
spring
|
||||
spring-watcher-listen (~> 2.0.0)
|
||||
stripe (= 5.29.0)
|
||||
@ -503,7 +518,6 @@ DEPENDENCIES
|
||||
vcr (= 6.0.0)
|
||||
web-console (>= 3.3.0)
|
||||
webmock
|
||||
webpacker (~> 5.x)
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.19
|
||||
2.2.21
|
||||
|
3
Procfile
3
Procfile
@ -1,4 +1,3 @@
|
||||
web: bundle exec rails server puma -p $PORT
|
||||
worker: bundle exec sidekiq -C ./config/sidekiq.yml
|
||||
wp-client: bin/webpack-dev-server
|
||||
wp-server: SERVER_BUNDLE_ONLY=yes bin/webpack --watch
|
||||
webpack: bin/webpacker-dev-server
|
||||
|
@ -83,7 +83,7 @@ class API::AuthProvidersController < API::ApiController
|
||||
params.require(:auth_provider)
|
||||
.permit(:name, :providable_type,
|
||||
providable_attributes: [:id, :base_url, :token_endpoint, :authorization_endpoint, :logout_endpoint,
|
||||
:profile_url, :client_id, :client_secret,
|
||||
:profile_url, :client_id, :client_secret, :scopes,
|
||||
o_auth2_mappings_attributes: [:id, :local_model, :local_field, :api_field,
|
||||
:api_endpoint, :api_data_type, :_destroy,
|
||||
transformation: [:type, :format, :true_value,
|
||||
|
@ -6,7 +6,7 @@ class API::OpenlabProjectsController < API::ApiController
|
||||
before_action :init_openlab
|
||||
|
||||
def index
|
||||
render json: @projets.search(params[:q], page: params[:page], per_page: params[:per_page]).response.body
|
||||
render json: @projects.search(params[:q], page: params[:page], per_page: params[:per_page]).response.body
|
||||
rescue StandardError
|
||||
render json: { errors: ['service unavailable'] }
|
||||
end
|
||||
@ -15,6 +15,6 @@ class API::OpenlabProjectsController < API::ApiController
|
||||
|
||||
def init_openlab
|
||||
client = Openlab::Client.new(app_secret: Setting.get('openlab_app_secret'))
|
||||
@projets = Openlab::Projects.new(client)
|
||||
@projects = Openlab::Projects.new(client)
|
||||
end
|
||||
end
|
||||
|
@ -4,7 +4,7 @@ import 'regenerator-runtime/runtime';
|
||||
import 'jquery';
|
||||
import {} from 'jquery-ujs';
|
||||
import 'bootstrap-sass';
|
||||
import '../src/javascript/lib/polyfill';
|
||||
import 'src/javascript/lib/polyfill';
|
||||
import 'angular';
|
||||
<% unless Rails.application.secrets.angular_locale == 'en-us' %>
|
||||
import 'angular-i18n/angular-locale_<%= Rails.application.secrets.angular_locale %>.js';
|
||||
@ -31,16 +31,15 @@ import 'ngUpload';
|
||||
import 'jasny-bootstrap/js/fileinput';
|
||||
import 'holderjs';
|
||||
import 'AngularDevise';
|
||||
import '../src/javascript/lib/devise-modal';
|
||||
import 'src/javascript/lib/devise-modal';
|
||||
import 'angular-growl-v2';
|
||||
import 'angular-xeditable';
|
||||
import 'checklist-model/checklist-model';
|
||||
import 'angular-unsavedchanges/lib/unsavedChanges';
|
||||
import 'angular-loading-bar/src/loading-bar';
|
||||
import 'angular-scroll/angular-scroll';
|
||||
import 'angular-google-analytics/dist/angular-google-analytics';
|
||||
import '../src/javascript/lib/dirDisqus';
|
||||
import '../src/javascript/lib/humanize';
|
||||
import 'src/javascript/lib/dirDisqus';
|
||||
import 'src/javascript/lib/humanize';
|
||||
import 'underscore/underscore';
|
||||
import 'elasticsearch-browser/elasticsearch.angular';
|
||||
import 'd3/d3';
|
||||
@ -56,7 +55,7 @@ import 'summernote';
|
||||
import 'summernote/lang/summernote-<%= Rails.application.secrets.summernote_locale %>.js';
|
||||
<% end %>
|
||||
import 'angular-summernote/dist/angular-summernote';
|
||||
import '../src/javascript/lib/summernote-ext-nugget';
|
||||
import 'src/javascript/lib/summernote-ext-nugget';
|
||||
import '@claviska/jquery-minicolors/jquery.minicolors.js';
|
||||
import 'angular-minicolors/angular-minicolors.js';
|
||||
import 'angular-translate/dist/angular-translate';
|
||||
@ -80,18 +79,18 @@ import 'angular-ui-tour/app/angular-ui-tour';
|
||||
import '@fortawesome/fontawesome-free';
|
||||
import '@fortawesome/fontawesome-free/js/v4-shims';
|
||||
|
||||
require('../src/javascript/app.js');
|
||||
require('../src/javascript/router.js');
|
||||
require('../src/javascript/plugins.js.erb');
|
||||
require('src/javascript/app.js');
|
||||
require('src/javascript/router.js');
|
||||
require('src/javascript/plugins.js.erb');
|
||||
|
||||
function importAll (r) { r.keys().forEach(r); }
|
||||
|
||||
importAll(require.context('../src/javascript/components/', true, /.*/));
|
||||
importAll(require.context('../src/javascript/controllers/', true, /.*/));
|
||||
importAll(require.context('../src/javascript/services/', true, /.*/));
|
||||
importAll(require.context('../src/javascript/directives/', true, /.*/));
|
||||
importAll(require.context('../src/javascript/filters/', true, /.*/));
|
||||
importAll(require.context('../src/javascript/typings/', true, /.*/));
|
||||
importAll(require.context('src/javascript/components/', true, /.*/));
|
||||
importAll(require.context('src/javascript/controllers/', true, /.*/));
|
||||
importAll(require.context('src/javascript/services/', true, /.*/));
|
||||
importAll(require.context('src/javascript/directives/', true, /.*/));
|
||||
importAll(require.context('src/javascript/filters/', true, /.*/));
|
||||
importAll(require.context('src/javascript/typings/', true, /.*/));
|
||||
|
||||
importAll(require.context('../images', true));
|
||||
importAll(require.context('../templates', true));
|
||||
importAll(require.context('images', true));
|
||||
importAll(require.context('templates', true));
|
@ -15,4 +15,4 @@
|
||||
@import '~angular-aside/dist/css/angular-aside';
|
||||
@import '~codemirror/lib/codemirror';
|
||||
|
||||
@import '../src/stylesheets/application.scss';
|
||||
@import 'src/stylesheets/application.scss';
|
@ -1,2 +0,0 @@
|
||||
|
||||
@import '../src/stylesheets/app.printer';
|
2
app/frontend/printer.scss
Normal file
2
app/frontend/printer.scss
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
@import 'src/stylesheets/app.printer';
|
@ -3,7 +3,7 @@ import { AxiosResponse } from 'axios';
|
||||
import { Space } from '../models/space';
|
||||
|
||||
export default class SpaceAPI {
|
||||
static async index (): Promise<Array<any>> {
|
||||
static async index (): Promise<Array<Space>> {
|
||||
const res: AxiosResponse<Array<Space>> = await apiClient.get('/api/spaces');
|
||||
return res?.data;
|
||||
}
|
||||
@ -12,5 +12,4 @@ export default class SpaceAPI {
|
||||
const res: AxiosResponse<Space> = await apiClient.get(`/api/spaces/${id}`);
|
||||
return res?.data;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
* creating namespaces and moduled for controllers, filters, services, and directives.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-var -- Application is a global variable.
|
||||
var Application = Application || {};
|
||||
|
||||
Application.Components = angular.module('application.components', []);
|
||||
@ -17,22 +18,17 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
'ngUpload', 'duScroll', 'application.filters', 'application.services', 'application.directives',
|
||||
'frapontillo.bootstrap-switch', 'application.controllers', 'application.router', 'application.components',
|
||||
'ui.select', 'ui.calendar', 'angularMoment', 'Devise', 'angular-growl', 'xeditable',
|
||||
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch', 'angular-google-analytics',
|
||||
'checklist-model', 'unsavedChanges', 'angular-loading-bar', 'ngTouch',
|
||||
'angularUtils.directives.dirDisqus', 'summernote', 'elasticsearch', 'angular-medium-editor', 'naif.base64',
|
||||
'minicolors', 'pascalprecht.translate', 'ngFitText', 'ngAside', 'ngCapsLock', 'vcRecaptcha', 'ui.codemirror',
|
||||
'bm.uiTour'])
|
||||
.config(['$httpProvider', 'AuthProvider', 'growlProvider', 'unsavedWarningsConfigProvider', 'AnalyticsProvider', 'uibDatepickerPopupConfig', '$provide', '$translateProvider', 'TourConfigProvider',
|
||||
function ($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, AnalyticsProvider, uibDatepickerPopupConfig, $provide, $translateProvider, TourConfigProvider) {
|
||||
.config(['$httpProvider', 'AuthProvider', 'growlProvider', 'unsavedWarningsConfigProvider', 'uibDatepickerPopupConfig', '$provide', '$translateProvider', 'TourConfigProvider', '$sceDelegateProvider',
|
||||
function ($httpProvider, AuthProvider, growlProvider, unsavedWarningsConfigProvider, uibDatepickerPopupConfig, $provide, $translateProvider, TourConfigProvider, $sceDelegateProvider) {
|
||||
// Google analytics
|
||||
// first we check the user acceptance
|
||||
const cookiesConsent = document.cookie.replace(/(?:(?:^|.*;\s*)fab-manager-cookies-consent\s*=\s*([^;]*).*$)|^.*$/, '$1');
|
||||
if (cookiesConsent === 'accept') {
|
||||
AnalyticsProvider.setAccount(Fablab.trackingId);
|
||||
// track all routes (or not)
|
||||
AnalyticsProvider.trackPages(true);
|
||||
AnalyticsProvider.setDomainName(Fablab.baseHostUrl);
|
||||
AnalyticsProvider.useAnalytics(true);
|
||||
AnalyticsProvider.setPageEvent('$stateChangeSuccess');
|
||||
GTM.enableAnalytics(Fablab.trackingId);
|
||||
} else {
|
||||
// if the cookies were not explicitly accepted, delete them
|
||||
document.cookie = '_ga=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
@ -65,8 +61,10 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
$translateProvider.preferredLanguage(Fablab.locale);
|
||||
// End the tour when the user clicks the forward or back buttons of the browser
|
||||
TourConfigProvider.enableNavigationInterceptors();
|
||||
}]).run(['$rootScope', '$log', 'Auth', 'amMoment', '$state', 'editableOptions', 'Analytics',
|
||||
function ($rootScope, $log, Auth, amMoment, $state, editableOptions, Analytics) {
|
||||
|
||||
$sceDelegateProvider.resourceUrlWhitelist(['self']);
|
||||
}]).run(['$rootScope', '$transitions', '$log', 'Auth', 'amMoment', '$state', 'editableOptions',
|
||||
function ($rootScope, $transitions, $log, Auth, amMoment, $state, editableOptions) {
|
||||
// Angular-moment (date-time manipulations library)
|
||||
amMoment.changeLocale(Fablab.moment_locale);
|
||||
|
||||
@ -75,9 +73,12 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
|
||||
// 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;
|
||||
$state.prevParams = fromParams;
|
||||
$transitions.onSuccess({ }, function (trans) {
|
||||
$state.prevState = trans.$from().name;
|
||||
$state.prevParams = trans.$from().params;
|
||||
|
||||
const path = trans.router.stateService.href(trans.$to(), {}, { absolute: true });
|
||||
GTM.trackPage(path, trans.$to().name);
|
||||
});
|
||||
|
||||
// Global function to allow the user to navigate to the previous screen (ie. $state).
|
||||
@ -85,7 +86,7 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
$rootScope.backPrevLocation = function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if ($state.prevState.name === '') {
|
||||
if ($state.prevState === '') {
|
||||
$state.prevState = 'app.public.home';
|
||||
}
|
||||
$state.go($state.prevState, $state.prevParams);
|
||||
@ -112,9 +113,9 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
|
||||
// Prevent the usage of the application for members with incomplete profiles: they will be redirected to
|
||||
// the 'profile completion' page. This is especially useful for user's accounts imported through SSO.
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState) {
|
||||
$transitions.onStart({}, function (trans) {
|
||||
Auth.currentUser().then(function (currentUser) {
|
||||
if (currentUser.need_completion && toState.name !== 'app.logged.profileCompletion') {
|
||||
if (currentUser.need_completion && trans.$to().name !== 'app.logged.profileCompletion') {
|
||||
$state.go('app.logged.profileCompletion');
|
||||
}
|
||||
}).catch(() => {
|
||||
@ -122,10 +123,6 @@ angular.module('application', ['ngCookies', 'ngResource', 'ngSanitize', 'ui.rout
|
||||
});
|
||||
});
|
||||
|
||||
// This code does nothing but it is here to remember to not remove the Analytics dependency,
|
||||
// see https://github.com/revolunet/angular-google-analytics#automatic-page-view-tracking
|
||||
Analytics.pageView();
|
||||
|
||||
/**
|
||||
* This helper method builds and return an array containing every integers between
|
||||
* the provided start and end.
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { FieldErrors, UseFormRegister, Validate } from 'react-hook-form';
|
||||
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||
|
||||
type inputType = string|number|readonly string [];
|
||||
type ruleTypes = {
|
||||
@ -9,12 +10,12 @@ type ruleTypes = {
|
||||
maxLenght?: number,
|
||||
min?: number,
|
||||
max?: number,
|
||||
validate?: Validate<any>;
|
||||
validate?: Validate<FieldValues>;
|
||||
};
|
||||
|
||||
interface RHFInputProps {
|
||||
id: string,
|
||||
register: UseFormRegister<any>,
|
||||
register: UseFormRegister<FieldValues>,
|
||||
label?: string,
|
||||
tooltip?: string,
|
||||
defaultValue?: inputType,
|
||||
|
@ -3,7 +3,7 @@ import { Node } from '@tiptap/core';
|
||||
export interface IframeOptions {
|
||||
allowFullscreen: boolean,
|
||||
HTMLAttributes: {
|
||||
[key: string]: any
|
||||
[key: string]: string
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ import WalletAPI from '../../api/wallet';
|
||||
import { Invoice } from '../../models/invoice';
|
||||
import SettingAPI from '../../api/setting';
|
||||
import { SettingName } from '../../models/setting';
|
||||
import { GoogleTagManager } from '../../models/gtm';
|
||||
import { ComputePriceResult } from '../../models/price';
|
||||
import { Wallet } from '../../models/wallet';
|
||||
import FormatLib from '../../lib/format';
|
||||
@ -52,6 +53,8 @@ interface AbstractPaymentModalProps {
|
||||
modalSize?: ModalSize,
|
||||
}
|
||||
|
||||
declare const GTM: GoogleTagManager;
|
||||
|
||||
/**
|
||||
* This component is an abstract modal that must be extended by each payment gateway to include its payment form.
|
||||
*
|
||||
@ -90,7 +93,9 @@ export const AbstractPaymentModal: React.FC<AbstractPaymentModalProps> = ({ isOp
|
||||
CustomAssetAPI.get(CustomAssetName.CgvFile).then(asset => setCgv(asset));
|
||||
SettingAPI.get(SettingName.PaymentGateway).then((setting) => {
|
||||
// we capitalize the first letter of the name
|
||||
setGateway(setting.value.replace(/^\w/, (c) => c.toUpperCase()));
|
||||
if (setting.value) {
|
||||
setGateway(setting.value.replace(/^\w/, (c) => c.toUpperCase()));
|
||||
}
|
||||
});
|
||||
|
||||
return () => { mounted.current = false; };
|
||||
@ -154,6 +159,7 @@ export const AbstractPaymentModal: React.FC<AbstractPaymentModalProps> = ({ isOp
|
||||
*/
|
||||
const handleFormSuccess = async (result: Invoice|PaymentSchedule): Promise<void> => {
|
||||
setSubmitState(false);
|
||||
GTM.trackPurchase(result.id, result.total);
|
||||
afterSuccess(result);
|
||||
};
|
||||
|
||||
|
@ -11,7 +11,7 @@ import { PaymentSchedule } from '../../../models/payment-schedule';
|
||||
* A form component to collect the credit card details and to create the payment method on Stripe.
|
||||
* The form validation button must be created elsewhere, using the attribute form={formId}.
|
||||
*/
|
||||
export const StripeForm: React.FC<GatewayFormProps> = ({ onSubmit, onSuccess, onError, children, className, paymentSchedule = false, cart, customer, operator, formId }) => {
|
||||
export const StripeForm: React.FC<GatewayFormProps> = ({ onSubmit, onSuccess, onError, children, className, paymentSchedule = false, cart, formId }) => {
|
||||
const { t } = useTranslation('shared');
|
||||
|
||||
const stripe = useStripe();
|
||||
|
@ -26,7 +26,6 @@ interface FreeExtendModalProps {
|
||||
* Modal dialog shown to extend the current subscription of a customer, for free
|
||||
*/
|
||||
const FreeExtendModal: React.FC<FreeExtendModalProps> = ({ isOpen, toggleModal, subscription, customerId, onError, onSuccess }) => {
|
||||
|
||||
// we do not render the modal if the subscription was not provided
|
||||
if (!subscription) return null;
|
||||
|
||||
|
@ -318,8 +318,8 @@ Application.Controllers.controller('NewAuthenticationController', ['$scope', '$s
|
||||
/**
|
||||
* Page to edit an already added authentication provider
|
||||
*/
|
||||
Application.Controllers.controller('EditAuthenticationController', ['$scope', '$state', '$stateParams', '$rootScope', '$uibModal', 'dialogs', 'growl', 'providerPromise', 'mappingFieldsPromise', 'AuthProvider', '_t',
|
||||
function ($scope, $state, $stateParams, $rootScope, $uibModal, dialogs, growl, providerPromise, mappingFieldsPromise, AuthProvider, _t) {
|
||||
Application.Controllers.controller('EditAuthenticationController', ['$scope', '$state', '$rootScope', '$uibModal', 'dialogs', 'growl', 'providerPromise', 'mappingFieldsPromise', 'AuthProvider', '_t',
|
||||
function ($scope, $state, $rootScope, $uibModal, dialogs, growl, providerPromise, mappingFieldsPromise, AuthProvider, _t) {
|
||||
// parameters of the currently edited authentication provider
|
||||
$scope.provider = providerPromise;
|
||||
|
||||
|
@ -619,12 +619,12 @@ Application.Controllers.controller('NewEventController', ['$scope', '$state', 'C
|
||||
/**
|
||||
* Controller used in the events edition page
|
||||
*/
|
||||
Application.Controllers.controller('EditEventController', ['$scope', '$state', '$stateParams', 'CSRF', 'eventPromise', 'categoriesPromise', 'themesPromise', 'ageRangesPromise', 'priceCategoriesPromise', '$uibModal', 'growl', '_t',
|
||||
function ($scope, $state, $stateParams, CSRF, eventPromise, categoriesPromise, themesPromise, ageRangesPromise, priceCategoriesPromise, $uibModal, growl, _t) {
|
||||
Application.Controllers.controller('EditEventController', ['$scope', '$state', '$transition$', 'CSRF', 'eventPromise', 'categoriesPromise', 'themesPromise', 'ageRangesPromise', 'priceCategoriesPromise', '$uibModal', 'growl', '_t',
|
||||
function ($scope, $state, $transition$, CSRF, eventPromise, categoriesPromise, themesPromise, ageRangesPromise, priceCategoriesPromise, $uibModal, growl, _t) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/events/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/events/${$transition$.params().id}`;
|
||||
|
||||
// Form action on the above URL
|
||||
$scope.method = 'put';
|
||||
|
@ -4,7 +4,7 @@
|
||||
no-undef,
|
||||
no-unreachable,
|
||||
no-unused-vars,
|
||||
standard/no-callback-literal,
|
||||
n/no-callback-literal,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
@ -17,8 +17,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Application.Controllers.controller('GraphsController', ['$scope', '$state', '$rootScope', 'es', 'Statistics', '_t',
|
||||
function ($scope, $state, $rootScope, es, Statistics, _t) {
|
||||
Application.Controllers.controller('GraphsController', ['$scope', '$state', '$rootScope', '$transitions', 'es', 'Statistics', '_t',
|
||||
function ($scope, $state, $rootScope, $transitions, es, Statistics, _t) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// height of the HTML/SVG charts elements in pixels
|
||||
@ -167,8 +167,8 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
|
||||
// workaround for angular-bootstrap::tabs behavior: on tab deletion, another tab will be selected
|
||||
// which will cause every tabs to reload, one by one, when the view is closed
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
|
||||
if ((fromState.name === 'app.admin.stats_graphs') && (Object.keys(fromParams).length === 0)) {
|
||||
$transitions.onStart({ to: 'app.admin.stats_graphs' }, function (trans) {
|
||||
if (Object.keys(trans.from().params).length === 0) {
|
||||
return $scope.preventRefresh = true;
|
||||
}
|
||||
});
|
||||
@ -179,7 +179,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param $event {Object} jQuery event object
|
||||
* @param datePicker {Object} settings object of the concerned datepicker. Must have an 'opened' property
|
||||
*/
|
||||
var toggleDatePicker = function ($event, datePicker) {
|
||||
const toggleDatePicker = function ($event, datePicker) {
|
||||
$event.preventDefault();
|
||||
$event.stopPropagation();
|
||||
return datePicker.opened = !datePicker.opened;
|
||||
@ -188,7 +188,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
/**
|
||||
* Query elasticSearch according to the current parameters and update the chart
|
||||
*/
|
||||
var refreshChart = function () {
|
||||
const refreshChart = function () {
|
||||
if ($scope.selectedIndex && !$scope.preventRefresh) {
|
||||
return query($scope.selectedIndex, function (aggregations, error) {
|
||||
if (error) {
|
||||
@ -239,7 +239,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* Format aggregations as retuned by elasticSearch to an understandable format for NVD3
|
||||
* @param aggs {Object} as returned by elasticsearch
|
||||
*/
|
||||
var formatAggregations = function (aggs) {
|
||||
const formatAggregations = function (aggs) {
|
||||
const format = {};
|
||||
|
||||
angular.forEach(aggs, function (type, type_key) { // go through aggs[$TYPE] where $TYPE = month|year|hour|booking|...
|
||||
@ -254,7 +254,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
const cur_subtype = cur_type.subtypes[it_st];
|
||||
if (subgroup.key === cur_subtype.key) { // ... which match $SUBTYPE
|
||||
// then we construct NVD3 dataSource according to these information
|
||||
var dataSource = {
|
||||
const dataSource = {
|
||||
values: [],
|
||||
key: cur_subtype.label,
|
||||
total: 0,
|
||||
@ -292,7 +292,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param limit {number} limit the number of stats in the bar chart
|
||||
* @param typeKey {String} field name witch results are grouped by
|
||||
*/
|
||||
var formatRankingAggregations = function (aggs, limit, typeKey) {
|
||||
const formatRankingAggregations = function (aggs, limit, typeKey) {
|
||||
const format =
|
||||
{ ranking: [] };
|
||||
|
||||
@ -325,7 +325,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param key {string} raw value of the label
|
||||
* @param typeKey {string} name of the field the results are grouped by
|
||||
*/
|
||||
var getRankingLabel = function (key, typeKey) {
|
||||
const getRankingLabel = function (key, typeKey) {
|
||||
if ($scope.selectedIndex) {
|
||||
if (typeKey === 'subType') {
|
||||
for (const type of Array.from($scope.selectedIndex.types)) {
|
||||
@ -356,7 +356,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param callback {function} function be to run after results were retrieved,
|
||||
* it will receive two parameters : results {Array}, error {String} (if any)
|
||||
*/
|
||||
var query = function (index, callback) {
|
||||
const query = function (index, callback) {
|
||||
// invalid callback handeling
|
||||
if (typeof (callback) !== 'function') {
|
||||
console.error('[graphsController::query] Error: invalid callback provided');
|
||||
@ -384,7 +384,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
let type_it = 0;
|
||||
const results = {};
|
||||
let error = '';
|
||||
var recursiveCb = function () {
|
||||
const recursiveCb = function () {
|
||||
if (type_it < stat_types.length) {
|
||||
return queryElasticStats(index.es_type_key, stat_types[type_it], function (prevResults, prevError) {
|
||||
if (prevError) {
|
||||
@ -418,7 +418,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param callback {function} function be to run after results were retrieved,
|
||||
* it will receive two parameters : results {Array}, error {String} (if any)
|
||||
*/
|
||||
var queryElasticStats = function (esType, statType, callback) {
|
||||
const queryElasticStats = function (esType, statType, callback) {
|
||||
// handle invalid callback
|
||||
if (typeof (callback) !== 'function') {
|
||||
console.error('[graphsController::queryElasticStats] Error: invalid callback provided');
|
||||
@ -457,7 +457,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param callback {function} function be to run after results were retrieved,
|
||||
* it will receive two parameters : results {Array}, error {String} (if any)
|
||||
*/
|
||||
var queryElasticRanking = function (esType, groupKey, sortKey, callback) {
|
||||
const queryElasticRanking = function (esType, groupKey, sortKey, callback) {
|
||||
// handle invalid callback
|
||||
if (typeof (callback) !== 'function') {
|
||||
return console.error('[graphsController::queryElasticRanking] Error: invalid callback provided');
|
||||
@ -497,15 +497,13 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param intervalBegin {moment} statitics interval beginning (moment.js type)
|
||||
* @param intervalEnd {moment} statitics interval ending (moment.js type)
|
||||
*/
|
||||
var buildElasticAggregationsQuery = function (type, interval, intervalBegin, intervalEnd) {
|
||||
const buildElasticAggregationsQuery = function (type, interval, intervalBegin, intervalEnd) {
|
||||
const q = {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
match: {
|
||||
type: type
|
||||
}
|
||||
match: { type }
|
||||
},
|
||||
{
|
||||
range: {
|
||||
@ -527,7 +525,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
intervals: {
|
||||
date_histogram: {
|
||||
field: 'date',
|
||||
interval: interval,
|
||||
interval,
|
||||
min_doc_count: 0,
|
||||
extended_bounds: {
|
||||
min: intervalBegin.valueOf(),
|
||||
@ -566,7 +564,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param intervalBegin {moment} statitics interval beginning (moment.js type)
|
||||
* @param intervalEnd {moment} statitics interval ending (moment.js type)
|
||||
*/
|
||||
var buildElasticAggregationsRankingQuery = function (groupKey, sortKey, intervalBegin, intervalEnd) {
|
||||
const buildElasticAggregationsRankingQuery = function (groupKey, sortKey, intervalBegin, intervalEnd) {
|
||||
const q = {
|
||||
query: {
|
||||
bool: {
|
||||
@ -635,7 +633,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param data {Array} array of NVD3 dataSources
|
||||
* @param type {String} which chart to update (statistic type key)
|
||||
*/
|
||||
var updateChart = function (chart_type, data, type) {
|
||||
const updateChart = function (chart_type, data, type) {
|
||||
const id = `#chart-${type} svg`;
|
||||
|
||||
// clean old charts
|
||||
@ -695,7 +693,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
/**
|
||||
* Given an NVD3 line chart axis, scale it to display ordinated dates, according to the given arguments
|
||||
*/
|
||||
var setTimeScale = function (nvd3Axis, nvd3Scale, argsArray) {
|
||||
const setTimeScale = function (nvd3Axis, nvd3Scale, argsArray) {
|
||||
const scale = d3.time.scale();
|
||||
|
||||
nvd3Axis.scale(scale);
|
||||
@ -710,7 +708,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
/**
|
||||
* Translate line chart data in dates row to bar chart data, one bar per type.
|
||||
*/
|
||||
var prepareDataForBarChart = function (data, type) {
|
||||
const prepareDataForBarChart = function (data, type) {
|
||||
const newData = [{
|
||||
key: type,
|
||||
values: []
|
||||
@ -738,7 +736,7 @@ Application.Controllers.controller('GraphsController', ['$scope', '$state', '$ro
|
||||
* @param getValue {function} the callback which will return the value on which the sort will occurs
|
||||
* @returns {Array}
|
||||
*/
|
||||
var stableSort = function (array, order, getValue) {
|
||||
const stableSort = function (array, order, getValue) {
|
||||
// prepare sorting
|
||||
const keys_order = [];
|
||||
const result = [];
|
||||
|
@ -55,13 +55,13 @@ Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise
|
||||
$scope.saveGroup = function (data, id) {
|
||||
if (id != null) {
|
||||
return Group.update({ id }, { group: data }, response => growl.success(_t('app.admin.members.group_form.changes_successfully_saved'))
|
||||
, error => growl.error(_t('app.admin.members.group_form.an_error_occurred_while_saving_changes')));
|
||||
, () => growl.error(_t('app.admin.members.group_form.an_error_occurred_while_saving_changes')));
|
||||
} else {
|
||||
return Group.save({ group: data }, function (resp) {
|
||||
growl.success(_t('app.admin.members.group_form.new_group_successfully_saved'));
|
||||
return $scope.groups[$scope.groups.length - 1].id = resp.id;
|
||||
}
|
||||
, function (error) {
|
||||
, function () {
|
||||
growl.error(_t('app.admin.members.group_form.an_error_occurred_when_saving_the_new_group'));
|
||||
return $scope.groups.splice($scope.groups.length - 1, 1);
|
||||
});
|
||||
@ -77,7 +77,7 @@ Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise
|
||||
growl.success(_t('app.admin.members.group_form.group_successfully_deleted'));
|
||||
return $scope.groups.splice(index, 1);
|
||||
}
|
||||
, error => growl.error(_t('app.admin.members.group_form.unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it')));
|
||||
, () => growl.error(_t('app.admin.members.group_form.unable_to_delete_group_because_some_users_and_or_groups_are_still_linked_to_it')));
|
||||
|
||||
/**
|
||||
* Enable/disable the group at the specified index
|
||||
@ -92,7 +92,7 @@ Application.Controllers.controller('GroupsController', ['$scope', 'groupsPromise
|
||||
$scope.groups[index] = response;
|
||||
return growl.success(_t('app.admin.members.group_form.group_successfully_enabled_disabled', { STATUS: response.disabled }));
|
||||
}
|
||||
, error => growl.error(_t('app.admin.members.group_form.unable_to_enable_disable_group', { STATUS: !group.disabled })));
|
||||
, () => growl.error(_t('app.admin.members.group_form.unable_to_enable_disable_group', { STATUS: !group.disabled })));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -195,6 +195,14 @@ Application.Controllers.controller('InvoicesController', ['$scope', '$state', 'I
|
||||
name: 'accounting_Space_label',
|
||||
value: settings.accounting_Space_label
|
||||
},
|
||||
packCode: {
|
||||
name: 'accounting_Pack_code',
|
||||
value: settings.accounting_Pack_code
|
||||
},
|
||||
packLabel: {
|
||||
name: 'accounting_Pack_label',
|
||||
value: settings.accounting_Pack_label
|
||||
},
|
||||
errorCode: {
|
||||
name: 'accounting_Error_code',
|
||||
value: settings.accounting_Error_code
|
||||
@ -1239,7 +1247,7 @@ Application.Controllers.controller('AvoirModalController', ['$scope', '$uibModal
|
||||
function (avoir) { // success
|
||||
$uibModalInstance.close({ avoir, invoice: $scope.invoice });
|
||||
},
|
||||
function (err) { // failed
|
||||
function () { // failed
|
||||
growl.error(_t('app.admin.invoices.unable_to_create_the_refund'));
|
||||
}
|
||||
);
|
||||
|
@ -650,12 +650,12 @@ Application.Controllers.controller('AdminMembersController', ['$scope', '$sce',
|
||||
/**
|
||||
* Controller used in the member edition page
|
||||
*/
|
||||
Application.Controllers.controller('EditMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'activeProviderPromise', 'Wallet', 'settingsPromise',
|
||||
function ($scope, $state, $stateParams, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, activeProviderPromise, Wallet, settingsPromise) {
|
||||
Application.Controllers.controller('EditMemberController', ['$scope', '$state', '$transition$', 'Member', 'Training', 'dialogs', 'growl', 'Group', 'Subscription', 'CSRF', 'memberPromise', 'tagsPromise', '$uibModal', 'Plan', '$filter', '_t', 'walletPromise', 'transactionsPromise', 'activeProviderPromise', 'Wallet', 'settingsPromise',
|
||||
function ($scope, $state, $transition$, Member, Training, dialogs, growl, Group, Subscription, CSRF, memberPromise, tagsPromise, $uibModal, Plan, $filter, _t, walletPromise, transactionsPromise, activeProviderPromise, Wallet, settingsPromise) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/members/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/members/${$transition$.params().id}`;
|
||||
|
||||
// Form action on the above URL
|
||||
$scope.method = 'patch';
|
||||
@ -922,8 +922,8 @@ Application.Controllers.controller('EditMemberController', ['$scope', '$state',
|
||||
/**
|
||||
* Controller used in the member's creation page (admin view)
|
||||
*/
|
||||
Application.Controllers.controller('NewMemberController', ['$scope', '$state', '$stateParams', 'Member', 'Training', 'Group', 'CSRF', 'settingsPromise',
|
||||
function ($scope, $state, $stateParams, Member, Training, Group, CSRF, settingsPromise) {
|
||||
Application.Controllers.controller('NewMemberController', ['$scope', '$state', 'Member', 'Training', 'Group', 'CSRF', 'settingsPromise',
|
||||
function ($scope, $state, Member, Training, Group, CSRF, settingsPromise) {
|
||||
CSRF.setMetaTags();
|
||||
|
||||
/* PUBLIC SCOPE */
|
||||
|
@ -224,8 +224,8 @@ Application.Controllers.controller('NewPlanController', ['$scope', '$uibModal',
|
||||
/**
|
||||
* Controller used in the plan edition form
|
||||
*/
|
||||
Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'plans', 'planPromise', 'machines', 'spaces', 'prices', 'partners', 'CSRF', '$state', '$stateParams', 'growl', '$filter', '_t', 'Plan', 'planCategories',
|
||||
function ($scope, groups, plans, planPromise, machines, spaces, prices, partners, CSRF, $state, $stateParams, growl, $filter, _t, Plan, planCategories) {
|
||||
Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'plans', 'planPromise', 'machines', 'spaces', 'prices', 'partners', 'CSRF', '$state', '$transition$', 'growl', '$filter', '_t', 'Plan', 'planCategories',
|
||||
function ($scope, groups, plans, planPromise, machines, spaces, prices, partners, CSRF, $state, $transition$, growl, $filter, _t, Plan, planCategories) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// List of spaces
|
||||
@ -254,7 +254,7 @@ Application.Controllers.controller('EditPlanController', ['$scope', 'groups', 'p
|
||||
if ($scope.plan.disabled) { $scope.plan.disabled = 'true'; }
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/plans/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/plans/${$transition$.params().id}`;
|
||||
|
||||
// HTTP method for the rest API
|
||||
$scope.method = 'PATCH';
|
||||
|
@ -403,7 +403,7 @@ Application.Controllers.controller('EditPricingController', ['$scope', '$state',
|
||||
$scope.spaceCredits[$scope.spaceCredits.length - 1].id = resp.id;
|
||||
return growl.success(_t('app.admin.pricing.credit_was_successfully_saved'));
|
||||
}
|
||||
, function (err) {
|
||||
, function () {
|
||||
$scope.spaceCredits.pop();
|
||||
return growl.error(_t('app.admin.pricing.error_creating_credit'));
|
||||
});
|
||||
|
@ -2,7 +2,7 @@
|
||||
no-constant-condition,
|
||||
no-return-assign,
|
||||
no-undef,
|
||||
standard/no-callback-literal,
|
||||
n/no-callback-literal,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
@ -15,8 +15,8 @@
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Application.Controllers.controller('StatisticsController', ['$scope', '$state', '$rootScope', '$uibModal', 'es', 'Member', '_t', 'membersPromise', 'statisticsPromise', 'uiTourService', 'settingsPromise',
|
||||
function ($scope, $state, $rootScope, $uibModal, es, Member, _t, membersPromise, statisticsPromise, uiTourService, settingsPromise) {
|
||||
Application.Controllers.controller('StatisticsController', ['$scope', '$state', '$transitions', '$rootScope', '$uibModal', 'es', 'Member', '_t', 'membersPromise', 'statisticsPromise', 'uiTourService', 'settingsPromise',
|
||||
function ($scope, $state, $transitions, $rootScope, $uibModal, es, Member, _t, membersPromise, statisticsPromise, uiTourService, settingsPromise) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// search window size
|
||||
@ -407,8 +407,8 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
|
||||
const initialize = function () {
|
||||
// workaround for angular-bootstrap::tabs behavior: on tab deletion, another tab will be selected
|
||||
// which will cause every tabs to reload, one by one, when the view is closed
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
|
||||
if ((fromState.name === 'app.admin.statistics') && (Object.keys(fromParams).length === 0)) {
|
||||
$transitions.onStart({ to: 'app.admin.statistics' }, function (trans) {
|
||||
if (Object.keys(trans.from().params).length === 0) {
|
||||
return $scope.preventRefresh = true;
|
||||
}
|
||||
});
|
||||
@ -522,9 +522,7 @@ Application.Controllers.controller('StatisticsController', ['$scope', '$state',
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
type: type
|
||||
}
|
||||
term: { type }
|
||||
},
|
||||
{
|
||||
range: {
|
||||
|
@ -45,13 +45,13 @@ Application.Controllers.controller('TagsController', ['$scope', 'tagsPromise', '
|
||||
$scope.saveTag = function (data, id) {
|
||||
if (id != null) {
|
||||
return Tag.update({ id }, { tag: data }, response => growl.success(_t('app.admin.members.tag_form.changes_successfully_saved'))
|
||||
, error => growl.error(_t('app.admin.members.tag_form.an_error_occurred_while_saving_changes')));
|
||||
, () => growl.error(_t('app.admin.members.tag_form.an_error_occurred_while_saving_changes')));
|
||||
} else {
|
||||
return Tag.save({ tag: data }, function (resp) {
|
||||
growl.success(_t('app.admin.members.tag_form.new_tag_successfully_saved'));
|
||||
return $scope.tags[$scope.tags.length - 1].id = resp.id;
|
||||
}
|
||||
, function (error) {
|
||||
, function () {
|
||||
growl.error(_t('app.admin.members.tag_form.an_error_occurred_while_saving_the_new_tag'));
|
||||
return $scope.tags.splice($scope.tags.length - 1, 1);
|
||||
});
|
||||
@ -78,7 +78,7 @@ Application.Controllers.controller('TagsController', ['$scope', 'tagsPromise', '
|
||||
growl.success(_t('app.admin.members.tag_form.tag_successfully_deleted'));
|
||||
return $scope.tags.splice(index, 1);
|
||||
}
|
||||
, error => growl.error(_t('app.admin.members.tag_form.an_error_occurred_and_the_tag_deletion_failed')));
|
||||
, () => growl.error(_t('app.admin.members.tag_form.an_error_occurred_and_the_tag_deletion_failed')));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -114,15 +114,15 @@ Application.Controllers.controller('NewTrainingController', ['$scope', '$state',
|
||||
/**
|
||||
* Controller used in the training edition page (admin)
|
||||
*/
|
||||
Application.Controllers.controller('EditTrainingController', ['$scope', '$state', '$stateParams', 'trainingPromise', 'machinesPromise', 'CSRF',
|
||||
function ($scope, $state, $stateParams, trainingPromise, machinesPromise, CSRF) {
|
||||
Application.Controllers.controller('EditTrainingController', ['$scope', '$state', '$transition$', 'trainingPromise', 'machinesPromise', 'CSRF',
|
||||
function ($scope, $state, $transition$, trainingPromise, machinesPromise, CSRF) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// Form action on the following URL
|
||||
$scope.method = 'patch';
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/trainings/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/trainings/${$transition$.params().id}`;
|
||||
|
||||
// Details of the training to edit (id in URL)
|
||||
$scope.training = trainingPromise;
|
||||
|
@ -12,8 +12,8 @@
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
|
||||
Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$window', '$locale', '$timeout', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version', 'Help',
|
||||
function ($rootScope, $scope, $window, $locale, $timeout, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version, Help) {
|
||||
Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$transitions', '$window', '$locale', '$timeout', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version', 'Help',
|
||||
function ($rootScope, $scope, $transitions, $window, $locale, $timeout, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version, Help) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// User's notifications will get refreshed every 30s
|
||||
@ -325,19 +325,18 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
$rootScope.toCheckNotifications = false;
|
||||
});
|
||||
|
||||
// bind to the $stateChangeStart event (AngularJS/UI-Router)
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
|
||||
if (!toState.data) { return; }
|
||||
// bind to the $transitions.onStart event (UI-Router)
|
||||
$transitions.onStart({}, function (trans) {
|
||||
if (!trans.$to().data) { return; }
|
||||
|
||||
const { authorizedRoles } = toState.data;
|
||||
const { authorizedRoles } = trans.$to().data;
|
||||
if (!AuthService.isAuthorized(authorizedRoles)) {
|
||||
event.preventDefault();
|
||||
if (AuthService.isAuthenticated()) {
|
||||
// user is not allowed
|
||||
console.error('[ApplicationController::initialize] user is not allowed');
|
||||
} else {
|
||||
// user is not logged in
|
||||
openLoginModal(toState, toParams);
|
||||
openLoginModal(trans.$to().name, trans.$to().params);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -462,6 +461,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco
|
||||
// what to do when the modal is closed
|
||||
|
||||
// authentication succeeded, set the session, gather the notifications and redirect
|
||||
GTM.trackLogin();
|
||||
$scope.setCurrentUser(user);
|
||||
|
||||
if ((toState !== null) && (toParams !== null)) {
|
||||
|
@ -13,28 +13,20 @@ Application.Controllers.controller('CookiesController', ['$scope', '$cookies', '
|
||||
// link pointed by "learn more"
|
||||
$scope.learnMoreUrl = 'https://www.cookiesandyou.com/';
|
||||
|
||||
// current user wallet
|
||||
// add a cookie to the browser, saving the user choice to refuse cookies
|
||||
$scope.declineCookies = function () {
|
||||
const expires = moment().add(13, 'months').toDate();
|
||||
$cookies.put('fab-manager-cookies-consent', 'decline', { expires });
|
||||
readCookie();
|
||||
};
|
||||
|
||||
// current wallet transactions
|
||||
// add a cookie to the browser, saving the user choice to accept cookies.
|
||||
// Then enable the analytics
|
||||
$scope.acceptCookies = function () {
|
||||
const expires = moment().add(13, 'months').toDate();
|
||||
$cookies.put('fab-manager-cookies-consent', 'accept', { expires });
|
||||
readCookie();
|
||||
// enable tracking using code provided by google analytics
|
||||
/* eslint-disable */
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', Fablab.trackingId, 'auto');
|
||||
ga('send', 'pageview');
|
||||
/* eslint-enable */
|
||||
GTM.enableAnalytics(Fablab.trackingId);
|
||||
};
|
||||
|
||||
/* PRIVATE SCOPE */
|
||||
@ -44,7 +36,7 @@ Application.Controllers.controller('CookiesController', ['$scope', '$cookies', '
|
||||
*/
|
||||
const initialize = function () {
|
||||
readCookie();
|
||||
// if the privacy policy was defined, redirect the user to it
|
||||
// if the privacy policy was defined, redirect the user to it when clicking on "read more"
|
||||
Setting.get({ name: 'privacy_body' }, data => {
|
||||
if (data.setting.value) {
|
||||
$scope.learnMoreUrl = '#!/privacy-policy';
|
||||
|
@ -126,8 +126,8 @@ Application.Controllers.controller('EventsController', ['$scope', '$state', 'Eve
|
||||
}
|
||||
]);
|
||||
|
||||
Application.Controllers.controller('ShowEventController', ['$scope', '$state', '$stateParams', '$rootScope', 'Event', '$uibModal', 'Member', 'Reservation', 'Price', 'CustomAsset', 'Slot', 'eventPromise', 'growl', '_t', 'Wallet', 'AuthService', 'helpers', 'dialogs', 'priceCategoriesPromise', 'settingsPromise', 'LocalPayment',
|
||||
function ($scope, $state, $stateParams, $rootScope, Event, $uibModal, Member, Reservation, Price, CustomAsset, Slot, eventPromise, growl, _t, Wallet, AuthService, helpers, dialogs, priceCategoriesPromise, settingsPromise, LocalPayment) {
|
||||
Application.Controllers.controller('ShowEventController', ['$scope', '$state', '$rootScope', 'Event', '$uibModal', 'Member', 'Reservation', 'Price', 'CustomAsset', 'Slot', 'eventPromise', 'growl', '_t', 'Wallet', 'AuthService', 'helpers', 'dialogs', 'priceCategoriesPromise', 'settingsPromise', 'LocalPayment',
|
||||
function ($scope, $state,$rootScope, Event, $uibModal, Member, Reservation, Price, CustomAsset, Slot, eventPromise, growl, _t, Wallet, AuthService, helpers, dialogs, priceCategoriesPromise, settingsPromise, LocalPayment) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// reservations for the currently shown event
|
||||
|
@ -1,11 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
Application.Controllers.controller('HeaderController', ['$scope', '$rootScope', '$state', 'settingsPromise',
|
||||
function ($scope, $rootScope, $state, settingsPromise) {
|
||||
Application.Controllers.controller('HeaderController', ['$scope', '$transitions', '$state', 'settingsPromise',
|
||||
function ($scope, $transitions, $state, settingsPromise) {
|
||||
$scope.aboutPage = ($state.current.name === 'app.public.about');
|
||||
|
||||
$rootScope.$on('$stateChangeStart', function (event, toState) {
|
||||
$scope.aboutPage = (toState.name === 'app.public.about');
|
||||
$transitions.onStart({}, function (trans) {
|
||||
$scope.aboutPage = (trans.$to().name === 'app.public.about');
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
Application.Controllers.controller('HomeController', ['$scope', '$stateParams', '$translatePartialLoader', 'AuthService', 'settingsPromise', 'Member', 'uiTourService', '_t',
|
||||
function ($scope, $stateParams, $translatePartialLoader, AuthService, settingsPromise, Member, uiTourService, _t) {
|
||||
Application.Controllers.controller('HomeController', ['$scope', '$transition$', '$translatePartialLoader', 'AuthService', 'settingsPromise', 'Member', 'uiTourService', '_t',
|
||||
function ($scope, $transition$, $translatePartialLoader, AuthService, settingsPromise, Member, uiTourService, _t) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// Home page HTML content
|
||||
@ -38,8 +38,8 @@ Application.Controllers.controller('HomeController', ['$scope', '$stateParams',
|
||||
const initialize = function () {
|
||||
// if we receive a token to reset the password as GET parameter, trigger the
|
||||
// changePassword modal from the parent controller
|
||||
if ($stateParams.reset_password_token) {
|
||||
return $scope.$parent.editPassword($stateParams.reset_password_token);
|
||||
if ($transition$.params().reset_password_token) {
|
||||
return $scope.$parent.editPassword($transition$.params().reset_password_token);
|
||||
}
|
||||
|
||||
// We set the home page content, with the directives replacing the placeholders
|
||||
|
@ -245,12 +245,12 @@ Application.Controllers.controller('NewMachineController', ['$scope', '$state',
|
||||
/**
|
||||
* Controller used in the machine edition page (admin)
|
||||
*/
|
||||
Application.Controllers.controller('EditMachineController', ['$scope', '$state', '$stateParams', 'machinePromise', 'CSRF',
|
||||
function ($scope, $state, $stateParams, machinePromise, CSRF) {
|
||||
Application.Controllers.controller('EditMachineController', ['$scope', '$state', '$transition$', 'machinePromise', 'CSRF',
|
||||
function ($scope, $state, $transition$, machinePromise, CSRF) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/machines/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/machines/${$transition$.params().id}`;
|
||||
|
||||
// Form action on the above URL
|
||||
$scope.method = 'put';
|
||||
@ -278,8 +278,8 @@ Application.Controllers.controller('EditMachineController', ['$scope', '$state',
|
||||
/**
|
||||
* Controller used in the machine details page (public)
|
||||
*/
|
||||
Application.Controllers.controller('ShowMachineController', ['$scope', '$state', '$uibModal', '$stateParams', '_t', 'Machine', 'growl', 'machinePromise', 'dialogs',
|
||||
function ($scope, $state, $uibModal, $stateParams, _t, Machine, growl, machinePromise, dialogs) {
|
||||
Application.Controllers.controller('ShowMachineController', ['$scope', '$state', '$uibModal', '_t', 'Machine', 'growl', 'machinePromise', 'dialogs',
|
||||
function ($scope, $state, $uibModal, _t, Machine, growl, machinePromise, dialogs) {
|
||||
// Retrieve the details for the machine id in the URL, if an error occurs redirect the user to the machines list
|
||||
$scope.machine = machinePromise;
|
||||
|
||||
@ -357,8 +357,8 @@ Application.Controllers.controller('ShowMachineController', ['$scope', '$state',
|
||||
* This controller workflow is pretty similar to the trainings reservation controller.
|
||||
*/
|
||||
|
||||
Application.Controllers.controller('ReserveMachineController', ['$scope', '$stateParams', '_t', 'moment', 'Auth', '$timeout', 'Member', 'Availability', 'plansPromise', 'groupsPromise', 'machinePromise', 'settingsPromise', 'uiCalendarConfig', 'CalendarConfig', 'Reservation', 'growl',
|
||||
function ($scope, $stateParams, _t, moment, Auth, $timeout, Member, Availability, plansPromise, groupsPromise, machinePromise, settingsPromise, uiCalendarConfig, CalendarConfig, Reservation, growl) {
|
||||
Application.Controllers.controller('ReserveMachineController', ['$scope', '$transition$', '_t', 'moment', 'Auth', '$timeout', 'Member', 'Availability', 'plansPromise', 'groupsPromise', 'machinePromise', 'settingsPromise', 'uiCalendarConfig', 'CalendarConfig', 'Reservation', 'growl',
|
||||
function ($scope, $transition$, _t, moment, Auth, $timeout, Member, Availability, plansPromise, groupsPromise, machinePromise, settingsPromise, uiCalendarConfig, CalendarConfig, Reservation, growl) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// Slot free to be booked
|
||||
@ -660,7 +660,7 @@ Application.Controllers.controller('ReserveMachineController', ['$scope', '$stat
|
||||
const initialize = function () {
|
||||
$scope.eventSources.push({
|
||||
events: function (start, end, timezone, callback) {
|
||||
Availability.machine({ machineId: $stateParams.id }, function (availabilities) {
|
||||
Availability.machine({ machineId: $transition$.params().id }, function (availabilities) {
|
||||
callback(availabilities);
|
||||
});
|
||||
},
|
||||
|
@ -323,7 +323,7 @@ Application.Controllers.controller('ShowProfileController', ['$scope', 'memberPr
|
||||
* and return the filtered networks
|
||||
* @return {Array}
|
||||
*/
|
||||
var filterNetworks = function () {
|
||||
const filterNetworks = function () {
|
||||
const networks = [];
|
||||
for (const network of Array.from(SocialNetworks)) {
|
||||
if ($scope.user.profile[network] && ($scope.user.profile[network].length > 0)) {
|
||||
|
@ -480,12 +480,12 @@ Application.Controllers.controller('NewProjectController', ['$rootScope', '$scop
|
||||
/**
|
||||
* Controller used in the project edition page
|
||||
*/
|
||||
Application.Controllers.controller('EditProjectController', ['$rootScope', '$scope', '$state', '$stateParams', 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'projectPromise', 'Diacritics', 'dialogs', 'allowedExtensions', '_t',
|
||||
function ($rootScope, $scope, $state, $stateParams, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, projectPromise, Diacritics, dialogs, allowedExtensions, _t) {
|
||||
Application.Controllers.controller('EditProjectController', ['$rootScope', '$scope', '$state', '$transition$', 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'projectPromise', 'Diacritics', 'dialogs', 'allowedExtensions', '_t',
|
||||
function ($rootScope, $scope, $state, $transition$, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, projectPromise, Diacritics, dialogs, allowedExtensions, _t) {
|
||||
/* PUBLIC SCOPE */
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/projects/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/projects/${$transition$.params().id}`;
|
||||
|
||||
// Form action on the above URL
|
||||
$scope.method = 'put';
|
||||
@ -618,7 +618,7 @@ Application.Controllers.controller('ShowProjectController', ['$scope', '$state',
|
||||
growl.success(_t('app.public.projects_show.your_report_was_successful_thanks'));
|
||||
return $uibModalInstance.close(res);
|
||||
}
|
||||
, function (error) {
|
||||
, function () {
|
||||
// creation failed...
|
||||
growl.error(_t('app.public.projects_show.an_error_occured_while_sending_your_report'));
|
||||
}
|
||||
|
@ -234,12 +234,12 @@ Application.Controllers.controller('NewSpaceController', ['$scope', '$state', 'C
|
||||
/**
|
||||
* Controller used in the space edition page (admin)
|
||||
*/
|
||||
Application.Controllers.controller('EditSpaceController', ['$scope', '$state', '$stateParams', 'spacePromise', 'CSRF',
|
||||
function ($scope, $state, $stateParams, spacePromise, CSRF) {
|
||||
Application.Controllers.controller('EditSpaceController', ['$scope', '$state', '$transition$', 'spacePromise', 'CSRF',
|
||||
function ($scope, $state, $transition$, spacePromise, CSRF) {
|
||||
CSRF.setMetaTags();
|
||||
|
||||
// API URL where the form will be posted
|
||||
$scope.actionUrl = `/api/spaces/${$stateParams.id}`;
|
||||
$scope.actionUrl = `/api/spaces/${$transition$.params().id}`;
|
||||
|
||||
// Form action on the above URL
|
||||
$scope.method = 'put';
|
||||
@ -307,8 +307,8 @@ Application.Controllers.controller('ShowSpaceController', ['$scope', '$state', '
|
||||
* per slots.
|
||||
*/
|
||||
|
||||
Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateParams', 'Auth', '$timeout', 'Availability', 'Member', 'plansPromise', 'groupsPromise', 'settingsPromise', 'spacePromise', '_t', 'uiCalendarConfig', 'CalendarConfig', 'Reservation',
|
||||
function ($scope, $stateParams, Auth, $timeout, Availability, Member, plansPromise, groupsPromise, settingsPromise, spacePromise, _t, uiCalendarConfig, CalendarConfig, Reservation) {
|
||||
Application.Controllers.controller('ReserveSpaceController', ['$scope', '$transition$', 'Auth', '$timeout', 'Availability', 'Member', 'plansPromise', 'groupsPromise', 'settingsPromise', 'spacePromise', '_t', 'uiCalendarConfig', 'CalendarConfig', 'Reservation',
|
||||
function ($scope, $transition$, Auth, $timeout, Availability, Member, plansPromise, groupsPromise, settingsPromise, spacePromise, _t, uiCalendarConfig, CalendarConfig, Reservation) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// Color of the selected event backgound
|
||||
@ -601,7 +601,7 @@ Application.Controllers.controller('ReserveSpaceController', ['$scope', '$stateP
|
||||
// in the router because this allows to refetchEvents from fullCalendar API.
|
||||
$scope.eventSources.push({
|
||||
events: function (start, end, timezone, callback) {
|
||||
Availability.spaces({ spaceId: $stateParams.id }, function (availabilities) {
|
||||
Availability.spaces({ spaceId: $transition$.params().id }, function (availabilities) {
|
||||
callback(availabilities);
|
||||
});
|
||||
},
|
||||
|
@ -91,8 +91,8 @@ Application.Controllers.controller('ShowTrainingController', ['$scope', '$state'
|
||||
* training can be reserved during the reservation process (the shopping cart may contains only one training and a subscription).
|
||||
*/
|
||||
|
||||
Application.Controllers.controller('ReserveTrainingController', ['$scope', '$stateParams', 'Auth', 'AuthService', '$timeout', 'Availability', 'Member', 'plansPromise', 'groupsPromise', 'settingsPromise', 'trainingPromise', '_t', 'uiCalendarConfig', 'CalendarConfig', 'Reservation',
|
||||
function ($scope, $stateParams, Auth, AuthService, $timeout, Availability, Member, plansPromise, groupsPromise, settingsPromise, trainingPromise, _t, uiCalendarConfig, CalendarConfig, Reservation) {
|
||||
Application.Controllers.controller('ReserveTrainingController', ['$scope', '$transition$', 'Auth', 'AuthService', '$timeout', 'Availability', 'Member', 'plansPromise', 'groupsPromise', 'settingsPromise', 'trainingPromise', '_t', 'uiCalendarConfig', 'CalendarConfig', 'Reservation',
|
||||
function ($scope, $transition$, Auth, AuthService, $timeout, Availability, Member, plansPromise, groupsPromise, settingsPromise, trainingPromise, _t, uiCalendarConfig, CalendarConfig, Reservation) {
|
||||
/* PRIVATE STATIC CONSTANTS */
|
||||
|
||||
// Color of the selected event backgound
|
||||
@ -144,7 +144,7 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
|
||||
$scope.training = trainingPromise;
|
||||
|
||||
// 'all' OR training's slug
|
||||
$scope.mode = $stateParams.id;
|
||||
$scope.mode = $transition$.params().id;
|
||||
|
||||
// fullCalendar (v2) configuration
|
||||
$scope.calendarConfig = CalendarConfig({
|
||||
@ -279,7 +279,7 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
|
||||
if ($scope.ctrl.member) {
|
||||
Member.get({ id: $scope.ctrl.member.id }, function (member) {
|
||||
$scope.ctrl.member = member;
|
||||
const id = $stateParams.id === 'all' ? $stateParams.id : $scope.training.id;
|
||||
const id = $transition$.params().id === 'all' ? $transition$.params().id : $scope.training.id;
|
||||
return Availability.trainings({ trainingId: id, member_id: $scope.ctrl.member.id }, function (trainings) {
|
||||
uiCalendarConfig.calendars.calendar.fullCalendar('removeEvents');
|
||||
return $scope.eventSources.splice(0, 1, {
|
||||
@ -391,7 +391,7 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
|
||||
// in the router because this allows to refetchEvents from fullCalendar API.
|
||||
$scope.eventSources.push({
|
||||
events: function (start, end, timezone, callback) {
|
||||
Availability.trainings({ trainingId: $stateParams.id }, function (availabilities) {
|
||||
Availability.trainings({ trainingId: $transition$.params().id }, function (availabilities) {
|
||||
callback(availabilities);
|
||||
});
|
||||
},
|
||||
@ -408,7 +408,7 @@ Application.Controllers.controller('ReserveTrainingController', ['$scope', '$sta
|
||||
*/
|
||||
const calendarEventClickCb = function (event, jsEvent, view) {
|
||||
$scope.selectedEvent = event;
|
||||
if ($stateParams.id === 'all') {
|
||||
if ($transition$.params().id === 'all') {
|
||||
$scope.training = event.training;
|
||||
}
|
||||
return $scope.selectionTime = new Date();
|
||||
|
@ -4,9 +4,9 @@ Application.Directives.directive('bsJasnyFileinput', [function () {
|
||||
return {
|
||||
require: ['ngModel'],
|
||||
link: function ($scope, elm, attrs, requiredCtrls) {
|
||||
var ngModelCtrl = requiredCtrls[0];
|
||||
var fileinput = elm.parents('[data-provides=fileinput]');
|
||||
var filetypeRegex = attrs.bsJasnyFileinput;
|
||||
const ngModelCtrl = requiredCtrls[0];
|
||||
const fileinput = elm.parents('[data-provides=fileinput]');
|
||||
const filetypeRegex = attrs.bsJasnyFileinput;
|
||||
fileinput.on('clear.bs.fileinput', function (e) {
|
||||
if (ngModelCtrl) {
|
||||
ngModelCtrl.$setViewValue(null);
|
||||
|
@ -1,8 +1,3 @@
|
||||
/* eslint-disable
|
||||
no-undef,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
@ -135,7 +130,7 @@ Application.Filters.filter('projectsCollabored', [function () {
|
||||
};
|
||||
}]);
|
||||
|
||||
// depend on humanize.js lib in /vendor
|
||||
// depend on app/frontend/src/javascript/lib/humanize.js
|
||||
Application.Filters.filter('humanize', [function () {
|
||||
return (element, param) => Humanize.truncate(element, param, null);
|
||||
}]);
|
||||
@ -157,6 +152,8 @@ Application.Filters.filter('breakFilter', [function () {
|
||||
Application.Filters.filter('simpleText', [function () {
|
||||
return function (text) {
|
||||
if (text != null) {
|
||||
// add a line break after specific closing tags
|
||||
text = text.replace(/(<\/p>|<\/h4>|<\/h5>|<\/h6>|<\/pre>|<\/blockquote>)/g, '\n');
|
||||
text = text.replace(/<br\s*\/?>/g, '\n');
|
||||
return text.replace(/<\/?\w+[^>]*>/g, '');
|
||||
} else {
|
||||
@ -166,7 +163,7 @@ Application.Filters.filter('simpleText', [function () {
|
||||
}]);
|
||||
|
||||
Application.Filters.filter('toTrusted', ['$sce', function ($sce) {
|
||||
return text => $sce.getTrustedHtml(text);
|
||||
return text => $sce.trustAsHtml(text);
|
||||
}]);
|
||||
|
||||
Application.Filters.filter('planIntervalFilter', [function () {
|
||||
|
@ -11,7 +11,7 @@
|
||||
'Auth',
|
||||
'$rootScope',
|
||||
function ($uibModal, $http, Auth, $rootScope) {
|
||||
var promise = null;
|
||||
let promise = null;
|
||||
function reset () {
|
||||
promise = null;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ angular.module('angularUtils.directives.dirDisqus', [])
|
||||
|
||||
// get the remote Disqus script and insert it into the DOM, but only if it not already loaded (as that will cause warnings)
|
||||
if (!$window.DISQUS) {
|
||||
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
const dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
||||
dsq.src = '//' + scope.disqus_shortname + '.disqus.com/embed.js';
|
||||
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
||||
} else {
|
||||
|
@ -9,7 +9,7 @@ export default class FormatLib {
|
||||
*/
|
||||
static date = (date: Date): string => {
|
||||
return Intl.DateTimeFormat().format(moment(date).toDate());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the formatted localized time for the given date
|
||||
@ -23,12 +23,12 @@ export default class FormatLib {
|
||||
*/
|
||||
static duration = (interval: unitOfTime.DurationConstructor, intervalCount: number): string => {
|
||||
return moment.duration(intervalCount, interval).locale(Fablab.moment_locale).humanize();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the formatted localized amount for the given price (eg. 20.5 => "20,50 €")
|
||||
*/
|
||||
static price = (price: number): string => {
|
||||
return new Intl.NumberFormat(Fablab.intl_locale, { style: 'currency', currency: Fablab.intl_currency }).format(price);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
43
app/frontend/src/javascript/lib/gtm.js
Normal file
43
app/frontend/src/javascript/lib/gtm.js
Normal file
@ -0,0 +1,43 @@
|
||||
// this script loads the google tag manager, used by Google Analytics V4
|
||||
(function () {
|
||||
const GTM = {};
|
||||
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag () { window.dataLayer.push(arguments); }
|
||||
|
||||
GTM.enableAnalytics = function (trackingId) {
|
||||
gtag('js', new Date());
|
||||
gtag('config', trackingId);
|
||||
|
||||
const node = document.createElement('script');
|
||||
const firstScript = document.getElementsByTagName('script')[0];
|
||||
node.async = true;
|
||||
node.src = `//www.googletagmanager.com/gtag/js?id=${trackingId}`;
|
||||
firstScript.parentNode.insertBefore(node, firstScript);
|
||||
};
|
||||
|
||||
GTM.trackPage = function (url, title) {
|
||||
gtag('event', 'page_view', {
|
||||
page_location: url,
|
||||
page_title: title
|
||||
});
|
||||
};
|
||||
|
||||
GTM.trackLogin = function () {
|
||||
gtag('event', 'login');
|
||||
};
|
||||
|
||||
GTM.trackPurchase = function (transactionId, value) {
|
||||
gtag('event', 'purchase', {
|
||||
transaction_id: transactionId,
|
||||
value,
|
||||
currency: Fablab.intl_currency
|
||||
});
|
||||
};
|
||||
|
||||
this.GTM = GTM;
|
||||
|
||||
if (typeof module !== 'undefined' && module !== null) {
|
||||
module.exports = GTM;
|
||||
}
|
||||
}).call(this);
|
@ -1,23 +1,21 @@
|
||||
(function () {
|
||||
var Humanize, isArray, isFinite, isNaN, objectRef, timeFormats, toString;
|
||||
const objectRef = new function () {}();
|
||||
|
||||
objectRef = new function () {}();
|
||||
const toString = objectRef.toString;
|
||||
|
||||
toString = objectRef.toString;
|
||||
|
||||
isNaN = function (value) {
|
||||
const isNaN = function (value) {
|
||||
return Number.isNaN(value);
|
||||
};
|
||||
|
||||
isFinite = function (value) {
|
||||
const isFinite = function (value) {
|
||||
return ((typeof window !== 'undefined' && window !== null ? window.isFinite : undefined) || global.isFinite)(value) && !isNaN(parseFloat(value));
|
||||
};
|
||||
|
||||
isArray = function (value) {
|
||||
const isArray = function (value) {
|
||||
return toString.call(value) === '[object Array]';
|
||||
};
|
||||
|
||||
timeFormats = [
|
||||
const timeFormats = [
|
||||
{
|
||||
name: 'second',
|
||||
value: 1e3
|
||||
@ -36,7 +34,7 @@
|
||||
}
|
||||
];
|
||||
|
||||
Humanize = {};
|
||||
const Humanize = {};
|
||||
|
||||
Humanize.intword = function (number, charWidth, decimals) {
|
||||
if (decimals == null) {
|
||||
@ -51,18 +49,18 @@
|
||||
};
|
||||
|
||||
Humanize.compactInteger = function (input, decimals) {
|
||||
var bigNumPrefixes, decimalIndex, decimalPart, decimalPartArray, length, number, numberLength, numberLengths, output, outputNumber, signString, unsignedNumber, unsignedNumberCharacterArray, unsignedNumberString, wholePart, wholePartArray, _i, _len, _length;
|
||||
let decimalPart, length, output, outputNumber, unsignedNumberString, _i, _len, _length;
|
||||
if (decimals == null) {
|
||||
decimals = 0;
|
||||
}
|
||||
decimals = Math.max(decimals, 0);
|
||||
number = parseInt(input, 10);
|
||||
signString = number < 0 ? '-' : '';
|
||||
unsignedNumber = Math.abs(number);
|
||||
const number = parseInt(input, 10);
|
||||
const signString = number < 0 ? '-' : '';
|
||||
const unsignedNumber = Math.abs(number);
|
||||
unsignedNumberString = '' + unsignedNumber;
|
||||
numberLength = unsignedNumberString.length;
|
||||
numberLengths = [13, 10, 7, 4];
|
||||
bigNumPrefixes = ['T', 'B', 'M', 'k'];
|
||||
const numberLength = unsignedNumberString.length;
|
||||
const numberLengths = [13, 10, 7, 4];
|
||||
const bigNumPrefixes = ['T', 'B', 'M', 'k'];
|
||||
if (unsignedNumber < 1000) {
|
||||
if (decimals > 0) {
|
||||
unsignedNumberString += '.' + (Array(decimals + 1).join('0'));
|
||||
@ -79,11 +77,11 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
decimalIndex = numberLength - length + 1;
|
||||
unsignedNumberCharacterArray = unsignedNumberString.split('');
|
||||
wholePartArray = unsignedNumberCharacterArray.slice(0, decimalIndex);
|
||||
decimalPartArray = unsignedNumberCharacterArray.slice(decimalIndex, decimalIndex + decimals + 1);
|
||||
wholePart = wholePartArray.join('');
|
||||
const decimalIndex = numberLength - length + 1;
|
||||
const unsignedNumberCharacterArray = unsignedNumberString.split('');
|
||||
const wholePartArray = unsignedNumberCharacterArray.slice(0, decimalIndex);
|
||||
const decimalPartArray = unsignedNumberCharacterArray.slice(decimalIndex, decimalIndex + decimals + 1);
|
||||
const wholePart = wholePartArray.join('');
|
||||
decimalPart = decimalPartArray.join('');
|
||||
if (decimalPart.length < decimals) {
|
||||
decimalPart += '' + (Array(decimals - decimalPart.length + 1).join('0'));
|
||||
@ -105,7 +103,7 @@
|
||||
};
|
||||
|
||||
Humanize.filesize = Humanize.fileSize = function (filesize) {
|
||||
var sizeStr;
|
||||
let sizeStr;
|
||||
if (filesize >= 1073741824) {
|
||||
sizeStr = Humanize.formatNumber(filesize / 1073741824, 2, '') + ' GB';
|
||||
} else if (filesize >= 1048576) {
|
||||
@ -119,7 +117,6 @@
|
||||
};
|
||||
|
||||
Humanize.formatNumber = function (number, precision, thousand, decimal) {
|
||||
var base; var commas; var decimals; var firstComma; var mod; var negative; var usePrecision;
|
||||
if (precision == null) {
|
||||
precision = 0;
|
||||
}
|
||||
@ -129,36 +126,35 @@
|
||||
if (decimal == null) {
|
||||
decimal = '.';
|
||||
}
|
||||
firstComma = function (number, thousand, position) {
|
||||
const firstComma = function (number, thousand, position) {
|
||||
if (position) {
|
||||
return number.substr(0, position) + thousand;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
commas = function (number, thousand, position) {
|
||||
const commas = function (number, thousand, position) {
|
||||
return number.substr(position).replace(/(\d{3})(?=\d)/g, '$1' + thousand);
|
||||
};
|
||||
decimals = function (number, decimal, usePrecision) {
|
||||
const decimals = function (number, decimal, usePrecision) {
|
||||
if (usePrecision) {
|
||||
return decimal + Humanize.toFixed(Math.abs(number), usePrecision).split('.')[1];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
usePrecision = Humanize.normalizePrecision(precision);
|
||||
negative = number < 0 ? '-' : '';
|
||||
base = parseInt(Humanize.toFixed(Math.abs(number || 0), usePrecision), 10) + '';
|
||||
mod = base.length > 3 ? base.length % 3 : 0;
|
||||
const usePrecision = Humanize.normalizePrecision(precision);
|
||||
const negative = number < 0 ? '-' : '';
|
||||
const base = parseInt(Humanize.toFixed(Math.abs(number || 0), usePrecision), 10) + '';
|
||||
const mod = base.length > 3 ? base.length % 3 : 0;
|
||||
return negative + firstComma(base, thousand, mod) + commas(base, thousand, mod) + decimals(number, decimal, usePrecision);
|
||||
};
|
||||
|
||||
Humanize.toFixed = function (value, precision) {
|
||||
var power;
|
||||
if (precision == null) {
|
||||
precision = Humanize.normalizePrecision(precision, 0);
|
||||
}
|
||||
power = Math.pow(10, precision);
|
||||
const power = Math.pow(10, precision);
|
||||
return (Math.round(value * power) / power).toFixed(precision);
|
||||
};
|
||||
|
||||
@ -172,16 +168,16 @@
|
||||
};
|
||||
|
||||
Humanize.ordinal = function (value) {
|
||||
var end, leastSignificant, number, specialCase;
|
||||
number = parseInt(value, 10);
|
||||
let end;
|
||||
const number = parseInt(value, 10);
|
||||
if (number === 0) {
|
||||
return value;
|
||||
}
|
||||
specialCase = number % 100;
|
||||
const specialCase = number % 100;
|
||||
if (specialCase === 11 || specialCase === 12 || specialCase === 13) {
|
||||
return '' + number + 'th';
|
||||
}
|
||||
leastSignificant = number % 10;
|
||||
const leastSignificant = number % 10;
|
||||
switch (leastSignificant) {
|
||||
case 1:
|
||||
end = 'st';
|
||||
@ -199,7 +195,7 @@
|
||||
};
|
||||
|
||||
Humanize.times = function (value, overrides) {
|
||||
var number, smallTimes, _ref;
|
||||
let number, smallTimes, _ref;
|
||||
if (overrides == null) {
|
||||
overrides = {};
|
||||
}
|
||||
@ -243,8 +239,8 @@
|
||||
};
|
||||
|
||||
Humanize.truncatewords = Humanize.truncateWords = function (string, length) {
|
||||
var array, i, result;
|
||||
array = string.split(' ');
|
||||
let i, result;
|
||||
const array = string.split(' ');
|
||||
result = '';
|
||||
i = 0;
|
||||
while (i < length) {
|
||||
@ -259,7 +255,7 @@
|
||||
};
|
||||
|
||||
Humanize.truncatenumber = Humanize.boundedNumber = function (num, bound, ending) {
|
||||
var result;
|
||||
let result;
|
||||
if (bound == null) {
|
||||
bound = 100;
|
||||
}
|
||||
@ -276,8 +272,8 @@
|
||||
};
|
||||
|
||||
Humanize.oxford = function (items, limit, limitStr) {
|
||||
var extra, limitIndex, numItems;
|
||||
numItems = items.length;
|
||||
let extra, limitIndex;
|
||||
const numItems = items.length;
|
||||
if (numItems < 2) {
|
||||
return '' + items;
|
||||
} else if (numItems === 2) {
|
||||
@ -296,7 +292,7 @@
|
||||
};
|
||||
|
||||
Humanize.dictionary = function (object, joiner, separator) {
|
||||
var defs, key, result, val;
|
||||
let defs, key, result, val;
|
||||
if (joiner == null) {
|
||||
joiner = ' is ';
|
||||
}
|
||||
@ -316,12 +312,12 @@
|
||||
};
|
||||
|
||||
Humanize.frequency = function (list, verb) {
|
||||
var len, str, times;
|
||||
let str;
|
||||
if (!isArray(list)) {
|
||||
return;
|
||||
}
|
||||
len = list.length;
|
||||
times = Humanize.times(len);
|
||||
const len = list.length;
|
||||
const times = Humanize.times(len);
|
||||
if (len === 0) {
|
||||
str = '' + times + ' ' + verb;
|
||||
} else {
|
||||
@ -331,7 +327,7 @@
|
||||
};
|
||||
|
||||
Humanize.pace = function (value, intervalMs, unit) {
|
||||
var f, prefix, rate, relativePace, roundedPace, timeUnit, _i, _len;
|
||||
let f, prefix, relativePace, timeUnit, _i, _len;
|
||||
if (unit == null) {
|
||||
unit = 'time';
|
||||
}
|
||||
@ -340,7 +336,7 @@
|
||||
}
|
||||
prefix = 'Approximately';
|
||||
timeUnit = null;
|
||||
rate = value / intervalMs;
|
||||
const rate = value / intervalMs;
|
||||
for (_i = 0, _len = timeFormats.length; _i < _len; _i++) {
|
||||
f = timeFormats[_i];
|
||||
relativePace = rate * f.value;
|
||||
@ -354,7 +350,7 @@
|
||||
relativePace = 1;
|
||||
timeUnit = timeFormats[timeFormats.length - 1].name;
|
||||
}
|
||||
roundedPace = Math.round(relativePace);
|
||||
const roundedPace = Math.round(relativePace);
|
||||
unit = Humanize.pluralize(roundedPace, unit);
|
||||
return '' + prefix + ' ' + roundedPace + ' ' + unit + ' per ' + timeUnit;
|
||||
};
|
||||
@ -387,21 +383,20 @@
|
||||
};
|
||||
|
||||
Humanize.titlecase = Humanize.titleCase = function (string) {
|
||||
var doTitleCase; var internalCaps; var smallWords; var splitOnHyphensRegex; var splitOnWhiteSpaceRegex;
|
||||
smallWords = /\b(a|an|and|at|but|by|de|en|for|if|in|of|on|or|the|to|via|vs?\.?)\b/i;
|
||||
internalCaps = /\S+[A-Z]+\S*/;
|
||||
splitOnWhiteSpaceRegex = /\s+/;
|
||||
splitOnHyphensRegex = /-/;
|
||||
doTitleCase = function (_string, hyphenated, firstOrLast) {
|
||||
var index, stringArray, titleCasedArray, word, _i, _len;
|
||||
const smallWords = /\b(a|an|and|at|but|by|de|en|for|if|in|of|on|or|the|to|via|vs?\.?)\b/i;
|
||||
const internalCaps = /\S+[A-Z]+\S*/;
|
||||
const splitOnWhiteSpaceRegex = /\s+/;
|
||||
const splitOnHyphensRegex = /-/;
|
||||
const doTitleCase = function (_string, hyphenated, firstOrLast) {
|
||||
let index, word, _i, _len;
|
||||
if (hyphenated == null) {
|
||||
hyphenated = false;
|
||||
}
|
||||
if (firstOrLast == null) {
|
||||
firstOrLast = true;
|
||||
}
|
||||
titleCasedArray = [];
|
||||
stringArray = _string.split(hyphenated ? splitOnHyphensRegex : splitOnWhiteSpaceRegex);
|
||||
const titleCasedArray = [];
|
||||
const stringArray = _string.split(hyphenated ? splitOnHyphensRegex : splitOnWhiteSpaceRegex);
|
||||
for (index = _i = 0, _len = stringArray.length; _i < _len; index = ++_i) {
|
||||
word = stringArray[index];
|
||||
if (word.indexOf('-') !== -1) {
|
||||
|
@ -7,13 +7,13 @@ if (typeof Object.assign !== 'function') {
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
var to = Object(target);
|
||||
const to = Object(target);
|
||||
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
var nextSource = arguments[index];
|
||||
for (let index = 1; index < arguments.length; index++) {
|
||||
const nextSource = arguments[index];
|
||||
|
||||
if (nextSource != null) { // Skip over if undefined or null
|
||||
for (var nextKey in nextSource) {
|
||||
for (const nextKey in nextSource) {
|
||||
// Avoid bugs when hasOwnProperty is shadowed
|
||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
|
@ -18,5 +18,5 @@ export default class UserLib {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -16,5 +16,5 @@ export default class WalletLib {
|
||||
} else {
|
||||
return price - this.wallet.amount;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
6
app/frontend/src/javascript/models/gtm.ts
Normal file
6
app/frontend/src/javascript/models/gtm.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export interface GoogleTagManager {
|
||||
enableAnalytics: (trackingId: string) => void,
|
||||
trackPage: (url: string, title: string) => void,
|
||||
trackLogin: () => void,
|
||||
trackPurchase: (transactionId: number, value: number) => void,
|
||||
}
|
@ -1,14 +1,3 @@
|
||||
/* eslint-disable
|
||||
no-return-assign,
|
||||
no-undef,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
angular.module('application.router', ['ui.router'])
|
||||
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
|
||||
$locationProvider.hashPrefix('!');
|
||||
@ -243,7 +232,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
memberPromise: ['$stateParams', 'Member', function ($stateParams, Member) { return Member.get({ id: $stateParams.id }).$promise; }]
|
||||
memberPromise: ['$transition$', 'Member', function ($transition$, Member) { return Member.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.members', {
|
||||
@ -297,7 +286,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
projectPromise: ['$stateParams', 'Project', function ($stateParams, Project) { return Project.get({ id: $stateParams.id }).$promise; }],
|
||||
projectPromise: ['$transition$', 'Project', function ($transition$, Project) { return Project.get({ id: $transition$.params().id }).$promise; }],
|
||||
shortnamePromise: ['Setting', function (Setting) { return Setting.get({ name: 'disqus_shortname' }).$promise; }]
|
||||
}
|
||||
})
|
||||
@ -310,7 +299,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
projectPromise: ['$stateParams', 'Project', function ($stateParams, Project) { return Project.get({ id: $stateParams.id }).$promise; }],
|
||||
projectPromise: ['$transition$', 'Project', function ($transition$, Project) { return Project.get({ id: $transition$.params().id }).$promise; }],
|
||||
allowedExtensions: ['Setting', function (Setting) { return Setting.get({ name: 'allowed_cad_extensions' }).$promise; }]
|
||||
}
|
||||
})
|
||||
@ -347,7 +336,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise; }]
|
||||
machinePromise: ['Machine', '$transition$', function (Machine, $transition$) { return Machine.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.machines_reserve', {
|
||||
@ -361,7 +350,7 @@ angular.module('application.router', ['ui.router'])
|
||||
resolve: {
|
||||
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise; }],
|
||||
machinePromise: ['Machine', '$transition$', function (Machine, $transition$) { return Machine.get({ id: $transition$.params().id }).$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) {
|
||||
return Setting.query({
|
||||
names: "['machine_explications_alert', 'booking_window_start', 'booking_window_end', 'booking_move_enable', " +
|
||||
@ -380,7 +369,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
machinePromise: ['Machine', '$stateParams', function (Machine, $stateParams) { return Machine.get({ id: $stateParams.id }).$promise; }]
|
||||
machinePromise: ['Machine', '$transition$', function (Machine, $transition$) { return Machine.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -419,7 +408,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise; }]
|
||||
spacePromise: ['Space', '$transition$', function (Space, $transition$) { return Space.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.space_edit', {
|
||||
@ -432,7 +421,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise; }]
|
||||
spacePromise: ['Space', '$transition$', function (Space, $transition$) { return Space.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.space_reserve', {
|
||||
@ -445,7 +434,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
spacePromise: ['Space', '$stateParams', function (Space, $stateParams) { return Space.get({ id: $stateParams.id }).$promise; }],
|
||||
spacePromise: ['Space', '$transition$', function (Space, $transition$) { return Space.get({ id: $transition$.params().id }).$promise; }],
|
||||
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) {
|
||||
@ -482,7 +471,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
trainingPromise: ['Training', '$stateParams', function (Training, $stateParams) { return Training.get({ id: $stateParams.id }).$promise; }]
|
||||
trainingPromise: ['Training', '$transition$', function (Training, $transition$) { return Training.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.logged.trainings_reserve', {
|
||||
@ -498,8 +487,8 @@ angular.module('application.router', ['ui.router'])
|
||||
explicationAlertPromise: ['Setting', function (Setting) { return Setting.get({ name: 'training_explications_alert' }).$promise; }],
|
||||
plansPromise: ['Plan', function (Plan) { return Plan.query().$promise; }],
|
||||
groupsPromise: ['Group', function (Group) { return Group.query().$promise; }],
|
||||
trainingPromise: ['Training', '$stateParams', function (Training, $stateParams) {
|
||||
if ($stateParams.id !== 'all') { return Training.get({ id: $stateParams.id }).$promise; }
|
||||
trainingPromise: ['Training', '$transition$', function (Training, $transition$) {
|
||||
if ($transition$.params().id !== 'all') { return Training.get({ id: $transition$.params().id }).$promise; }
|
||||
}],
|
||||
settingsPromise: ['Setting', function (Setting) {
|
||||
return Setting.query({
|
||||
@ -563,7 +552,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise; }],
|
||||
eventPromise: ['Event', '$transition$', function (Event, $transition$) { return Event.get({ id: $transition$.params().id }).$promise; }],
|
||||
priceCategoriesPromise: ['PriceCategory', function (PriceCategory) { return PriceCategory.query().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['booking_move_enable', 'booking_move_delay', 'booking_cancel_enable', 'booking_cancel_delay', 'event_explications_alert', 'online_payment_module']" }).$promise; }]
|
||||
}
|
||||
@ -694,7 +683,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
trainingPromise: ['Training', '$stateParams', function (Training, $stateParams) { return Training.get({ id: $stateParams.id }).$promise; }],
|
||||
trainingPromise: ['Training', '$transition$', function (Training, $transition$) { return Training.get({ id: $transition$.params().id }).$promise; }],
|
||||
machinesPromise: ['Machine', function (Machine) { return Machine.query().$promise; }]
|
||||
}
|
||||
})
|
||||
@ -740,7 +729,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise; }],
|
||||
eventPromise: ['Event', '$transition$', function (Event, $transition$) { return Event.get({ id: $transition$.params().id }).$promise; }],
|
||||
categoriesPromise: ['Category', function (Category) { return Category.query().$promise; }],
|
||||
themesPromise: ['EventTheme', function (EventTheme) { return EventTheme.query().$promise; }],
|
||||
ageRangesPromise: ['AgeRange', function (AgeRange) { return AgeRange.query().$promise; }],
|
||||
@ -756,8 +745,8 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
eventPromise: ['Event', '$stateParams', function (Event, $stateParams) { return Event.get({ id: $stateParams.id }).$promise; }],
|
||||
reservationsPromise: ['Reservation', '$stateParams', function (Reservation, $stateParams) { return Reservation.query({ reservable_id: $stateParams.id, reservable_type: 'Event' }).$promise; }]
|
||||
eventPromise: ['Event', '$transition$', function (Event, $transition$) { return Event.get({ id: $transition$.params().id }).$promise; }],
|
||||
reservationsPromise: ['Reservation', '$transition$', function (Reservation, $transition$) { return Reservation.query({ reservable_id: $transition$.params().id, reservable_type: 'Event' }).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -820,7 +809,7 @@ angular.module('application.router', ['ui.router'])
|
||||
spaces: ['Space', function (Space) { return Space.query().$promise; }],
|
||||
machines: ['Machine', function (Machine) { return Machine.query().$promise; }],
|
||||
plans: ['Plan', function (Plan) { return Plan.query().$promise; }],
|
||||
planPromise: ['Plan', '$stateParams', function (Plan, $stateParams) { return Plan.get({ id: $stateParams.id }).$promise; }],
|
||||
planPromise: ['Plan', '$transition$', function (Plan, $transition$) { return Plan.get({ id: $transition$.params().id }).$promise; }],
|
||||
planCategories: ['PlanCategory', function (PlanCategory) { return PlanCategory.query().$promise; }]
|
||||
}
|
||||
})
|
||||
@ -854,7 +843,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
couponPromise: ['Coupon', '$stateParams', function (Coupon, $stateParams) { return Coupon.get({ id: $stateParams.id }).$promise; }]
|
||||
couponPromise: ['Coupon', '$transition$', function (Coupon, $transition$) { return Coupon.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
|
||||
@ -879,7 +868,8 @@ angular.module('application.router', ['ui.router'])
|
||||
"'accounting_Machine_code', 'accounting_Machine_label', 'accounting_Training_code', 'accounting_Training_label', " +
|
||||
"'accounting_Event_code', 'accounting_Event_label', 'accounting_Space_code', 'accounting_Space_label', " +
|
||||
"'payment_gateway', 'accounting_Error_code', 'accounting_Error_label', 'payment_schedule_prefix', " +
|
||||
"'feature_tour_display', 'online_payment_module', 'stripe_public_key', 'stripe_currency', 'invoice_prefix']"
|
||||
"'feature_tour_display', 'online_payment_module', 'stripe_public_key', 'stripe_currency', 'invoice_prefix', " +
|
||||
"'accounting_Pack_code', 'accounting_Pack_label']"
|
||||
}).$promise;
|
||||
}],
|
||||
stripeSecretKey: ['Setting', function (Setting) { return Setting.isPresent({ name: 'stripe_secret_key' }).$promise; }],
|
||||
@ -958,7 +948,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
importItem: ['Import', '$stateParams', function (Import, $stateParams) { return Import.get({ id: $stateParams.id }).$promise; }]
|
||||
importItem: ['Import', '$transition$', function (Import, $transition$) { return Import.get({ id: $transition$.params().id }).$promise; }]
|
||||
}
|
||||
})
|
||||
.state('app.admin.members_edit', {
|
||||
@ -970,9 +960,9 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
memberPromise: ['Member', '$stateParams', function (Member, $stateParams) { return Member.get({ id: $stateParams.id }).$promise; }],
|
||||
memberPromise: ['Member', '$transition$', function (Member, $transition$) { return Member.get({ id: $transition$.params().id }).$promise; }],
|
||||
activeProviderPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.active().$promise; }],
|
||||
walletPromise: ['Wallet', '$stateParams', function (Wallet, $stateParams) { return Wallet.getWalletByUser({ user_id: $stateParams.id }).$promise; }],
|
||||
walletPromise: ['Wallet', '$transition$', function (Wallet, $transition$) { return Wallet.getWalletByUser({ user_id: $transition$.params().id }).$promise; }],
|
||||
transactionsPromise: ['Wallet', 'walletPromise', function (Wallet, walletPromise) { return Wallet.transactions({ id: walletPromise.id }).$promise; }],
|
||||
tagsPromise: ['Tag', function (Tag) { return Tag.query().$promise; }],
|
||||
settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['phone_required', 'address_required']" }).$promise; }]
|
||||
@ -1027,7 +1017,7 @@ angular.module('application.router', ['ui.router'])
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
providerPromise: ['AuthProvider', '$stateParams', function (AuthProvider, $stateParams) { return AuthProvider.get({ id: $stateParams.id }).$promise; }],
|
||||
providerPromise: ['AuthProvider', '$transition$', function (AuthProvider, $transition$) { return AuthProvider.get({ id: $transition$.params().id }).$promise; }],
|
||||
mappingFieldsPromise: ['AuthProvider', function (AuthProvider) { return AuthProvider.mapping_fields().$promise; }]
|
||||
}
|
||||
})
|
||||
@ -1083,7 +1073,7 @@ angular.module('application.router', ['ui.router'])
|
||||
"'display_name_enable', 'machines_sort_by', 'fab_analytics', 'statistics_module', 'address_required', " +
|
||||
"'link_name', 'home_content', 'home_css', 'phone_required', 'upcoming_events_shown', 'public_agenda_module'," +
|
||||
"'renew_pack_threshold', 'pack_only_for_subscription', 'overlapping_categories', 'public_registrations'," +
|
||||
"'extended_prices_in_same_day']"
|
||||
"'extended_prices_in_same_day', 'recaptcha_site_key', 'recaptcha_secret_key']"
|
||||
}).$promise;
|
||||
}],
|
||||
privacyDraftsPromise: ['Setting', function (Setting) { return Setting.get({ name: 'privacy_draft', history: true }).$promise; }],
|
||||
|
@ -14,7 +14,7 @@ Application.Services.service('Diacritics', [
|
||||
* @returns {string} without diacritics
|
||||
*/
|
||||
remove: function (str) {
|
||||
var defaultDiacriticsRemovalap = [
|
||||
const defaultDiacriticsRemovalap = [
|
||||
{ base: 'A', letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F' },
|
||||
{ base: 'AA', letters: '\uA732' },
|
||||
{ base: 'AE', letters: '\u00C6\u01FC\u01E2' },
|
||||
@ -103,10 +103,10 @@ Application.Services.service('Diacritics', [
|
||||
{ base: 'z', letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' }
|
||||
];
|
||||
|
||||
var diacriticsMap = {};
|
||||
for (var i = 0; i < defaultDiacriticsRemovalap.length; i++) {
|
||||
var letters = defaultDiacriticsRemovalap[i].letters.split('');
|
||||
for (var j = 0; j < letters.length; j++) {
|
||||
const diacriticsMap = {};
|
||||
for (let i = 0; i < defaultDiacriticsRemovalap.length; i++) {
|
||||
const letters = defaultDiacriticsRemovalap[i].letters.split('');
|
||||
for (let j = 0; j < letters.length; j++) {
|
||||
diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use "sass:math";
|
||||
|
||||
// This is the default html and body font-size for the base rem value.
|
||||
$rem-base: 10px !default;
|
||||
|
||||
@ -20,12 +22,12 @@ $modules: () !default;
|
||||
// STRIP UNIT
|
||||
// It strips the unit of measure and returns it
|
||||
@function strip-unit($num) {
|
||||
@return $num / ($num * 0 + 1);
|
||||
@return math.div($num, $num * 0 + 1);
|
||||
}
|
||||
|
||||
// CONVERT TO REM
|
||||
@function convert-to-rem($value, $base-value: $rem-base) {
|
||||
$value: strip-unit($value) / strip-unit($base-value) * 1rem;
|
||||
$value: math.div(strip-unit($value), strip-unit($base-value)) * 1rem;
|
||||
|
||||
@if $value == 0rem {
|
||||
$value: 0;
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use 'sass:math';
|
||||
|
||||
/*layout*/
|
||||
.header,
|
||||
.footer {
|
||||
@ -286,8 +288,8 @@ body.container {
|
||||
height: $header-md-height;
|
||||
|
||||
.navbar-form {
|
||||
margin-top: floor(($header-md-height - 30) / 2);
|
||||
margin-bottom: floor(($header-md-height - 30) / 2);
|
||||
margin-top: floor(math.div($header-md-height - 30, 2));
|
||||
margin-bottom: floor(math.div($header-md-height - 30, 2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -689,7 +691,7 @@ body.container {
|
||||
cursor: pointer;
|
||||
& .Event-picture {opacity: 0.7;}
|
||||
}
|
||||
|
||||
|
||||
&-picture {
|
||||
height: 250px;
|
||||
background-color: #fff;
|
||||
@ -701,7 +703,7 @@ body.container {
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&-desc {
|
||||
position: relative;
|
||||
padding: 15px;
|
||||
|
@ -1,3 +1,5 @@
|
||||
@use 'sass:math';
|
||||
|
||||
/*primary nav*/
|
||||
.navbar-header {
|
||||
position: relative;
|
||||
@ -42,7 +44,7 @@
|
||||
.nav-primary {
|
||||
li {
|
||||
> a > i {
|
||||
margin: floor(-($nav-primary-height - $line-height-computed) / 2) -10px;
|
||||
margin: floor(math.div(-($nav-primary-height - $line-height-computed), 2)) -10px;
|
||||
line-height: $nav-primary-height;
|
||||
width: $nav-primary-height;
|
||||
float: left;
|
||||
@ -61,7 +63,7 @@
|
||||
ul.nav {
|
||||
> li {
|
||||
> a {
|
||||
padding: floor(($nav-primary-height - $line-height-computed) / 2) 15px;
|
||||
padding: floor(math.div($nav-primary-height - $line-height-computed, 2)) 15px;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
|
||||
@ -245,7 +247,7 @@
|
||||
|
||||
> .vbox > .header,
|
||||
> .vbox > .footer {
|
||||
padding: 0 floor(($nav-xs-width - 30px) / 2);
|
||||
padding: 0 floor(math.div($nav-xs-width - 30px, 2));
|
||||
}
|
||||
|
||||
.hidden-nav-xs {
|
||||
@ -309,7 +311,7 @@
|
||||
> li {
|
||||
> a {
|
||||
.header-md & {
|
||||
padding: floor(($header-md-height - $line-height-computed) / 2 - 1);
|
||||
padding: floor(math.div($header-md-height - $line-height-computed, 2) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -326,7 +328,7 @@
|
||||
// + *{
|
||||
// padding-top: 50px !important;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
.nav-bar-fixed-bottom {
|
||||
@ -518,7 +520,7 @@
|
||||
border-left: 3px solid;
|
||||
|
||||
// #870003;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,3 @@
|
||||
@import "~fullcalendar/dist/fullcalendar.print";
|
||||
@media print {
|
||||
@import "~fullcalendar/dist/fullcalendar.print";
|
||||
}
|
||||
|
@ -1,25 +1,28 @@
|
||||
.cookies-consent {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 3rem;
|
||||
left: 3rem;
|
||||
width: 40rem;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #f5f5f5;
|
||||
padding: 3rem;
|
||||
flex-direction: column;
|
||||
z-index: 100;
|
||||
-webkit-box-shadow: 0 4px 10px 2px rgba(224, 224, 224, 0.43);
|
||||
-moz-box-shadow: 0 4px 10px 2px rgba(224, 224, 224, 0.43);
|
||||
box-shadow: 0 4px 10px 2px rgba(224, 224, 224, 0.43);
|
||||
-webkit-box-shadow: 0 4px 10px 2px rgba(0, 0, 0, 0.25);
|
||||
-moz-box-shadow: 0 4px 10px 2px rgba(0, 0, 0, 0.25);
|
||||
box-shadow: 0 4px 10px 2px rgba(0, 0, 0, 0.25);
|
||||
|
||||
.cookies-actions {
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
height: 45px;
|
||||
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
|
||||
button {
|
||||
flex-basis: 50%;
|
||||
@extend .fab-button;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
button.decline {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
@ -31,4 +34,10 @@
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 480px) {
|
||||
bottom: 3rem;
|
||||
left: 3rem;
|
||||
width: 40rem;
|
||||
}
|
||||
}
|
||||
|
@ -90,4 +90,15 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': providerForm['auth_provider[scopes]'].$dirty && providerForm['auth_provider[scopes]'].$invalid}">
|
||||
<label for="provider_client_secret" class="col-sm-3 control-label" translate>{{ 'app.shared.oauth2.scopes' }}</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text"
|
||||
ng-model="provider.providable_attributes.scopes"
|
||||
class="form-control"
|
||||
name="auth_provider[scopes]"
|
||||
id="provider_scopes"
|
||||
placeholder="profile,email...">
|
||||
</div>
|
||||
</div>
|
||||
<ng-include src="'/admin/authentications/_oauth2_mapping.html'"></ng-include>
|
||||
|
@ -106,6 +106,16 @@
|
||||
<input type="text" id="spaceLabel" ng-model="settings.spaceLabel.value" class="form-control" placeholder="{{ 'app.admin.invoices.general_space_label' | translate }}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label for="packCode" translate>{{ 'app.admin.invoices.accounting_Pack_code' }}</label>
|
||||
<input type="text" id="packCode" ng-model="settings.packCode.value" class="form-control" placeholder="{{ 'app.admin.invoices.general_pack_code' | translate }}"/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="packLabel" translate>{{ 'app.admin.invoices.accounting_Pack_label' }}</label>
|
||||
<input type="text" id="packLabel" ng-model="settings.packLabel.value" class="form-control" placeholder="{{ 'app.admin.invoices.general_pack_label' | translate }}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<label for="spaceCode" translate>{{ 'app.admin.invoices.accounting_Error_code' }}</label>
|
||||
|
@ -42,7 +42,7 @@
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-addon"><i class="fa fa-search"></i></div>
|
||||
<input type="search" class="form-control" placeholder="Mots-clés" ng-model="search.q"/>
|
||||
<input type="search" class="form-control" placeholder="{{ 'app.public.projects_list.keywords' | translate }}" ng-model="search.q"/>
|
||||
<div class="input-group-btn">
|
||||
<button type="submit" class="btn btn-warning" translate>{{ 'app.public.projects_list.search' }}</button>
|
||||
</div>
|
||||
|
@ -19,6 +19,8 @@ class AccountingPeriod < ApplicationRecord
|
||||
validates_with PeriodOverlapValidator
|
||||
validates_with PeriodIntegrityValidator
|
||||
|
||||
belongs_to :user, class_name: 'User', foreign_key: 'closed_by'
|
||||
|
||||
def delete
|
||||
false
|
||||
end
|
||||
@ -79,13 +81,15 @@ class AccountingPeriod < ApplicationRecord
|
||||
end
|
||||
|
||||
def compute_totals
|
||||
period_invoices = invoices_with_vat(invoices.where(type: nil))
|
||||
period_avoirs = invoices_with_vat(invoices.where(type: 'Avoir'))
|
||||
period_invoices = invoices_with_vat(invoices.where(type: nil).includes([:invoice_items]))
|
||||
period_avoirs = invoices_with_vat(invoices.where(type: 'Avoir').includes([:invoice_items]))
|
||||
self.period_total = (period_invoices.map(&method(:price_without_taxe)).reduce(:+) || 0) -
|
||||
(period_avoirs.map(&method(:price_without_taxe)).reduce(:+) || 0)
|
||||
|
||||
all_invoices = invoices_with_vat(Invoice.where('CAST(created_at AS DATE) <= :end_date AND type IS NULL', end_date: end_at))
|
||||
all_avoirs = invoices_with_vat(Invoice.where("CAST(created_at AS DATE) <= :end_date AND type = 'Avoir'", end_date: end_at))
|
||||
all_invoices = invoices_with_vat(Invoice.where('CAST(created_at AS DATE) <= :end_date AND type IS NULL', end_date: end_at)
|
||||
.includes([:invoice_items]))
|
||||
all_avoirs = invoices_with_vat(Invoice.where("CAST(created_at AS DATE) <= :end_date AND type = 'Avoir'", end_date: end_at)
|
||||
.includes([:invoice_items]))
|
||||
self.perpetual_total = (all_invoices.map(&method(:price_without_taxe)).reduce(:+) || 0) -
|
||||
(all_avoirs.map(&method(:price_without_taxe)).reduce(:+) || 0)
|
||||
self.footprint = compute_footprint
|
||||
|
@ -8,11 +8,6 @@ class InvoiceItem < Footprintable
|
||||
has_one :payment_gateway_object, as: :item
|
||||
|
||||
belongs_to :object, polymorphic: true
|
||||
belongs_to :reservation, foreign_type: 'Reservation', foreign_key: 'object_id'
|
||||
belongs_to :subscription, foreign_type: 'Subscription', foreign_key: 'object_id'
|
||||
belongs_to :wallet_transaction, foreign_type: 'WalletTransaction', foreign_key: 'object_id'
|
||||
belongs_to :offer_day, foreign_type: 'OfferDay', foreign_key: 'object_id'
|
||||
belongs_to :statistic_profile_prepaid_pack, foreign_type: 'StatisticProfilePrepaidPack', foreign_key: 'object_id'
|
||||
|
||||
after_create :chain_record
|
||||
after_update :log_changes
|
||||
|
@ -1,4 +0,0 @@
|
||||
class OpenAPI::CallsCountTracing < ApplicationRecord
|
||||
belongs_to :projets, foreign_key: :open_api_client_id
|
||||
validates :projets, :at, presence: true
|
||||
end
|
@ -2,8 +2,6 @@
|
||||
|
||||
# OpenAPI::Client keeps track of the authorized accesses to the 3-rd party API (aka. OpenAPI)
|
||||
class OpenAPI::Client < ApplicationRecord
|
||||
has_many :calls_count_tracings, foreign_key: :open_api_client_id, dependent: :destroy
|
||||
|
||||
validates :name, presence: true
|
||||
validates_uniqueness_of :token
|
||||
|
||||
|
@ -128,7 +128,9 @@ class Setting < ApplicationRecord
|
||||
pack_only_for_subscription
|
||||
overlapping_categories
|
||||
extended_prices_in_same_day
|
||||
public_registrations] }
|
||||
public_registrations
|
||||
accounting_Pack_code
|
||||
accounting_Pack_label] }
|
||||
# WARNING: when adding a new key, you may also want to add it in:
|
||||
# - config/locales/en.yml#settings
|
||||
# - app/frontend/src/javascript/models/setting.ts#SettingName
|
||||
@ -195,4 +197,11 @@ class Setting < ApplicationRecord
|
||||
setting = find_or_initialize_by(name: name)
|
||||
setting.save && setting.history_values.create(invoicing_profile: user.invoicing_profile, value: value.to_s)
|
||||
end
|
||||
|
||||
##
|
||||
# Check if the given setting was set
|
||||
##
|
||||
def self.set?(name)
|
||||
find_by(name: name)&.value.nil? ? false : true
|
||||
end
|
||||
end
|
||||
|
@ -49,6 +49,8 @@ class User < ApplicationRecord
|
||||
|
||||
has_one :payment_gateway_object, as: :item
|
||||
|
||||
has_many :accounting_periods, foreign_key: 'closed_by', dependent: :nullify
|
||||
|
||||
# fix for create admin user
|
||||
before_save do
|
||||
email&.downcase!
|
||||
|
@ -25,9 +25,9 @@ class PDF::Invoice < Prawn::Document
|
||||
)
|
||||
|
||||
# logo
|
||||
img_b64 = Setting.find_by(name: 'invoice_logo')
|
||||
img_b64 = Setting.get('invoice_logo')
|
||||
begin
|
||||
image StringIO.new(Base64.decode64(img_b64.value)), fit: [415, 40]
|
||||
image StringIO.new(Base64.decode64(img_b64)), fit: [415, 40]
|
||||
rescue StandardError => e
|
||||
puts "Unable to decode invoice logo from base64: #{e}"
|
||||
end
|
||||
@ -97,9 +97,9 @@ class PDF::Invoice < Prawn::Document
|
||||
DATE: I18n.l(invoice.main_item.object.slots[0].start_at.to_date),
|
||||
TIME: I18n.l(invoice.main_item.object.slots[0].start_at, format: :hour_minute))
|
||||
invoice.invoice_items.each do |item|
|
||||
next unless item.subscription
|
||||
next unless item.object_type == Subscription.name
|
||||
|
||||
subscription = item.subscription
|
||||
subscription = item.object
|
||||
cancellation = invoice.is_a?(Avoir) ? I18n.t('invoices.cancellation') + ' - ' : ''
|
||||
object = "\n- #{object}\n- #{cancellation + subscription_verbose(subscription, name)}"
|
||||
break
|
||||
@ -135,7 +135,7 @@ class PDF::Invoice < Prawn::Document
|
||||
details = invoice.is_a?(Avoir) ? I18n.t('invoices.cancellation') + ' - ' : ''
|
||||
|
||||
if item.object_type == Subscription.name
|
||||
subscription = item.subscription
|
||||
subscription = item.object
|
||||
if invoice.main_item.object_type == 'OfferDay'
|
||||
details += I18n.t('invoices.subscription_extended_for_free_from_START_to_END',
|
||||
START: I18n.l(invoice.main_item.object.start_at.to_date),
|
||||
|
@ -28,9 +28,9 @@ class PDF::PaymentSchedule < Prawn::Document
|
||||
)
|
||||
|
||||
# logo
|
||||
img_b64 = Setting.find_by(name: 'invoice_logo')
|
||||
img_b64 = Setting.get('invoice_logo')
|
||||
begin
|
||||
image StringIO.new(Base64.decode64(img_b64.value)), fit: [415, 40]
|
||||
image StringIO.new(Base64.decode64(img_b64)), fit: [415, 40]
|
||||
rescue StandardError => e
|
||||
puts "Unable to decode invoice logo from base64: #{e}"
|
||||
end
|
||||
|
@ -20,6 +20,6 @@ class ProjectPolicy < ApplicationPolicy
|
||||
end
|
||||
|
||||
def destroy?
|
||||
user.admin? or record.author.user_id == user
|
||||
user.admin? or record.author.user_id == user.id
|
||||
end
|
||||
end
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Check the access policies for API::SubscriptionsController
|
||||
class SubscriptionPolicy < ApplicationPolicy
|
||||
def show?
|
||||
user.admin? or record.user_id == user.id
|
||||
user.admin? || user.manager? || record.user.id == user.id
|
||||
end
|
||||
|
||||
def payment_details?
|
||||
|
@ -69,6 +69,8 @@ class AccountingExportService
|
||||
end
|
||||
elsif invoice.main_item.object_type == 'WalletTransaction'
|
||||
rows << "#{wallet_row(invoice)}\n"
|
||||
elsif invoice.main_item.object_type == 'StatisticProfilePrepaidPack'
|
||||
rows << "#{pack_row(invoice)}\n"
|
||||
elsif invoice.main_item.object_type == 'Error'
|
||||
items = invoice.invoice_items.reject { |ii| ii.object_type == 'Subscription' }
|
||||
items.each do |item|
|
||||
@ -131,6 +133,16 @@ class AccountingExportService
|
||||
)
|
||||
end
|
||||
|
||||
def pack_row(invoice)
|
||||
row(
|
||||
invoice,
|
||||
account(invoice, :pack),
|
||||
account(invoice, :pack, type: :label),
|
||||
invoice.invoice_items.first.net_amount / 100.00,
|
||||
line_label: label(invoice)
|
||||
)
|
||||
end
|
||||
|
||||
# Generate the "VAT" row, which contains the credit to the VAT account, with VAT amount only
|
||||
def vat_row(invoice)
|
||||
total = invoice.invoice_items.map(&:net_amount).sum
|
||||
@ -195,29 +207,35 @@ class AccountingExportService
|
||||
def account(invoice, account, type: :code, means: :other)
|
||||
case account
|
||||
when :projets
|
||||
Setting.find_by(name: "accounting_#{means}_client_#{type}")&.value
|
||||
Setting.get("accounting_#{means}_client_#{type}")
|
||||
when :vat
|
||||
Setting.find_by(name: "accounting_VAT_#{type}")&.value
|
||||
Setting.get("accounting_VAT_#{type}")
|
||||
when :subscription
|
||||
if invoice.subscription_invoice?
|
||||
Setting.find_by(name: "accounting_subscription_#{type}")&.value
|
||||
Setting.get("accounting_subscription_#{type}")
|
||||
else
|
||||
puts "WARN: Invoice #{invoice.id} has no subscription"
|
||||
end
|
||||
when :reservation
|
||||
if invoice.main_item.object_type == 'Reservation'
|
||||
Setting.find_by(name: "accounting_#{invoice.main_item.object.reservable_type}_#{type}")&.value
|
||||
Setting.get("accounting_#{invoice.main_item.object.reservable_type}_#{type}")
|
||||
else
|
||||
puts "WARN: Invoice #{invoice.id} has no reservation"
|
||||
end
|
||||
when :wallet
|
||||
if invoice.main_item.object_type == 'WalletTransaction'
|
||||
Setting.find_by(name: "accounting_wallet_#{type}")&.value
|
||||
Setting.get("accounting_wallet_#{type}")
|
||||
else
|
||||
puts "WARN: Invoice #{invoice.id} is not a wallet credit"
|
||||
end
|
||||
when :pack
|
||||
if invoice.main_item.object_type == 'StatisticProfilePrepaidPack'
|
||||
Setting.get("accounting_Pack_#{type}")
|
||||
else
|
||||
puts "WARN: Invoice #{invoice.id} has no prepaid-pack"
|
||||
end
|
||||
when :error
|
||||
Setting.find_by(name: "accounting_Error_#{type}")&.value
|
||||
Setting.get("accounting_Error_#{type}")
|
||||
else
|
||||
puts "Unsupported account #{account}"
|
||||
end || ''
|
||||
|
@ -46,7 +46,7 @@ class Members::MembersService
|
||||
@member.update_statistic_profile
|
||||
@member.generate_subscription_invoice(current_user.id)
|
||||
@member.send_confirmation_instructions
|
||||
UsersMailer.delay.notify_user_account_created(@member, @member.password)
|
||||
UsersMailer.notify_user_account_created(@member, @member.password).deliver_later
|
||||
true
|
||||
else
|
||||
false
|
||||
|
@ -126,13 +126,11 @@ class StatisticService
|
||||
|
||||
def subscriptions_list(options = default_options)
|
||||
result = []
|
||||
InvoiceItem.where('invoice_items.created_at >= :start_date AND invoice_items.created_at <= :end_date', options)
|
||||
.eager_load(invoice: [:coupon], subscription: [:plan, statistic_profile: [:group]]).each do |i|
|
||||
InvoiceItem.where("object_type = '#{Subscription.name}' AND invoice_items.created_at >= :start_date AND invoice_items.created_at <= :end_date", options)
|
||||
.eager_load(invoice: [:coupon]).each do |i|
|
||||
next if i.invoice.is_a?(Avoir)
|
||||
|
||||
sub = i.subscription
|
||||
|
||||
next unless sub
|
||||
sub = i.object
|
||||
|
||||
ca = i.amount.to_i
|
||||
cs = CouponService.new
|
||||
|
@ -46,7 +46,7 @@ class UserService
|
||||
admin.send_confirmation_instructions
|
||||
admin.add_role(:admin)
|
||||
admin.remove_role(:member)
|
||||
UsersMailer.delay.notify_user_account_created(admin, generated_password)
|
||||
UsersMailer.notify_user_account_created(admin, generated_password).deliver_later
|
||||
end
|
||||
{ saved: saved, user: admin }
|
||||
end
|
||||
@ -61,7 +61,7 @@ class UserService
|
||||
manager.send_confirmation_instructions
|
||||
manager.add_role(:manager)
|
||||
manager.remove_role(:member)
|
||||
UsersMailer.delay.notify_user_account_created(manager, generated_password)
|
||||
UsersMailer.notify_user_account_created(manager, generated_password).deliver_later
|
||||
end
|
||||
{ saved: saved, user: manager }
|
||||
end
|
||||
|
@ -4,9 +4,9 @@ json.partial! 'api/auth_providers/auth_provider', auth_provider: @provider
|
||||
|
||||
if @provider.providable_type == OAuth2Provider.name
|
||||
json.providable_attributes do
|
||||
json.extract! @provider.providable, :id, :base_url, :token_endpoint, :authorization_endpoint, :profile_url, :client_id, :client_secret
|
||||
json.extract! @provider.providable, :id, :base_url, :token_endpoint, :authorization_endpoint, :profile_url, :client_id, :client_secret, :scopes
|
||||
json.o_auth2_mappings_attributes @provider.providable.o_auth2_mappings do |m|
|
||||
json.extract! m, :id, :local_model, :local_field, :api_field, :api_endpoint, :api_data_type, :transformation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -67,9 +67,7 @@
|
||||
Fablab.sessionTours = [];
|
||||
</script>
|
||||
|
||||
<%= stylesheet_packs_with_chunks_tag 'application', media: 'all' %>
|
||||
<%= stylesheet_packs_with_chunks_tag 'plugins', media: 'all' %>
|
||||
<%= stylesheet_packs_with_chunks_tag 'printer', media: 'print' %>
|
||||
<%= stylesheet_pack_tag 'application', 'plugins', 'printer' %>
|
||||
<% unless Stylesheet.theme.nil? %>
|
||||
<link rel="stylesheet" media="all" href="<%= stylesheet_path(Stylesheet.theme.id) %>-<%= Stylesheet.theme.updated_at.to_i.to_s %>.css" />
|
||||
<% end %>
|
||||
@ -134,6 +132,6 @@
|
||||
<span class="text-sm">Powered by <a href="http://www.fab-manager.com" target="_blank">Fab-manager</a></span>
|
||||
</div>
|
||||
|
||||
<%= javascript_packs_with_chunks_tag 'application' %>
|
||||
<%= javascript_pack_tag 'application' %>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,10 +0,0 @@
|
||||
class OpenAPITraceCallsCountWorker < Sidekiq::Workers
|
||||
include Sidekiq::Worker
|
||||
sidekiq_options queue: 'default', retry: true
|
||||
|
||||
def perform
|
||||
OpenAPI::Client.find_each do |client|
|
||||
OpenAPI::CallsCountTracing.create!(projets: client, calls_count: client.calls_count, at: DateTime.current)
|
||||
end
|
||||
end
|
||||
end
|
@ -7,7 +7,7 @@ class OpenlabWorker
|
||||
|
||||
def initialize
|
||||
client = Openlab::Client.new(app_secret: Setting.get('openlab_app_secret'))
|
||||
@projets = Openlab::Projects.new(client)
|
||||
@projects = Openlab::Projects.new(client)
|
||||
super
|
||||
end
|
||||
|
||||
@ -17,12 +17,12 @@ class OpenlabWorker
|
||||
case action.to_s
|
||||
when /create/
|
||||
project = Project.find(project_id)
|
||||
response = @projets.create(project.openlab_attributes)
|
||||
response = @projects.create(project.openlab_attributes)
|
||||
when /update/
|
||||
project = Project.find(project_id)
|
||||
response = @projets.update(project_id, project.openlab_attributes)
|
||||
response = @projects.update(project_id, project.openlab_attributes)
|
||||
when /destroy/
|
||||
response = @projets.destroy(project_id)
|
||||
response = @projects.destroy(project_id)
|
||||
else
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
@ -1,3 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Send a reminder email to the user who has made a reservation
|
||||
class ReservationReminderWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
@ -5,25 +8,24 @@ class ReservationReminderWorker
|
||||
DEFAULT_REMINDER_DELAY = 24.hours
|
||||
|
||||
def perform
|
||||
enabled = Setting.find_by(name: 'reminder_enable').try(:value)
|
||||
if enabled == 'true'
|
||||
delay = Setting.find_by(name: 'reminder_delay').try(:value).try(:to_i).try(:hours) || DEFAULT_REMINDER_DELAY
|
||||
return unless Setting.get('reminder_enable')
|
||||
|
||||
starting = DateTime.current.beginning_of_hour + delay
|
||||
ending = starting + 1.hour
|
||||
delay = Setting.find_by(name: 'reminder_delay').try(:value).try(:to_i).try(:hours) || DEFAULT_REMINDER_DELAY
|
||||
|
||||
Reservation.joins(:slots).where('slots.start_at >= ? AND slots.start_at <= ? AND slots.canceled_at IS NULL', starting, ending).each do |r|
|
||||
already_sent = Notification.where(
|
||||
attached_object_type: Reservation.name,
|
||||
attached_object_id: r.id,
|
||||
notification_type_id: NotificationType.find_by_name('notify_member_reservation_reminder')
|
||||
).count
|
||||
unless already_sent > 0
|
||||
NotificationCenter.call type: 'notify_member_reservation_reminder',
|
||||
receiver: r.user,
|
||||
attached_object: r
|
||||
end
|
||||
end
|
||||
starting = DateTime.current.beginning_of_hour + delay
|
||||
ending = starting + 1.hour
|
||||
|
||||
Reservation.joins(:slots).where('slots.start_at >= ? AND slots.start_at <= ? AND slots.canceled_at IS NULL', starting, ending).each do |r|
|
||||
already_sent = Notification.where(
|
||||
attached_object_type: Reservation.name,
|
||||
attached_object_id: r.id,
|
||||
notification_type_id: NotificationType.find_by_name('notify_member_reservation_reminder')
|
||||
).count
|
||||
next if already_sent.positive?
|
||||
|
||||
NotificationCenter.call type: 'notify_member_reservation_reminder',
|
||||
receiver: r.user,
|
||||
attached_object: r
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -4,7 +4,6 @@ module.exports = function (api) {
|
||||
const isDevelopmentEnv = api.env('development');
|
||||
const isProductionEnv = api.env('production');
|
||||
const isTestEnv = api.env('test');
|
||||
const isWebpackDevServer = process.env.WEBPACK_DEV_SERVER;
|
||||
|
||||
if (!validEnv.includes(currentEnv)) {
|
||||
throw new Error(
|
||||
@ -16,39 +15,20 @@ module.exports = function (api) {
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
const defaultConfigFunc = require('shakapacker/package/babel/preset.js');
|
||||
const resultConfig = defaultConfigFunc(api);
|
||||
|
||||
const changesOnDefault = {
|
||||
presets: [
|
||||
isTestEnv && [
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
node: 'current'
|
||||
},
|
||||
modules: 'commonjs'
|
||||
},
|
||||
'@babel/preset-react'
|
||||
],
|
||||
(isProductionEnv || isDevelopmentEnv) && [
|
||||
'@babel/preset-env',
|
||||
{
|
||||
forceAllTransforms: true,
|
||||
useBuiltIns: 'entry',
|
||||
corejs: 3,
|
||||
modules: false,
|
||||
exclude: ['transform-typeof-symbol']
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/preset-react',
|
||||
{
|
||||
development: isDevelopmentEnv || isTestEnv,
|
||||
useBuiltIns: true
|
||||
}
|
||||
],
|
||||
['@babel/preset-typescript', { allExtensions: true, isTSX: true }]
|
||||
]
|
||||
].filter(Boolean),
|
||||
plugins: [
|
||||
isWebpackDevServer && 'react-refresh/babel',
|
||||
'babel-plugin-macros',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
isTestEnv && 'babel-plugin-dynamic-import-node',
|
||||
@ -56,7 +36,7 @@ module.exports = function (api) {
|
||||
[
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
{
|
||||
loose: false
|
||||
loose: true
|
||||
}
|
||||
],
|
||||
[
|
||||
@ -65,26 +45,28 @@ module.exports = function (api) {
|
||||
useBuiltIns: true
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/plugin-transform-runtime',
|
||||
{
|
||||
helpers: false,
|
||||
regenerator: true,
|
||||
corejs: false
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/plugin-transform-regenerator',
|
||||
{
|
||||
async: false
|
||||
}
|
||||
],
|
||||
isProductionEnv && [
|
||||
'babel-plugin-transform-react-remove-prop-types',
|
||||
isProductionEnv && ['babel-plugin-transform-react-remove-prop-types',
|
||||
{
|
||||
removeImport: true
|
||||
}
|
||||
],
|
||||
process.env.WEBPACK_SERVE && [
|
||||
'react-refresh/babel',
|
||||
{
|
||||
exclude: 'node_modules/**'
|
||||
}
|
||||
]
|
||||
].filter(Boolean)
|
||||
};
|
||||
|
||||
resultConfig.presets = [...resultConfig.presets, ...changesOnDefault.presets];
|
||||
resultConfig.plugins = [...resultConfig.plugins, ...changesOnDefault.plugins];
|
||||
|
||||
return resultConfig;
|
||||
};
|
||||
|
15
bin/webpacker
Executable file
15
bin/webpacker
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "pathname"
|
||||
require "bundler/setup"
|
||||
require "webpacker"
|
||||
require "webpacker/webpack_runner"
|
||||
|
||||
ENV["RAILS_ENV"] ||= "development"
|
||||
ENV["NODE_ENV"] ||= ENV["RAILS_ENV"]
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", Pathname.new(__FILE__).realpath)
|
||||
|
||||
APP_ROOT = File.expand_path("..", __dir__)
|
||||
Dir.chdir(APP_ROOT) do
|
||||
Webpacker::WebpackRunner.run(ARGV)
|
||||
end
|
18
bin/webpacker-dev-server
Executable file
18
bin/webpacker-dev-server
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
ENV["RAILS_ENV"] ||= "development"
|
||||
ENV["NODE_ENV"] ||= ENV["RAILS_ENV"]
|
||||
|
||||
require "pathname"
|
||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||
Pathname.new(__FILE__).realpath)
|
||||
|
||||
require "bundler/setup"
|
||||
|
||||
require "webpacker"
|
||||
require "webpacker/dev_server_runner"
|
||||
|
||||
APP_ROOT = File.expand_path("..", __dir__)
|
||||
Dir.chdir(APP_ROOT) do
|
||||
Webpacker::DevServerRunner.run(ARGV)
|
||||
end
|
15
bin/yarn
15
bin/yarn
@ -1,9 +1,16 @@
|
||||
#!/usr/bin/env ruby
|
||||
APP_ROOT = File.expand_path('..', __dir__)
|
||||
|
||||
APP_ROOT = File.expand_path("..", __dir__)
|
||||
Dir.chdir(APP_ROOT) do
|
||||
begin
|
||||
exec "yarnpkg", *ARGV
|
||||
rescue Errno::ENOENT
|
||||
yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
|
||||
select { |dir| File.expand_path(dir) != __dir__ }.
|
||||
product(["yarn", "yarnpkg", "yarn.cmd", "yarn.ps1"]).
|
||||
map { |dir, file| File.expand_path(file, dir) }.
|
||||
find { |file| File.executable?(file) }
|
||||
|
||||
if yarn
|
||||
exec yarn, *ARGV
|
||||
else
|
||||
$stderr.puts "Yarn executable was not detected in the system."
|
||||
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
|
||||
exit 1
|
||||
|
@ -1,10 +1,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Define an application-wide content security policy
|
||||
# For further information see the following documentation
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
||||
|
||||
# Rails.application.config.content_security_policy do |policy|
|
||||
Rails.application.config.content_security_policy do |policy| # # If you are using webpack-dev-server then specify webpack-dev-server host
|
||||
policy.connect_src :self, :https, 'http://localhost:3035', 'ws://localhost:3035' if Rails.env.development?
|
||||
|
||||
# policy.default_src :self, :https
|
||||
# policy.font_src :self, :https, :data
|
||||
# policy.img_src :self, :https, :data
|
||||
@ -14,7 +18,7 @@
|
||||
|
||||
# # Specify URI for violation reports
|
||||
# # policy.report_uri "/csp-violation-report-endpoint"
|
||||
# end
|
||||
end
|
||||
|
||||
# If you are using UJS then enable automatic nonce generation
|
||||
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
||||
|
@ -1,3 +1,5 @@
|
||||
Openlab.configure do |config|
|
||||
config.base_uri = Rails.application.secrets.openlab_base_uri unless Rails.env.production?
|
||||
config.base_uri = Rails.application.secrets.openlab_base_uri if Rails.application.secrets.openlab_base_uri
|
||||
config.httparty_verify = Rails.application.secrets.openlab_ssl_verify
|
||||
config.httparty_verify_peer = Rails.application.secrets.openlab_ssl_verify_peer
|
||||
end
|
||||
|
@ -1,25 +1,42 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'sidekiq'
|
||||
require 'sidekiq-scheduler'
|
||||
|
||||
redis_host = ENV['REDIS_HOST'] || 'localhost'
|
||||
redis_url = "redis://#{redis_host}:6379"
|
||||
|
||||
Sidekiq.configure_server do |config|
|
||||
config.redis = { url: redis_url }
|
||||
|
||||
# load sidekiq-cron schedule config
|
||||
schedule_file = 'config/schedule.yml'
|
||||
config.client_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Client
|
||||
end
|
||||
|
||||
if File.exist?(schedule_file)
|
||||
rendered_schedule_file = ERB.new(File.read(schedule_file)).result
|
||||
Sidekiq::Cron::Job.load_from_hash YAML.safe_load(rendered_schedule_file)
|
||||
config.server_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Server
|
||||
end
|
||||
|
||||
SidekiqUniqueJobs::Server.configure(config)
|
||||
|
||||
config.on(:startup) do
|
||||
# load sidekiq-scheduler schedule config
|
||||
schedule_file = 'config/schedule.yml'
|
||||
if File.exist?(schedule_file)
|
||||
rendered_schedule_file = ERB.new(File.read(schedule_file)).result
|
||||
Sidekiq.schedule = YAML.safe_load(rendered_schedule_file)
|
||||
SidekiqScheduler::Scheduler.instance.reload_schedule!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Sidekiq.configure_client do |config|
|
||||
config.redis = { url: redis_url }
|
||||
end
|
||||
|
||||
Sidekiq::Extensions.enable_delay!
|
||||
config.client_middleware do |chain|
|
||||
chain.add SidekiqUniqueJobs::Middleware::Client
|
||||
end
|
||||
end
|
||||
|
||||
# Quieting logging in the test environment
|
||||
if Rails.env.test?
|
||||
|
@ -78,8 +78,8 @@ de:
|
||||
slots_not_deleted: "Von {TOTAL} Slots {COUNT, plural, one {} =1{wurde einer wurde nicht gelöscht} other{wurden {COUNT} nicht gelöscht}}. Möglicherweise {COUNT, plural, =1{ist er} other{sind sie}} bereits reserviert."
|
||||
you_should_select_at_least_a_machine: "Sie sollten mindestens eine Maschine auf diesem Slot auswählen."
|
||||
inconsistent_times: "Fehler: das Ende der Verfügbarkeit liegt vor dem Beginn."
|
||||
min_one_slot: "The availability must be split in one slot at least."
|
||||
min_slot_duration: "You must specify a valid duration for the slots."
|
||||
min_one_slot: "Die Verfügbarkeit muss auf mindestens einen Slot aufgeteilt werden."
|
||||
min_slot_duration: "Sie müssen eine gültige Dauer für die Slots angeben."
|
||||
export_is_running_you_ll_be_notified_when_its_ready: "Export wird ausgeführt. Sie werden nach Fertigstellung benachrichtigt."
|
||||
actions: "Aktionen"
|
||||
block_reservations: "Reservierungen blockieren"
|
||||
@ -98,8 +98,8 @@ de:
|
||||
delete_this_slot: "Nur diesen Slot"
|
||||
delete_this_and_next: "Diesen Slot und die folgenden"
|
||||
delete_all: "Alle Slots"
|
||||
event_in_the_past: "Create a slot in the past"
|
||||
confirm_create_event_in_the_past: "You are about to create a slot in the past. Are you sure you want to do this? Members will not be able to book this slot."
|
||||
event_in_the_past: "Slot in der Vergangenheit erstellen"
|
||||
confirm_create_event_in_the_past: "Sie erstellen einen Slot in der Vergangenheit. Sind Sie sicher? Mitglieder werden diesen Slot nicht buchen können."
|
||||
edit_event: "Veranstaltung bearbeiten"
|
||||
view_reservations: "Reservierungen anzeigen"
|
||||
legend: "Legende"
|
||||
@ -370,70 +370,70 @@ de:
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
spaces_pricing:
|
||||
prices_match_space_hours_rates_html: "The prices below match one hour of space reservation, <strong>without subscription</strong>."
|
||||
prices_calculated_on_hourly_rate_html: "All the prices will be automatically calculated based on the hourly rate defined here.<br/><em>For example</em>, if you define an hourly rate at {RATE}: a slot of {DURATION} minutes, will be charged <strong>{PRICE}</strong>."
|
||||
you_can_override: "You can override this duration for each availability you create in the agenda. The price will then be adjusted accordingly."
|
||||
extended_prices: "Moreover, you can define extended prices which will apply in priority over the hourly rate below. Extended prices allow you, for example, to set a favorable price for a booking of several hours."
|
||||
spaces: "Spaces"
|
||||
price_updated: "Price successfully updated"
|
||||
prices_match_space_hours_rates_html: "Die unten aufgeführten Preise entsprechen einer Stunde Raumbelegung <strong>ohne Abonnement</strong>."
|
||||
prices_calculated_on_hourly_rate_html: "Alle Preise werden automatisch nach dem hier definierten Stundensatz berechnet.<br/><em>Zum Beispiel</em> wird bei einem veranschlagten Stundensatz von {RATE} ein Slot von {DURATION} Minuten zum Preis von <strong>{PRICE}</strong> berechnet."
|
||||
you_can_override: "Sie können diese Dauer für jede Verfügbarkeit überschreiben, die Sie in der Agenda erstellen. Der Preis wird dann entsprechend angepasst."
|
||||
extended_prices: "Darüber hinaus können Sie erweiterte Preise festlegen, die vorrangig zum unten stehenden Stundensatz gelten. Mit erweiterten Preisen können Sie zum Beispiel einen günstigen Preis für eine Buchung über mehrere Stunden festlegen."
|
||||
spaces: "Räume"
|
||||
price_updated: "Preis erfolgreich aktualisiert"
|
||||
machines_pricing:
|
||||
prices_match_machine_hours_rates_html: "Die unten aufgeführten Preise entsprechen einer Stunde Maschinengebrauch, <strong>ohne Abonnement</strong>."
|
||||
prices_calculated_on_hourly_rate_html: "Alle Preise werden automatisch nach dem hier definierten Stundensatz berechnet.<br/><em>Zum Beispiel</em> wird bei einem veranschlagten Stundensatz von {RATE} ein Slot von {DURATION} Minuten, zum Preis von <strong>{PRICE}</strong> berechnet."
|
||||
you_can_override: "Sie können diese Dauer für jede Verfügbarkeit überschreiben, die Sie in der Agenda erstellen. Der Preis wird dann entsprechend angepasst."
|
||||
machines: "Maschinen"
|
||||
price_updated: "Price successfully updated"
|
||||
price_updated: "Preis erfolgreich aktualisiert"
|
||||
configure_packs_button:
|
||||
packs: "Prepaid packs"
|
||||
no_packs: "No packs for now"
|
||||
pack_DURATION: "{DURATION} hours"
|
||||
packs: "Vorausbezahlte Pakete"
|
||||
no_packs: "Momentan keine Pakete"
|
||||
pack_DURATION: "{DURATION} Stunden"
|
||||
configure_extended_prices_button:
|
||||
extended_prices: "Extended prices"
|
||||
no_extended_prices: "No extended price for now"
|
||||
extended_price_DURATION: "{DURATION} hours"
|
||||
extended_prices: "Erweiterter Preis"
|
||||
no_extended_prices: "Momentan kein erweiterter Preis"
|
||||
extended_price_DURATION: "{DURATION} Stunden"
|
||||
extended_price_form:
|
||||
duration: "Duration (hours)"
|
||||
amount: "Price"
|
||||
duration: "Dauer (Stunden)"
|
||||
amount: "Preis"
|
||||
pack_form:
|
||||
hours: "Hours"
|
||||
amount: "Price"
|
||||
disabled: "Disabled"
|
||||
validity_count: "Maximum validity"
|
||||
select_interval: "Interval..."
|
||||
hours: "Stunden"
|
||||
amount: "Preis"
|
||||
disabled: "Deaktiviert"
|
||||
validity_count: "Maximale Gültigkeit"
|
||||
select_interval: "Zeitraum..."
|
||||
intervals:
|
||||
day: "{COUNT, plural, one{Day} other{Days}}"
|
||||
week: "{COUNT, plural, one{Week} other{Weeks}}"
|
||||
month: "{COUNT, plural, one{Month} other{Months}}"
|
||||
year: "{COUNT, plural, one{Year} other{Years}}"
|
||||
day: "{COUNT, plural, one {Tag} other {Tage}}"
|
||||
week: "{COUNT, plural, one{Woche} other{Wochen}}"
|
||||
month: "{COUNT, plural, one{Monat} other{Monate}}"
|
||||
year: "{COUNT, plural, one {Jahr} other {Jahre}}"
|
||||
create_pack:
|
||||
new_pack: "New prepaid pack"
|
||||
new_pack_info: "A prepaid pack allows users to buy {TYPE, select, Machine{machine} Space{space} other{}} hours before booking any slots. These packs can provide discounts on volumes purchases."
|
||||
create_pack: "Create this pack"
|
||||
pack_successfully_created: "The new prepaid pack was successfully created."
|
||||
new_pack: "Neues vorausbezahltes Paket"
|
||||
new_pack_info: "Ein vorausbezahltes Paket erlaubt den Kauf von {TYPE, select, Machine{Maschinen-} Space{Raum-} other{}}Stunden vor der Buchung eines Slots. Diese Pakete können Rabatte auf Volumenkäufe bieten."
|
||||
create_pack: "Dieses Paket erstellen"
|
||||
pack_successfully_created: "Das neue Vorausbezahlungs-Paket wurde erfolgreich erstellt."
|
||||
delete_pack:
|
||||
pack_deleted: "The prepaid pack was successfully deleted."
|
||||
unable_to_delete: "Unable to delete the prepaid pack: "
|
||||
delete_pack: "Delete the prepaid pack"
|
||||
confirm_delete: "Delete"
|
||||
delete_confirmation: "Are you sure you want to delete this prepaid pack? This won't be possible if the pack was already bought by users."
|
||||
pack_deleted: "Das Vorausbezahlungs-Paket wurde erfolgreich gelöscht."
|
||||
unable_to_delete: "Paket konnte nicht gelöscht werden: "
|
||||
delete_pack: "Vorausbezahlungs-Paket löschen"
|
||||
confirm_delete: "Löschen"
|
||||
delete_confirmation: "Sind Sie sicher, dass Sie dieses Paket löschen möchten? Dies ist nicht möglich, wenn das Paket bereits von Benutzern gekauft wurde."
|
||||
edit_pack:
|
||||
edit_pack: "Edit the pack"
|
||||
confirm_changes: "Confirm changes"
|
||||
pack_successfully_updated: "The prepaid pack was successfully updated."
|
||||
edit_pack: "Das Paket bearbeiten"
|
||||
confirm_changes: "Änderungen bestätigen"
|
||||
pack_successfully_updated: "Das Vorausbezahlungs-Paket wurde erfolgreich aktualisiert."
|
||||
create_extended_price:
|
||||
new_extended_price: "New extended price"
|
||||
new_extended_price_info: "Extended prices allows you to define prices based on custom durations, instead of the default hourly rates."
|
||||
create_extended_price: "Create extended price"
|
||||
extended_price_successfully_created: "The new extended price was successfully created."
|
||||
new_extended_price: "Neuer erweiterter Preis"
|
||||
new_extended_price_info: "Erweiterte Preise erlauben Ihnen die Festlegung von Preisen basierend auf benutzerdefinierten Zeitdauern anstelle der Standard-Stundensätze."
|
||||
create_extended_price: "Erweiterten Preis erstellen"
|
||||
extended_price_successfully_created: "Der neue erweiterte Preis wurde erfolgreich erstellt."
|
||||
delete_extended_price:
|
||||
extended_price_deleted: "The extended price was successfully deleted."
|
||||
unable_to_delete: "Unable to delete the extended price: "
|
||||
delete_extended_price: "Delete the extended price"
|
||||
confirm_delete: "Delete"
|
||||
delete_confirmation: "Are you sure you want to delete this extended price?"
|
||||
extended_price_deleted: "Der erweiterte Preis wurde erfolgreich gelöscht."
|
||||
unable_to_delete: "Der erweiterte Preis konnte nicht gelöscht werden: "
|
||||
delete_extended_price: "Erweiterten Preis löschen"
|
||||
confirm_delete: "Löschen"
|
||||
delete_confirmation: "Sind Sie sicher, dass Sie diesen erweiterten Preis löschen möchten?"
|
||||
edit_extended_price:
|
||||
edit_extended_price: "Edit the extended price"
|
||||
confirm_changes: "Confirm changes"
|
||||
extended_price_successfully_updated: "The extended price was successfully updated."
|
||||
edit_extended_price: "Erweiterten Preis bearbeiten"
|
||||
confirm_changes: "Änderungen bestätigen"
|
||||
extended_price_successfully_updated: "Der erweiterte Preis wurde erfolgreich aktualisiert."
|
||||
#ajouter un code promotionnel
|
||||
coupons_new:
|
||||
add_a_coupon: "Gutschein hinzufügen"
|
||||
@ -496,7 +496,7 @@ de:
|
||||
details: "Details"
|
||||
amount: "Betrag"
|
||||
machine_booking-3D_printer: "Maschinen-Buchung - 3D-Drucker"
|
||||
training_booking-3D_print: "Training booking - initiation to 3d printing"
|
||||
training_booking-3D_print: "Schulungsbuchung - Einstieg ins 3D-Drucken"
|
||||
total_amount: "Gesamtbetrag"
|
||||
total_including_all_taxes: "Gesamtpreis inkl. Steuern"
|
||||
VAT_disabled: "MwSt. deaktiviert"
|
||||
@ -553,15 +553,15 @@ de:
|
||||
enable_VAT: "MwSt. aktivieren"
|
||||
VAT_rate: "MwSt.-Satz"
|
||||
VAT_history: "MwSt.-Sätze Historie"
|
||||
VAT_notice: "This parameter configures the general case of the VAT rate and applies to everything sold by the Fablab. It is possible to override this parameter by setting a specific VAT rate for each object."
|
||||
edit_multi_VAT_button: "More options"
|
||||
multiVAT: "Advanced VAT"
|
||||
multi_VAT_notice: "<strong>Please note</strong>: The current general rate is {RATE}%. Here you can define different VAT rates for each category.</br></br>For example, you can override this value, only for machine reservations, by filling in the corresponding field below. If no value is filled in, the general rate will apply."
|
||||
VAT_rate_machine: "Machine reservation"
|
||||
VAT_rate_space: "Space reservation"
|
||||
VAT_rate_training: "Training reservation"
|
||||
VAT_rate_event: "Event reservation"
|
||||
VAT_rate_subscription: "Subscription"
|
||||
VAT_notice: "Dieser Parameter legt den allgemeinen Fall des MwSt.-Satzes fest und gilt für alles, was der Fablab verkauft. Der Parameter kann überschreiben werden, indem ein spezieller Mehrwertsteuersatz für jedes Objekt festgelegt wird."
|
||||
edit_multi_VAT_button: "Weitere Optionen"
|
||||
multiVAT: "Erweiterte MwSt."
|
||||
multi_VAT_notice: "<strong>Bitte beachten Sie</strong>: Der aktuelle allgemeine MwSt.-Satz beträgt {RATE}%. Hier können Sie unterschiedliche Mehrwertsteuersätze für jede Kategorie festlegen.</br></br>Zum Beispiel können Sie diesen Wert für Maschinenreservierungen überschreiben, indem Sie das entsprechende Feld unten ausfüllen. Wird kein Wert ausgefüllt, gilt der allgemeine Satz."
|
||||
VAT_rate_machine: "Maschinenreservierung"
|
||||
VAT_rate_space: "Raumreservierung"
|
||||
VAT_rate_training: "Schulungsreservierung"
|
||||
VAT_rate_event: "Veranstaltungsreservierung"
|
||||
VAT_rate_subscription: "Abonnement"
|
||||
changed_at: "Geändert am"
|
||||
changed_by: "Von"
|
||||
deleted_user: "Gelöschter Nutzer"
|
||||
@ -603,9 +603,9 @@ de:
|
||||
logo_successfully_saved: "Logo erfolgreich gespeichert."
|
||||
an_error_occurred_while_saving_the_logo: "Beim Speichern des Logos ist ein Fehler aufgetreten."
|
||||
filename: "Dateiname"
|
||||
schedule_filename: "Schedule file name"
|
||||
schedule_filename: "Dateiname des Zeitplans"
|
||||
prefix_info: "Die Rechnungen werden als PDF-Dateien generiert, die mit dem folgenden Präfix benannt sind."
|
||||
schedule_prefix_info: "The payment schedules will be generated as PDF files, named with the following prefix."
|
||||
schedule_prefix_info: "Die Zahlungspläne werden als PDF-Dateien mit dem folgenden Prefix generiert."
|
||||
prefix: "Präfix"
|
||||
prefix_successfully_saved: "Dateipräfix erfolgreich gespeichert"
|
||||
an_error_occurred_while_saving_the_prefix: "Beim Speichern des Dateipräfix ist ein Fehler aufgetreten"
|
||||
@ -673,16 +673,20 @@ de:
|
||||
general_space_code: "Abrechnungscode für alle Räume"
|
||||
accounting_Space_label: "Raumbezeichnung"
|
||||
general_space_label: "Abrechnungs-Label für alle Räume"
|
||||
accounting_Error_code: "Errors code"
|
||||
general_error_code: "Accounting code for erroneous invoices"
|
||||
accounting_Error_label: "Errors label"
|
||||
general_error_label: "Account label for erroneous invoices"
|
||||
accounting_Pack_code: "Prepaid-pack code"
|
||||
general_pack_code: "Accounting code for prepaid-packs"
|
||||
accounting_Pack_label: "Prepaid-pack label"
|
||||
general_pack_label: "Account label for prepaid-packs"
|
||||
accounting_Error_code: "Fehlercode"
|
||||
general_error_code: "Rechnungscode für fehlerhafte Rechnungen"
|
||||
accounting_Error_label: "Fehlerbezeichnung"
|
||||
general_error_label: "Kontobezeichnung für fehlerhafte Rechnungen"
|
||||
codes_customization_success: "Anpassung der Abrechnungscodes erfolgreich gespeichert."
|
||||
unexpected_error_occurred: "Beim Speichern der Codes ist ein unerwarteter Fehler aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
export_accounting_data: "Abrechnungsdaten exportieren"
|
||||
export_what: "What do you want to export?"
|
||||
export_VAT: "Export the collected VAT"
|
||||
export_to_ACD: "Export all data to the accounting software ACD"
|
||||
export_what: "Was möchten Sie exportieren?"
|
||||
export_VAT: "Die gesammelte MwSt. exportieren"
|
||||
export_to_ACD: "Alle Daten in die Buchhaltungssoftware ACD exportieren"
|
||||
export_is_running: "Export wird ausgeführt. Sie werden nach Fertigstellung benachrichtigt."
|
||||
export_form_date: "Exportieren ab"
|
||||
export_to_date: "Exportieren bis"
|
||||
@ -706,10 +710,10 @@ de:
|
||||
debit_euro: "Soll in Euro"
|
||||
credit_euro: "Guthaben in Euro"
|
||||
lettering: "Beschriftung"
|
||||
start_date: "Start date"
|
||||
end_date: "End date"
|
||||
vat_rate: "VAT rate"
|
||||
amount: "Total amount"
|
||||
start_date: "Startdatum"
|
||||
end_date: "Enddatum"
|
||||
vat_rate: "MwSt.-Satz"
|
||||
amount: "Gesamtbetrag"
|
||||
payment:
|
||||
payment_settings: "Bezahlungseinstellungen"
|
||||
online_payment: "Online-Bezahlung"
|
||||
@ -722,53 +726,53 @@ de:
|
||||
error_check_keys: "Fehler: Bitte überprüfen Sie Ihre Stripe-Schlüssel."
|
||||
stripe_keys_saved: "Stripe-Schlüssel erfolgreich gespeichert."
|
||||
error_saving_stripe_keys: "Die Stripe-Schlüssel konnten nicht gespeichert werden. Bitte versuchen Sie es später erneut."
|
||||
payzen_keys_info_html: "<p>To be able to collect online payments, you must configure the <a href='https://payzen.eu' target='_blank'>PayZen</a> identifiers and keys.</p><p>Retrieve them from <a href='https://secure.payzen.eu/vads-merchant/' target='_blank'>your merchant back office</a>.</p>"
|
||||
client_keys: "Client key"
|
||||
api_keys: "API keys"
|
||||
payzen_keys_info_html: "<p>Um Online-Zahlungen zu erhalten, müssen Sie die <a href='https://payzen.eu' target='_blank'>PayZen</a> Identifikatoren und Schlüssel konfigurieren.</p><p>Holen Sie sie aus <a href='https://secure.payzen.eu/vads-merchant/' target='_blank'>Ihrem Händler-Backend</a>.</p>"
|
||||
client_keys: "Kundenschlüssel"
|
||||
api_keys: "API-Schlüssel"
|
||||
edit_keys: "Schlüssel bearbeiten"
|
||||
currency: "Währung"
|
||||
currency_info_html: "Bitte geben Sie unten die Währung an, die für Online-Bezahlung verwendet wird. Sie sollten einen ISO-Code mit drei Buchstaben aus der Liste <a href='https://stripe.com/docs/currencies' target='_blank'>Stripe unterstützter Währungen eingeben</a>."
|
||||
currency_alert_html: "<strong>Warnung</strong>: Die Währung kann nicht mehr geändert werden, nachdem die erste Online-Zahlung eingegangen ist. Bitte nehmen Sie diese Einstellung sorgfältig vor, bevor Sie Fab-Manager für Mitglieder öffnen."
|
||||
stripe_currency: "Stripe-Währung"
|
||||
gateway_configuration_error: "An error occurred while configuring the payment gateway: "
|
||||
gateway_configuration_error: "Fehler beim Konfigurieren des Zahlungs-Gateways: "
|
||||
payzen:
|
||||
payzen_keys: "PayZen keys"
|
||||
payzen_keys: "PayZen-Schlüssel"
|
||||
payzen_username: "Benutzername"
|
||||
payzen_password: "Passwort"
|
||||
payzen_endpoint: "REST API server name"
|
||||
payzen_hmac: "HMAC-SHA-256 key"
|
||||
payzen_public_key: "Client public key"
|
||||
payzen_endpoint: "REST API Server Name"
|
||||
payzen_hmac: "HMAC-SHA-256 Schlüssel"
|
||||
payzen_public_key: "Öffentlicher Schlüssel des Kunden"
|
||||
currency: "Währung"
|
||||
payzen_currency: "PayZen Währung"
|
||||
currency_info_html: "Bitte geben Sie unten die Währung an, die für Online-Bezahlung verwendet wird. Sie sollten einen ISO-Code mit drei Buchstaben aus der Liste <a href='https://payzen.io/de-DE/payment-file/ips/list-of-supported-currencies.html' target='_blank'>PayZen unterstützter Währungen eingeben</a>."
|
||||
save: "Speichern"
|
||||
currency_error: "The inputted value is not a valid currency"
|
||||
error_while_saving: "An error occurred while saving the currency: "
|
||||
currency_updated: "The PayZen currency was successfully updated to {CURRENCY}."
|
||||
currency_error: "Der eingegebene Wert ist keine gültige Währung"
|
||||
error_while_saving: "Beim Speichern der Währung ist ein Fehler aufgetreten: "
|
||||
currency_updated: "Die PayZen-Währung wurde erfolgreich auf {CURRENCY} aktualisiert."
|
||||
#select a payment gateway
|
||||
gateway_modal:
|
||||
select_gateway_title: "Select a payment gateway"
|
||||
gateway_info: "To securely collect and process payments online, Fab-manager needs to use an third-party service authorized by the financial institutions, called a payment gateway."
|
||||
select_gateway: "Please select an available gateway"
|
||||
select_gateway_title: "Zahlungs-Gateway auswählen"
|
||||
gateway_info: "Um Zahlungen sicher online zu sammeln und zu verarbeiten, muss Fab-Manager einen von Finanzinstituten autorisierten Drittanbieter nutzen, der als Zahlungsgateway bezeichnet wird."
|
||||
select_gateway: "Bitte wählen Sie ein verfügbares Gateway"
|
||||
stripe: "Stripe"
|
||||
payzen: "PayZen"
|
||||
confirm_button: "Validate the gateway"
|
||||
confirm_button: "Gateway überprüfen"
|
||||
payment_schedules:
|
||||
filter_schedules: "Pläne filtern"
|
||||
no_payment_schedules: "Keine Zahlungspläne zum Anzeigen"
|
||||
load_more: "Mehr laden"
|
||||
card_updated_success: "The user's card was successfully updated"
|
||||
card_updated_success: "Die Karte des Nutzers wurde erfolgreich aktualisiert"
|
||||
document_filters:
|
||||
reference: "Referenz"
|
||||
customer: "Kunde"
|
||||
date: "Datum"
|
||||
update_payment_mean_modal:
|
||||
title: "Update the payment mean"
|
||||
update_info: "Please specify below the new payment mean for this payment schedule to continue."
|
||||
select_payment_mean: "Select a new payment mean"
|
||||
method_Transfer: "By bank transfer"
|
||||
method_Check: "By check"
|
||||
confirm_button: "Update"
|
||||
title: "Zahlungsmittel aktualisieren"
|
||||
update_info: "Bitte geben Sie unten das neue Zahlungsmittel an, damit der Zahlungszeitplan fortgesetzt werden kann."
|
||||
select_payment_mean: "Neues Zahlungsmittel auswählen"
|
||||
method_Transfer: "Per Banküberweisung"
|
||||
method_Check: "Per Scheck"
|
||||
confirm_button: "Aktualisieren"
|
||||
#management of users, labels, groups, and so on
|
||||
members:
|
||||
users_management: "Benutzer-Verwaltung"
|
||||
@ -918,7 +922,7 @@ de:
|
||||
expires_at: "Läuft ab am:"
|
||||
price_: "Preis:"
|
||||
offer_free_days: "Kostenlose Tage anbieten"
|
||||
renew_subscription: "Renew the subscription"
|
||||
renew_subscription: "Abonnement erneuern"
|
||||
user_has_no_current_subscription: "Benutzer hat kein aktuelles Abonnement."
|
||||
subscribe_to_a_plan: "Plan abonnieren"
|
||||
trainings: "Schulungen"
|
||||
@ -944,7 +948,7 @@ de:
|
||||
a_problem_occurred_while_saving_the_date: "Beim Speichern des Datums ist ein Problem aufgetreten."
|
||||
new_subscription: "Neues Abonnement"
|
||||
you_are_about_to_purchase_a_subscription_to_NAME: "Sie sind dabei, ein Abonnement für {NAME} zu kaufen."
|
||||
with_schedule: "Subscribe with a monthly payment schedule"
|
||||
with_schedule: "Mit einem monatlichen Zahlungsplan abonnieren"
|
||||
subscription_successfully_purchased: "Abonnement erfolgreich gekauft."
|
||||
a_problem_occurred_while_taking_the_subscription: "Bei der Übernahme des Abonnements ist ein Problem aufgetreten"
|
||||
wallet: "Guthabenkonto"
|
||||
@ -953,37 +957,37 @@ de:
|
||||
cannot_extend_own_subscription: "Sie können Ihr eigenes Abonnement nicht erweitern. Bitte fragen Sie einen anderen Manager oder einen Administrator."
|
||||
#extend a subscription for free
|
||||
free_extend_modal:
|
||||
extend_subscription: "Extend the subscription"
|
||||
offer_free_days_infos: "You are about to extend the user's subscription by offering him free additional days."
|
||||
credits_will_remain_unchanged: "The balance of free credits (training / machines / spaces) of the user will remain unchanged."
|
||||
current_expiration: "Current subscription will expire at:"
|
||||
extend_subscription: "Abonnement verlängern"
|
||||
offer_free_days_infos: "Sie sind dabei, das Abonnement des Benutzers zu verlängern, indem Sie ihm zusätzliche Tage kostenlos anbieten."
|
||||
credits_will_remain_unchanged: "Der Saldo der freien Gutschriften (Schulungen / Maschinen / Räume) des Nutzers bleibt unverändert."
|
||||
current_expiration: "Aktuelles Abonnement läuft ab um:"
|
||||
DATE_TIME: "{DATE} {TIME}"
|
||||
new_expiration_date: "New expiration date:"
|
||||
number_of_free_days: "Number of free days:"
|
||||
extend: "Extend"
|
||||
extend_success: "The subscription was successfully extended for free"
|
||||
new_expiration_date: "Neues Ablaufdatum:"
|
||||
number_of_free_days: "Anzahl der freien Tage:"
|
||||
extend: "Erweitern"
|
||||
extend_success: "Das Abonnement wurde erfolgreich kostenlos erweitert"
|
||||
#renew a subscription
|
||||
renew_subscription_modal:
|
||||
renew_subscription: "Renew the subscription"
|
||||
renew_subscription_info: "You are about to renew the user's subscription by charging him again for his current subscription."
|
||||
credits_will_be_reset: "The balance of free credits (training / machines / spaces) of the user will be reset, unused credits will be lost."
|
||||
current_expiration: "Current subscription will expire at:"
|
||||
new_start: "The new subscription will start at:"
|
||||
new_expiration_date: "The new subscription will expire at:"
|
||||
pay_in_one_go: "Pay in one go"
|
||||
renew: "Renew"
|
||||
renew_success: "The subscription was successfully renewed"
|
||||
renew_subscription: "Abonnement erneuern"
|
||||
renew_subscription_info: "Sie verlängern das Abonnement des Benutzers, indem Sie ihm sein aktuelles Abonnement erneut berechnen."
|
||||
credits_will_be_reset: "Der Saldo der freien Credits (Schulung / Maschinen / Räume) des Benutzers wird zurückgesetzt, nicht genutzte Credits gehen verloren."
|
||||
current_expiration: "Aktuelles Abonnement läuft ab um:"
|
||||
new_start: "Das neue Abonnement beginnt am:"
|
||||
new_expiration_date: "Das neue Abonnement läuft ab um:"
|
||||
pay_in_one_go: "In einem Schritt bezahlen"
|
||||
renew: "Erneuern"
|
||||
renew_success: "Das Abonnement wurde erfolgreich verlängert"
|
||||
#take a new subscription
|
||||
subscribe_modal:
|
||||
subscribe_USER: "Subscribe {USER}"
|
||||
subscribe: "Subscribe"
|
||||
select_plan: "Please select a plan"
|
||||
pay_in_one_go: "Pay in one go"
|
||||
subscribe_USER: "{USER} abonnieren"
|
||||
subscribe: "Abonnieren"
|
||||
select_plan: "Bitte wählen Sie einen Plan"
|
||||
pay_in_one_go: "In einem Schritt bezahlen"
|
||||
subscription_success: ""
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "Administrator hinzufügen"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Administrator erfolgreich erstellt. {GENDER, select, female{Sie} other{Er}} erhält {GENDER, select, female{ihre} other{seine}} Verbindungsanweisungen per E-Mail."
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Administrator erfolgreich erstellt. Er erhält seine Verbindungsanweisungen per E-Mail."
|
||||
failed_to_create_admin: "Administrator konnte nicht erstellt werden:"
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
@ -1001,7 +1005,7 @@ de:
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "Manager hinzufügen"
|
||||
manager_successfully_created: "Manager erfolgreich erstellt. {GENDER, select, female{Sie} other{Er}} erhält {GENDER, select, female{ihre} other{seine}} Verbindungsanweisungen per E-Mail."
|
||||
manager_successfully_created: "Manager erfolgreich erstellt. Er erhält seine Verbindungsanweisungen per E-Mail."
|
||||
failed_to_create_manager: "Konnte den Manager nicht erstellen:"
|
||||
man: "Männlich"
|
||||
woman: "Weiblich"
|
||||
@ -1032,7 +1036,7 @@ de:
|
||||
oauth2_provider_successfully_added: "OAuth 2.0 Provider erfolgreich hinzugefügt."
|
||||
#edit an authentication provider (SSO)
|
||||
authentication_edit:
|
||||
provider: "Provider:"
|
||||
provider: "Anbieter:"
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "Um diesen Provider hinzuzufügen, muss die Übereinstimmung zwischen User.uid und der API festgelegt werden."
|
||||
provider_successfully_updated: "Anbieter erfolgreich aktualisiert."
|
||||
an_error_occurred_unable_to_update_the_provider: "Ein Fehler ist aufgetreten: Der Anbieter konnte nicht aktualisiert werden."
|
||||
@ -1228,9 +1232,9 @@ de:
|
||||
error_SETTING_locked: "Die Einstellung konnte nicht aktualisiert werden: {SETTING} ist gesperrt. Bitte kontaktieren Sie Ihren Systemadministrator."
|
||||
an_error_occurred_saving_the_setting: "Beim Speichern der Einstellung ist ein Fehler aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
book_overlapping_slots_info: "Erlauben / Verhindern der Reservierung von überlappenden Slots"
|
||||
allow_booking: "Allow booking"
|
||||
overlapping_categories: "Overlapping categories"
|
||||
overlapping_categories_info: "Preventing booking on overlapping slots will be done by comparing the date and time of the following categories of reservations."
|
||||
allow_booking: "Buchungen erlauben"
|
||||
overlapping_categories: "Überlappende Kategorien"
|
||||
overlapping_categories_info: "Die Buchung von überlappenden Zeitnischen wird durch einen Vergleich zwischen Datum und Uhrzeit der folgenden Buchungskategorien verhindert."
|
||||
default_slot_duration: "Standarddauer für Slots"
|
||||
duration_minutes: "Dauer (in Minuten)"
|
||||
default_slot_duration_info: "Die Verfügbarkeit von Maschinen und Räumen ist in mehrere Slots dieser Dauer aufgeteilt. Dieser Wert kann je Verfügbarkeit überschrieben werden."
|
||||
@ -1243,10 +1247,10 @@ de:
|
||||
plans_info_html: "<p>Abonnements bieten eine Möglichkeit, Ihre Preise zu segmentieren und Vorteile für reguläre Benutzer zu bieten.</p><p><strong>Warnung:</strong> Es wird nicht empfohlen, die Abonnements zu deaktivieren, wenn mindestens ein Abonnement auf dem System aktiv ist.</p>"
|
||||
enable_plans: "Pläne aktivieren"
|
||||
plans_module: "Plan-Modul"
|
||||
trainings: "Trainings"
|
||||
trainings_info_html: "<p>Trainings are fully integrated into the Fab-manger's agenda. If enabled, your members will be able to book and pay trainings.</p><p>Trainings provides a way to prevent members to book some machines, if they do have not taken the prerequisite course.</p>"
|
||||
enable_trainings: "Enable the trainings"
|
||||
trainings_module: "trainings module"
|
||||
trainings: "Schulungen"
|
||||
trainings_info_html: "<p>Schulungen sind vollständig in die Agenda von Fab-Manger integriert. Wenn aktiviert, können Mitglieder Schulungen buchen und bezahlen.</p><p>Schulungen können Mitglieder daran hindern, Maschinen zu buchen, für die sie noch nicht den Grundkurs absolviert haben.</p>"
|
||||
enable_trainings: "Schulungen aktivieren"
|
||||
trainings_module: "Schulungs-Modul"
|
||||
invoicing: "Rechnungsstellung"
|
||||
invoicing_info_html: "<p>Sie können das Rechnungsmodul komplett deaktivieren.</p><p>Das ist nützlich, wenn Sie über Ihr eigenes Rechnungssystem verfügen und nicht wollen, dass Fab-Manager Rechnungen generiert und an Mitglieder sendet.</p><p><strong>Warnung:</strong> Auch wenn Sie das Rechnungsmodul deaktivieren, müssen Sie die Mehrwertsteuer konfigurieren, um Fehler in Rechnungslegung und Preisen zu vermeiden. Die Konfiguration erfolgt in der Sektion « Rechnungen > Einstellungen ».</p>"
|
||||
enable_invoicing: "Rechnungsstellung aktivieren"
|
||||
@ -1256,7 +1260,7 @@ de:
|
||||
phone_is_required: "Telefonummer erforderlich"
|
||||
phone_required_info: "Sie können festlegen, ob die Telefonnummer erforderlich sein soll, um einen neuen Benutzer auf Fab-Manager zu registrieren."
|
||||
address: "Adresse"
|
||||
address_required_info_html: "You can define if the address should be required to register a new user on Fab-manager.<br/><strong>Please note</strong> that, depending on your country, the regulations may requires addresses for the invoices to be valid."
|
||||
address_required_info_html: "Sie können festlegen, ob eine Adresse für die Neuregistrierung eines Benutzers erforderlich sein soll.<br/><strong>Bitte beachten Sie</strong> dass in Abhängigkeit von Landesvorschriften Adressen für die Gültigkeit der Rechnungen erforderlich sein können."
|
||||
address_is_required: "Adresse ist erforderlich"
|
||||
captcha: "Captcha"
|
||||
captcha_info_html: "Sie können einen Schutz gegen Roboter einrichten, um zu verhindern, dass diese Accounts erstellen. Dieser Schutz verwendet Google reCAPTCHA. Melden Sie sich für <a href='http://www.google.com/recaptcha/admin' target='_blank'>ein API-Schlüsselpaar</a> an, um reCaptcha zu verwenden."
|
||||
@ -1278,24 +1282,24 @@ de:
|
||||
confirmation_required_info: "Optional können Sie die Bestätigung der E-Mail-Adresse für Benutzer obligatorisch machen, bevor Sie Zugriff auf Fab-Manager bekommen."
|
||||
confirmation_is_required: "Bestätigung erforderlich"
|
||||
wallet_module: "Guthabenkonto-Modul"
|
||||
public_agenda_module: "public agenda module"
|
||||
public_agenda_module: "öffentliches Agenda-Modul"
|
||||
statistics_module: "Statistik-Modul"
|
||||
upcoming_events_shown: "Anzeigelimit für anstehende Termine"
|
||||
display_invite_to_renew_pack: "Display the invite to renew prepaid-packs"
|
||||
packs_threshold_info_html: "You can define under how many hours the user will be invited to buy a new prepaid-pack, if his stock of prepaid hours is under this threshold.<br/>You can set a <strong>number of hours</strong> (<em>eg. 5</em>) or a <strong>percentage</strong> of his current pack pack (<em>eg. 0.05 means 5%</em>)."
|
||||
renew_pack_threshold: "threshold for packs renewal"
|
||||
pack_only_for_subscription_info_html: "If this option is activated, the purchase and use of a prepaid pack is only possible for the user with a valid subscription."
|
||||
pack_only_for_subscription: "Subscription valid for purchase and use of a prepaid pack"
|
||||
pack_only_for_subscription_info: "Make subscription mandatory for prepaid packs"
|
||||
extended_prices: "Extended prices"
|
||||
extended_prices_info_html: "Spaces can have different prices depending on the cumulated duration of the booking. You can choose if this apply to all bookings or only to those starting within the same day."
|
||||
extended_prices_in_same_day: "Extended prices in the same day"
|
||||
public_registrations: "Public registrations"
|
||||
display_invite_to_renew_pack: "Einladung zur Erneuerung der vorausbezahlten Pakete anzeigen"
|
||||
packs_threshold_info_html: "Sie können festlegen, ab wievielen Reststunden der Benutzer auf den Kauf eines neuen Pakets an vorausbezahlten Stunden hingewiesen wird.<br/>Sie können eine <strong>Anzahl von Stunden</strong> (<em>z. B. 5</em>) oder einen <strong>Prozentsatz</strong> seines aktuellen Pakets (<em>z. B. 0,05 bedeutet 5%</em>) angeben."
|
||||
renew_pack_threshold: "Schwellenwert für Paketverlängerung"
|
||||
pack_only_for_subscription_info_html: "Wenn diese Option aktiviert ist, können nur Benutzer mit einem gültigen Abonnement vorausbezahlte Pakete kaufen und nutzen."
|
||||
pack_only_for_subscription: "Abonnement gültig für Kauf und Nutzung eines vorausbezahlten Pakets"
|
||||
pack_only_for_subscription_info: "Abonnement für vorausbezahlte Pakete obligatorisch machen"
|
||||
extended_prices: "Erweiterter Preis"
|
||||
extended_prices_info_html: "Räume können je nach Dauer der Buchung unterschiedliche Preise haben. Sie können wählen, ob dies für alle Buchungen oder nur für diejenigen gilt, die am selben Tag beginnen."
|
||||
extended_prices_in_same_day: "Erweiterte Preise am selben Tag"
|
||||
public_registrations: "Öffentliche Registrierungen"
|
||||
overlapping_options:
|
||||
training_reservations: "Trainings"
|
||||
machine_reservations: "Machines"
|
||||
space_reservations: "Spaces"
|
||||
events_reservations: "Events"
|
||||
training_reservations: "Schulungen"
|
||||
machine_reservations: "Maschinen"
|
||||
space_reservations: "Räume"
|
||||
events_reservations: "Veranstaltungen"
|
||||
general:
|
||||
general: "Allgemein"
|
||||
title: "Titel"
|
||||
@ -1317,9 +1321,9 @@ de:
|
||||
name: "Name"
|
||||
created_at: "Erstellungsdatum"
|
||||
updated_at: "Datum der letzten Aktualisierung"
|
||||
public_registrations: "Public registrations"
|
||||
public_registrations_info: "Allow everyone to register a new account on the platform. If disabled, only administrators and managers can create new accounts."
|
||||
public_registrations_allowed: "Public registrations allowed"
|
||||
public_registrations: "Öffentliche Registrierungen"
|
||||
public_registrations_info: "Erlaube jedem, ein neues Konto auf der Plattform anzulegen. Wenn deaktiviert, können nur Administratoren und Manager neue Konten erstellen."
|
||||
public_registrations_allowed: "Öffentliche Registrierungen erlaubt"
|
||||
help: "Hilfe"
|
||||
feature_tour: "Feature-Tour"
|
||||
feature_tour_info_html: "<p>Wenn sich ein Administrator oder Manager anmeldet, wird beim jeweils ersten Besuch eines Abschnitts der Anwendung die Feature-Tour ausgelöst. Sie können dieses Verhalten auf einen der folgenden Werte ändern:</p><ul><li>« Einmal », um das Standardverhalten beizubehalten.</li><li>« Pro Sitzung », um die Tour jedes Mal anzuzeigen, wenn die Anwendung erneut geöffnet wird.</li><li>« Nur manuell », deaktiviert die automatische Anzeige der Touren. Es ist weiterhin möglich, sie durch Drücken der F1-Taste oder durch Klicken auf « Hilfe » im Benutzermenu zu starten.</li></ul>"
|
||||
@ -1335,9 +1339,9 @@ de:
|
||||
wallet: "Guthabenkonto"
|
||||
wallet_info_html: "<p>Mit dem Guthabenkonto können Sie Benutzern eine Geldsumme zuweisen. Diese können es nach Belieben im Fab-Manager ausgeben.</p><p>Mitglieder können ihr Guthabenkonto nicht selbst aufladen, das können nur Manager und Administratoren.</p>"
|
||||
enable_wallet: "Guthabenkonto aktivieren"
|
||||
public_agenda: "Public agenda"
|
||||
public_agenda_info_html: "<p>The public agenda offers to members and visitors a general overview of the Fablab's planning.</p><p>Please note that, even logged, users won't be able to book a reservation or modify anything from this agenda: this is a read-only page.</p>"
|
||||
enable_public_agenda: "Enable public agenda"
|
||||
public_agenda: "Öffentliche Agenda"
|
||||
public_agenda_info_html: "<p>Die öffentliche Agenda bietet Mitgliedern und Besuchern eine allgemeine Übersicht über die Planung des Fablabs.</p><p>Bitte beachten Sie, dass selbst eingeloggte Benutzer keine Reservierung buchen oder die Agenda ändern können: Dies ist eine schreibgeschützte Seite.</p>"
|
||||
enable_public_agenda: "Öffentliche Agenda aktivieren"
|
||||
statistics: "Statistiken"
|
||||
statistics_info_html: "<p>Aktivieren oder deaktivieren Sie das Statistik-Modul.</p><p>Wenn aktiviert, konsolidiert das Modul die Tagesdaten in der Datenbank einer leistungsstarken Analyse-Engine. Administratoren können im entsprechenden Abschnitt die erstellten Diagramme und Tabellen durchsuchen.</p>"
|
||||
enable_statistics: "Statistik-Modul aktivieren"
|
||||
@ -1381,7 +1385,7 @@ de:
|
||||
online_payment: "Ist das Online-Zahlungsmodul aktiv?"
|
||||
invoices: "Ist das Rechnungsmodul aktiv?"
|
||||
openlab: "Ist das Projektteilungsmodul (OpenLab) aktiv?"
|
||||
tracking_id_info_html: "<p>Um die statistische Analyse der Besuche mithilfe von Google Analytics zu ermöglichen, tragen Sie hier Ihre Tracking-ID in der Form UA-000000-0 ein. Besuchen Sie <a href='https://analytics.google.com/analytics/web/' target='_blank'>die Google Analytics Website</a>, um eine Tracking-ID zu erstellen.<br/><strong>Warnung:</strong> wenn Sie dieses Feature aktivieren, muss in Ihrer Datenschutzrichtlinie darauf hingewiesen werden.</p><p> Um Google Analytics verwenden zu können, benötigen Sie auch den Hostnamen. Klicken Sie auf die angrenzende Schaltfläche. Dieser letzte Parameter wird auch an anderen Stellen verwendet, bitte verwenden Sie ihn vorsichtig.</p>"
|
||||
tracking_id_info_html: "Um die statistische Analyse der Besuche mithilfe von Google Analytics V4 zu ermöglichen, tragen Sie hier Ihre Tracking-ID in der Form G-XXXXXX ein. Besuchen Sie <a href='https://analytics.google.com/analytics/web/' target='_blank'>die Google Analytics Website</a>, um eine Tracking-ID zu erstellen.<br/><strong>Warnung:</strong> wenn Sie dieses Feature aktivieren, wird ein Cookie erstellt. Denken Sie daran, es oben in Ihrer Datenschutzrichtlinie darauf hingewiesen werden."
|
||||
tracking_id: "Tracking-ID"
|
||||
open_api_clients:
|
||||
add_new_client: "Neuen API-Client erstellen"
|
||||
@ -1395,7 +1399,7 @@ de:
|
||||
client_name: "Kundenname"
|
||||
confirmation_required: "Bestätigung erforderlich"
|
||||
do_you_really_want_to_delete_this_open_api_client: "Möchten Sie diesen OpenAPI-Client wirklich löschen?"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Möchten Sie diesen Zugriff wirklich widerrufen ? Er wird das aktuelle Token löschen und ersetzen."
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Möchten Sie diesen Zugriff wirklich widerrufen? Er wird das aktuelle Token löschen und ersetzen."
|
||||
client_successfully_created: "Client erfolgreich erstellt."
|
||||
client_successfully_updated: "Client erfolgreich aktualisiert."
|
||||
client_successfully_deleted: "Client erfolgreich gelöscht."
|
||||
@ -1422,50 +1426,50 @@ de:
|
||||
report_removed: "Der Bericht wurde gelöscht"
|
||||
failed_to_remove: "Ein Fehler ist aufgetreten, der Bericht konnte nicht gelöscht werden"
|
||||
plans_categories:
|
||||
manage_plans_categories: "Manage plans' categories"
|
||||
manage_plans_categories: "Plan-Kategorien verwalten"
|
||||
plan_categories_list:
|
||||
categories_list: "List of the plan's categories"
|
||||
categories_list: "Liste der Kategorien des Plans"
|
||||
no_categories: "Keine Kategorien"
|
||||
name: "Name"
|
||||
significance: "Significance"
|
||||
significance: "Signifikanz"
|
||||
create_plan_category:
|
||||
new_category: "New category"
|
||||
new_category: "Neue Kategorie"
|
||||
name: "Name"
|
||||
significance: "Significance"
|
||||
significance_info: "Categories will be shown ordered by signifiance. The higher you set the significance, the first the category will be shown."
|
||||
confirm_create: "Create the category"
|
||||
category_created: "The new category was successfully created"
|
||||
unable_to_create: "Unable to create the category: "
|
||||
significance: "Signifikanz"
|
||||
significance_info: "Kategorien werden nach Signifikanz sortiert. Je höher die Signifikanz, desto weiter oben wird die Kategorie angezeigt."
|
||||
confirm_create: "Kategorie erstellen"
|
||||
category_created: "Die neue Kategorie wurde erfolgreich erstellt"
|
||||
unable_to_create: "Die Kategorie konnte nicht erstellt werden: "
|
||||
edit_plan_category:
|
||||
edit_category: "Edit the category"
|
||||
edit_category: "Kategorie bearbeiten"
|
||||
name: "Name"
|
||||
significance: "Significance"
|
||||
confirm_edition: "Validate"
|
||||
category_updated: "The category was successfully updated"
|
||||
unable_to_update: "Unable to update the category: "
|
||||
significance_info: "Categories will be shown ordered by signifiance. The higher you set the significance, the first the category will be shown."
|
||||
significance: "Signifikanz"
|
||||
confirm_edition: "Bestätigen"
|
||||
category_updated: "Die Kategorie wurde erfolgreich aktualisiert"
|
||||
unable_to_update: "Die Kategorie konnte nicht aktualisiert werden: "
|
||||
significance_info: "Kategorien werden nach Signifikanz sortiert. Je höher die Signifikanz, desto weiter oben wird die Kategorie angezeigt."
|
||||
delete_plan_category:
|
||||
delete_category: "Delete a category"
|
||||
confirm_delete: "Delete"
|
||||
delete_confirmation: "Are you sure you want to delete this category? If you do, the plans associated with this category won't be sorted anymore."
|
||||
category_deleted: "The category was successfully deleted"
|
||||
unable_to_delete: "Unable to delete the category: "
|
||||
delete_category: "Kategorie löschen"
|
||||
confirm_delete: "Löschen"
|
||||
delete_confirmation: "Sind Sie sicher, dass Sie diese Kategorie löschen möchten? Wenn Sie dies tun, werden die mit dieser Kategorie verbundenen Pläne nicht mehr sortiert."
|
||||
category_deleted: "Die Kategorie wurde erfolgreich gelöscht"
|
||||
unable_to_delete: "Die Kategorie konnte nicht gelöscht werden: "
|
||||
local_payment:
|
||||
validate_cart: "Validate my cart"
|
||||
offline_payment: "Payment on site"
|
||||
about_to_cash: "You're about to confirm the cashing by an external payment mean. Please do not click on the button below until you have fully cashed the requested payment."
|
||||
about_to_confirm: "You're about to confirm your {ITEM, select, subscription{subscription} other{reservation}}."
|
||||
payment_method: "Payment method"
|
||||
method_card: "Online by card"
|
||||
method_check: "By check"
|
||||
method_transfer: "By bank transfer"
|
||||
card_collection_info: "By validating, you'll be prompted for the member's card number. This card will be automatically charged at the deadlines."
|
||||
check_collection_info: "By validating, you confirm that you have {DEADLINES} checks, allowing you to collect all the monthly payments."
|
||||
transfer_collection_info: "<p>By validating, you confirm that you set up {DEADLINES} bank direct debits, allowing you to collect all the monthly payments.</p><p><strong>Please note:</strong> the bank transfers are not automatically handled by Fab-manager.</p>"
|
||||
online_payment_disabled: "Online payment is not available. You cannot collect this payment schedule by online card."
|
||||
validate_cart: "Bestätigen Sie den Warenkorb"
|
||||
offline_payment: "Zahlung vor Ort"
|
||||
about_to_cash: "Sie bestätigen die Zahlung über ein externes Zahlungsmittel. Bitte klicken Sie nicht auf die Schaltfläche unten, bis Sie die angeforderte Zahlung vollständig eingelöst haben."
|
||||
about_to_confirm: "Sie bestätigen nun {ITEM, select, subscription{Ihr Abonnement} other{Ihre Reservierung}}"
|
||||
payment_method: "Zahlungsmethode"
|
||||
method_card: "Online per Karte"
|
||||
method_check: "Per Scheck"
|
||||
method_transfer: "Per Banküberweisung"
|
||||
card_collection_info: "Nach der Validierung werden Sie nach der Kartennummer des Mitglieds gefragt. Diese Karte wird automatisch zu den Fristen belastet."
|
||||
check_collection_info: "Durch die Validierung bestätigen Sie, dass Sie {DEADLINES} Schecks haben und so alle monatlichen Zahlungen abwickeln können."
|
||||
transfer_collection_info: "<p>Durch die Validierung bestätigen Sie, dass Sie {DEADLINES} Bank-Lastschriften eingerichtet haben, so dass alle monatlichen Zahlungen eingezogen werden können.</p><p><strong>Bitte beachten Sie:</strong> Banküberweisungen werden nicht automatisch vom Fab-Manager bearbeitet.</p>"
|
||||
online_payment_disabled: "Online-Zahlung ist nicht verfügbar. Sie können diesen Zahlungsplan nicht per Karte online abwickeln."
|
||||
check_list_setting:
|
||||
save: 'Save'
|
||||
customization_of_SETTING_successfully_saved: "Customization of the {SETTING} successfully saved."
|
||||
save: 'Speichern'
|
||||
customization_of_SETTING_successfully_saved: "Anpassung von {SETTING} erfolgreich gespeichert."
|
||||
#feature tour
|
||||
tour:
|
||||
conclusion:
|
||||
@ -1554,8 +1558,8 @@ de:
|
||||
title: "Gutschrift"
|
||||
content: "Ermöglicht die Erstellung einer Gutschrift für die Rechnung in dieser Zeile oder für ihre Unterelemente. <strong>Warnung:</strong> Nur das Rechnungsdokument wird generiert, die tatsächliche Gutschrift für den Benutzer wird immer in Ihrer Verantwortung liegen."
|
||||
payment-schedules:
|
||||
title: "Payment schedules"
|
||||
content: "<p>Some subscription plans may be configured to allow the members to pay them with a monthly payment schedule.</p><p>Here you can view all existing payment schedules and manage their deadlines.</p><p>Click on [+] at the beginning of a row to display all deadlines associated with a payment schedule, and run some actions on them.</p>"
|
||||
title: "Zahlungspläne"
|
||||
content: "<p>Einige Abonnements können so konfiguriert werden, dass die Mitglieder sie mit einem monatlichen Zahlungsplan bezahlen können.</p><p>Hier können Sie alle bestehenden Zahlungspläne einsehen und deren Fristen verwalten.</p><p>Klicken Sie auf [+] am Anfang einer Reihe, um alle mit einem Zahlungsplan verbundenen Fristen anzuzeigen, und führen Sie Aktionen aus.</p>"
|
||||
settings:
|
||||
title: "Einstellungen"
|
||||
content: "<p>Hier können Sie die Parameter für die Rechnungserstellung ändern. Klicken Sie auf das Element, das Sie bearbeiten wollen.</p><p>Insbesondere legen Sie hier fest, ob Sie der Mehrwertsteuer unterliegen und zu welchem Satz.</p>"
|
||||
|
@ -15,7 +15,7 @@ en:
|
||||
trainings: "Trainings"
|
||||
machines: "Machines"
|
||||
spaces: "Spaces"
|
||||
events: "Eventos"
|
||||
events: "Events"
|
||||
availabilities: "Availabilities"
|
||||
availabilities_notice: "Export to an Excel workbook every slots available for reservation, and their occupancy rate."
|
||||
info: "Info"
|
||||
@ -24,7 +24,7 @@ en:
|
||||
ongoing_reservations: "Ongoing reservations"
|
||||
without_reservation: "Without reservation"
|
||||
confirmation_required: "Confirmation required"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Do you really {GENDER, select, other {want}} to cancel the {USER}'s reservation, the {DATE} at {TIME}, concerning {RESERVATION}?"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Do you really want to cancel {USER}'s reservation, the {DATE} at {TIME}, concerning {RESERVATION}?"
|
||||
reservation_was_successfully_cancelled: "Reservation was successfully cancelled."
|
||||
reservation_cancellation_failed: "Reservation cancellation failed."
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "Unable to remove the last machine of the slot. Delete the slot rather."
|
||||
@ -184,7 +184,7 @@ en:
|
||||
NUMBER_reservation: "{NUMBER} {NUMBER, plural, one{reservation} other{reservations}}"
|
||||
none: "None"
|
||||
training_validation: "Training validation"
|
||||
training_of_the_DATE_TIME_html : "Training of the <strong>{DATE} - {TIME}</strong>"
|
||||
training_of_the_DATE_TIME_html: "Training of the <strong>{DATE} - {TIME}</strong>"
|
||||
you_can_validate_the_training_of_the_following_members: "You can validate the training of the following members:"
|
||||
deleted_user: "Deleted user"
|
||||
no_reservation: "No reservation"
|
||||
@ -271,7 +271,7 @@ en:
|
||||
events_edit:
|
||||
edit_the_event: "Edit the event"
|
||||
confirmation_required: "Confirmation required"
|
||||
edit_recurring_event: "You're about to update a periodic event. What do you want to update ?"
|
||||
edit_recurring_event: "You're about to update a periodic event. What do you want to update?"
|
||||
edit_this_event: "Only this event"
|
||||
edit_this_and_next: "This event and the following"
|
||||
edit_all: "All events"
|
||||
@ -322,10 +322,10 @@ en:
|
||||
none: "None" #grammar concordance with training.
|
||||
an_error_occurred_while_saving_the_number_of_credits: "An error occurred while saving the number of credits."
|
||||
an_error_occurred_while_deleting_credit_with_the_TRAINING: "An error occurred while deleting credit with the {TRAINING}."
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "An error occurred : unable to find the credit to revoke."
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "An error occurred: unable to find the credit to revoke."
|
||||
an_error_occurred_while_creating_credit_with_the_TRAINING: "An error occurred while creating credit with the {TRAINING}."
|
||||
not_set: "Not set"
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Error : a credit linking this machine with that subscription already exists."
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Error: a credit linking this machine with that subscription already exists."
|
||||
changes_have_been_successfully_saved: "Changes have been successfully saved."
|
||||
credit_was_successfully_saved: "Credit was successfully saved."
|
||||
error_creating_credit: "Unable to create credit, an error occurred"
|
||||
@ -365,7 +365,7 @@ en:
|
||||
these_prices_match_space_hours_rates_html: "The prices below match one hour of space usage, <strong>without subscription</strong>."
|
||||
add_a_space_credit: "Add a Space credit"
|
||||
space: "Space"
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "Error : a credit linking this space with that subscription already exists."
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "Error: a credit linking this space with that subscription already exists."
|
||||
status_enabled: "Enabled"
|
||||
status_disabled: "Disabled"
|
||||
status_all: "All"
|
||||
@ -511,7 +511,7 @@ en:
|
||||
no_invoices_for_now: "No invoices for now."
|
||||
payment_schedules_list: "Payment schedules"
|
||||
invoicing_settings: "Invoicing settings"
|
||||
warning_invoices_disabled: "Warning : invoices are not enabled. No invoices will be generated by Fab-manager. Nevertheless, you must correctly fill the information below, especially VAT."
|
||||
warning_invoices_disabled: "Warning: invoices are not enabled. No invoices will be generated by Fab-manager. Nevertheless, you must correctly fill the information below, especially VAT."
|
||||
change_logo: "Change logo"
|
||||
john_smith: "John Smith"
|
||||
john_smith_at_example_com: "jean.smith@example.com"
|
||||
@ -702,6 +702,10 @@ en:
|
||||
general_space_code: "Accounting code for all spaces"
|
||||
accounting_Space_label: "Spaces label"
|
||||
general_space_label: "Account label for all spaces"
|
||||
accounting_Pack_code: "Prepaid-pack code"
|
||||
general_pack_code: "Accounting code for prepaid-packs"
|
||||
accounting_Pack_label: "Prepaid-pack label"
|
||||
general_pack_label: "Account label for prepaid-packs"
|
||||
accounting_Error_code: "Errors code"
|
||||
general_error_code: "Accounting code for erroneous invoices"
|
||||
accounting_Error_label: "Errors label"
|
||||
@ -1012,7 +1016,7 @@ en:
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "Add an administrator"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Administrator successfully created. {GENDER, select, female{She} other{He}} receive {GENDER, select, female{her} other{his}} connection directives by e-mail."
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Successful creation. Connection directives were sent to the new administrator by e-mail."
|
||||
failed_to_create_admin: "Unable to create the administrator:"
|
||||
man: "Man"
|
||||
woman: "Woman"
|
||||
@ -1030,7 +1034,7 @@ en:
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "Add a manager"
|
||||
manager_successfully_created: "Manager successfully created. {GENDER, select, female{She} other{He}} receive {GENDER, select, female{her} other{his}} connection directives by e-mail."
|
||||
manager_successfully_created: "Successful creation. Connection directives were sent to the new manager by e-mail."
|
||||
failed_to_create_manager: "Unable to create the manager:"
|
||||
man: "Man"
|
||||
woman: "Woman"
|
||||
@ -1061,7 +1065,7 @@ en:
|
||||
oauth2_provider_successfully_added: "OAuth 2.0 provider successfully added."
|
||||
#edit an authentication provider (SSO)
|
||||
authentication_edit:
|
||||
provider: "Provider :"
|
||||
provider: "Provider:"
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "It is required to set the matching between User.uid and the API to add this provider."
|
||||
provider_successfully_updated: "Provider successfully updated."
|
||||
an_error_occurred_unable_to_update_the_provider: "An error occurred: unable to update the provider."
|
||||
@ -1351,7 +1355,7 @@ en:
|
||||
public_registrations_allowed: "Public registrations allowed"
|
||||
help: "Help"
|
||||
feature_tour: "Feature tour"
|
||||
feature_tour_info_html: "<p>When an administrator or a manager in logged-in, a feature tour will be triggered the first time he/she visits each section of the application. You can change this behavior to one of the following values:</p><ul><li>« Once » to keep the default behavior.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.</li></ul>"
|
||||
feature_tour_info_html: "<p>When an administrator or a manager in logged-in, a feature tour will be triggered the first time he visits each section of the application. You can change this behavior to one of the following values:</p><ul><li>« Once » to keep the default behavior.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.</li></ul>"
|
||||
feature_tour_display_mode: "Feature tour display mode"
|
||||
display_mode:
|
||||
once: "Once"
|
||||
@ -1410,7 +1414,7 @@ en:
|
||||
online_payment: "Is the online payment module active?"
|
||||
invoices: "Is the invoicing module active?"
|
||||
openlab: "Is the project sharing module (OpenLab) active?"
|
||||
tracking_id_info_html: "<p>To enable the statistical tracking of the visits using Google Analytics, set your tracking ID here. It is in the form UA-000000-2. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, remember to write it in your privacy policy, above.</p><p>The host name is also required to use Google Analytics. You can get it by clicking on the adjacent button. This last parameter is used elsewhere, please set it carefully.</p>"
|
||||
tracking_id_info_html: "To enable the statistical tracking of the visits using Google Analytics V4, set your tracking ID here. It is in the form G-XXXXXX. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, a cookie will be created. Remember to write it down in your privacy policy, above."
|
||||
tracking_id: "Tracking ID"
|
||||
open_api_clients:
|
||||
add_new_client: "Create new API client"
|
||||
@ -1424,7 +1428,7 @@ en:
|
||||
client_name: "Client's name"
|
||||
confirmation_required: "Confirmation required"
|
||||
do_you_really_want_to_delete_this_open_api_client: "Do you really want to delete this OpenAPI client?"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Do you really want to revoke this access ? It will erase and replace the current token."
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Do you really want to revoke this access? It will erase and replace the current token."
|
||||
client_successfully_created: "Client successfully created."
|
||||
client_successfully_updated: "Client successfully updated."
|
||||
client_successfully_deleted: "Client successfully deleted."
|
||||
|
@ -24,7 +24,7 @@ es:
|
||||
ongoing_reservations: "Reservas en curso"
|
||||
without_reservation: "Sin reserva"
|
||||
confirmation_required: "Confirmación requerida"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Realmente quieres cancelar la reserva del {USER}, en {DATE} a las {TIME}, respecto {RESERVATION}?"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "¿Realmente quieres cancelar la reserva del {USER}, en {DATE} a las {TIME}, respecto {RESERVATION}?"
|
||||
reservation_was_successfully_cancelled: "La reserva fué cancelada con éxito."
|
||||
reservation_cancellation_failed: "Fallo al cancelar la reserva."
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "No se puede quitar la última máquina de la ranura. Eliminar la ranura en su lugar."
|
||||
@ -271,7 +271,7 @@ es:
|
||||
events_edit:
|
||||
edit_the_event: "Editar el evento"
|
||||
confirmation_required: "Confirmation required"
|
||||
edit_recurring_event: "You're about to update a periodic event. What do you want to update ?"
|
||||
edit_recurring_event: "You're about to update a periodic event. What do you want to update?"
|
||||
edit_this_event: "Only this event"
|
||||
edit_this_and_next: "This event and the following"
|
||||
edit_all: "All events"
|
||||
@ -482,7 +482,7 @@ es:
|
||||
no_invoices_for_now: "Sin facturas por ahora."
|
||||
payment_schedules_list: "Payment schedules"
|
||||
invoicing_settings: "Configuración de facturación"
|
||||
warning_invoices_disabled: "Warning : invoices are not enabled. No invoices will be generated by Fab-manager. Nevertheless, you must correctly fill the information below, especially VAT."
|
||||
warning_invoices_disabled: "Warning: invoices are not enabled. No invoices will be generated by Fab-manager. Nevertheless, you must correctly fill the information below, especially VAT."
|
||||
change_logo: "Cambio de logotipo"
|
||||
john_smith: "John Smith"
|
||||
john_smith_at_example_com: "jean.smith@example.com"
|
||||
@ -673,6 +673,10 @@ es:
|
||||
general_space_code: "Accounting code for all spaces"
|
||||
accounting_Space_label: "Spaces label"
|
||||
general_space_label: "Account label for all spaces"
|
||||
accounting_Pack_code: "Prepaid-pack code"
|
||||
general_pack_code: "Accounting code for prepaid-packs"
|
||||
accounting_Pack_label: "Prepaid-pack label"
|
||||
general_pack_label: "Account label for prepaid-packs"
|
||||
accounting_Error_code: "Errors code"
|
||||
general_error_code: "Accounting code for erroneous invoices"
|
||||
accounting_Error_label: "Errors label"
|
||||
@ -838,7 +842,7 @@ es:
|
||||
active: "Activo"
|
||||
pending: "Pendiente"
|
||||
previous_provider: "Proveedor anteriorr"
|
||||
confirmation_required: "Delete the provider?"
|
||||
confirmation_required: "¿Eliminar el proveedor?"
|
||||
do_you_really_want_to_delete_the_TYPE_authentication_provider_NAME: "¿Realmente desea eliminar la {TYPE} proveedor de autenticación: {NAME}?"
|
||||
authentication_provider_successfully_deleted: "El proveedor de autenticación se eliminó correctamente."
|
||||
an_error_occurred_unable_to_delete_the_specified_provider: "Se ha producido un error: no se puede eliminar el proveedor especificado."
|
||||
@ -983,7 +987,7 @@ es:
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "Agregar un administrador"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "administrador creado correctamente. {GENDER, select, female{She} other{He}} receive {GENDER, select, female{her} other{his}} directivas de conexión por e-mail."
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Successful creation. Connection directives were sent to the new administrator by e-mail."
|
||||
failed_to_create_admin: "No se puede crear el administrador :"
|
||||
man: "Man"
|
||||
woman: "Woman"
|
||||
@ -1001,7 +1005,7 @@ es:
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "Add a manager"
|
||||
manager_successfully_created: "Manager successfully created. {GENDER, select, female{She} other{He}} receive {GENDER, select, female{her} other{his}} connection directives by e-mail."
|
||||
manager_successfully_created: "Successful creation. Connection directives were sent to the new manager by e-mail."
|
||||
failed_to_create_manager: "Unable to create the manager:"
|
||||
man: "Man"
|
||||
woman: "Woman"
|
||||
@ -1032,7 +1036,7 @@ es:
|
||||
oauth2_provider_successfully_added: "OAuth 2.0 proveedor agregado correctamente."
|
||||
#edit an authentication provider (SSO)
|
||||
authentication_edit:
|
||||
provider: "Proveedor :"
|
||||
provider: "Proveedor:"
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "Es necesario establecer la coincidencia entre User.uid y la API para agregar este proveedor."
|
||||
provider_successfully_updated: "Proveedor actualizado correctamente."
|
||||
an_error_occurred_unable_to_update_the_provider: "Se ha producido un error: no se puede actualizar el proveedor."
|
||||
@ -1322,7 +1326,7 @@ es:
|
||||
public_registrations_allowed: "Public registrations allowed"
|
||||
help: "Help"
|
||||
feature_tour: "Feature tour"
|
||||
feature_tour_info_html: "<p>When an administrator or a manager in logged-in, a feature tour will be triggered the first time he/she visits each section of the application. You can change this behavior to one of the following values:</p><ul><li>« Once » to keep the default behavior.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.</li></ul>"
|
||||
feature_tour_info_html: "<p>When an administrator or a manager in logged-in, a feature tour will be triggered the first time he visits each section of the application. You can change this behavior to one of the following values:</p><ul><li>« Once » to keep the default behavior.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.</li></ul>"
|
||||
feature_tour_display_mode: "Feature tour display mode"
|
||||
display_mode:
|
||||
once: "Once"
|
||||
@ -1381,7 +1385,7 @@ es:
|
||||
online_payment: "Is the online payment module active?"
|
||||
invoices: "Is the invoicing module active?"
|
||||
openlab: "Is the project sharing module (OpenLab) active?"
|
||||
tracking_id_info_html: "<p>To enable the statistical tracking of the visits using Google Analytics, set your tracking ID here. It is in the form UA-000000-2. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, remember to write it in your privacy policy, above.</p><p>The host name is also required to use Google Analytics. You can get it by clicking on the adjacent button. This last parameter is used elsewhere, please set it carefully.</p>"
|
||||
tracking_id_info_html: "To enable the statistical tracking of the visits using Google Analytics V4, set your tracking ID here. It is in the form G-XXXXXX. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, a cookie will be created. Remember to write it down in your privacy policy, above."
|
||||
tracking_id: "Tracking ID"
|
||||
open_api_clients:
|
||||
add_new_client: "Crear un nuevo cliente de API"
|
||||
@ -1395,7 +1399,7 @@ es:
|
||||
client_name: "Nombre del cliente"
|
||||
confirmation_required: "Confirmation required"
|
||||
do_you_really_want_to_delete_this_open_api_client: "¿Desea realmente eliminar este cliente OpenAPI?"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "¿Realmente desea revocar este acceso? Se borrará y reemplazará el token actual."
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Do you really want to revoke this access? It will erase and replace the current token."
|
||||
client_successfully_created: "Cliente creado correctamente."
|
||||
client_successfully_updated: "Cliente actualizado correctamente."
|
||||
client_successfully_deleted: "Cliente borrado correctamente."
|
||||
|
@ -24,7 +24,7 @@ fr:
|
||||
ongoing_reservations: "Réservations en cours"
|
||||
without_reservation: "Sans réservation"
|
||||
confirmation_required: "Confirmation requise"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Êtes-vous {GENDER, select, female{sûre} other{sûr}} de vouloir annuler la réservation de {USER}, le {DATE} à {TIME}, concernant {RESERVATION} ?"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Voulez-vous vraiment annuler la réservation de {USER}, le {DATE} à {TIME}, concernant {RESERVATION} ?"
|
||||
reservation_was_successfully_cancelled: "La réservation a bien été annulée."
|
||||
reservation_cancellation_failed: "L'annulation de la réservation a échouée."
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "Impossible de supprimer la dernière machine du créneau. Supprimez plutôt le créneau."
|
||||
@ -271,7 +271,7 @@ fr:
|
||||
events_edit:
|
||||
edit_the_event: "Éditer l’événement"
|
||||
confirmation_required: "Confirmation requise"
|
||||
edit_recurring_event: "Vous êtes sur le point de modifier un événement périodique. Que voulez-vous modifier ?"
|
||||
edit_recurring_event: "Vous êtes sur le point de mettre à jour un événement périodique. Que voulez-vous mettre à jour ?"
|
||||
edit_this_event: "Uniquement cet événement"
|
||||
edit_this_and_next: "Cet événement et tous les suivants"
|
||||
edit_all: "Tous les événements"
|
||||
@ -673,6 +673,10 @@ fr:
|
||||
general_space_code: "Code comptable pour tous les espaces"
|
||||
accounting_Space_label: "Libellé espaces"
|
||||
general_space_label: "Libellé du compte pour tous les espaces"
|
||||
accounting_Pack_code: "Code pack prépayé"
|
||||
general_pack_code: "Code comptable pour tous les packs prépayés"
|
||||
accounting_Pack_label: "Libellé pack prépayé"
|
||||
general_pack_label: "Libellé du compte pour tous les packs prépayés"
|
||||
accounting_Error_code: "Code erreurs"
|
||||
general_error_code: "Code comptable pour les factures en erreur"
|
||||
accounting_Error_label: "Libellé erreurs"
|
||||
@ -983,7 +987,7 @@ fr:
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "Ajouter un administrateur"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "L'administrateur a bien été créé. {GENDER, select, female{Elle} other{Il}} recevra ses instructions de connexion par email."
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Création réussie. Les directives de connexion ont été envoyées à l'administrateur par e-mail."
|
||||
failed_to_create_admin: "Impossible de créer l'administrateur :"
|
||||
man: "Homme"
|
||||
woman: "Femme"
|
||||
@ -1001,7 +1005,7 @@ fr:
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "Ajouter un gestionnaire"
|
||||
manager_successfully_created: "Le gestionnaire a bien été créé. {GENDER, select, female{Elle} other{Il}} recevra ses instructions de connexion par courriel."
|
||||
manager_successfully_created: "Création réussie. Les directives de connexion ont été envoyées au nouveau gestionnaire par e-mail."
|
||||
failed_to_create_manager: "Impossible de créer le gestionnaire :"
|
||||
man: "Homme"
|
||||
woman: "Femme"
|
||||
@ -1381,7 +1385,7 @@ fr:
|
||||
online_payment: "Le module de paiement par carte bancaire est-il actif ?"
|
||||
invoices: "Le module est facturation est-il actif ?"
|
||||
openlab: "Le module de partage de projets (OpenLab) est-il actif ?"
|
||||
tracking_id_info_html: "<p>Pour activer les suivi statistique des visites utilisant Google Analytics, définissez ici votre ID de suivi. Il se présente sous la forme UA-000000-2. Visitez <a href='https://analytics.google.com/analytics/web/' target='_blank'>le site web de Google Analytics</a> pour en obtenir un.<br/><strong>Attention :</strong> si vous activez cette fonctionnalité, pensez à l'indiquer dans votre politique de confidentialité, ci-dessus.</p><p>Le nom d'hôte est également requis pour pouvoir utiliser Google Analytics. Vous pouvez l'obtenir en cliquant sur le bouton adjacent. Ce dernier paramètre est utilisé ailleurs, veuillez le définir avec soin.</p>"
|
||||
tracking_id_info_html: "Pour activer les suivi statistique des visites utilisant Google Analytics V4, définissez ici votre ID de suivi. Il se présente sous la forme G-XXXXXX. Visitez <a href='https://analytics.google.com/analytics/web/' target='_blank'>le site web de Google Analytics</a> pour en obtenir un.<br/><strong>Attention :</strong> si vous activez cette fonctionnalité, une cookie sera créé. Pensez à l'indiquer dans votre politique de confidentialité, ci-dessus."
|
||||
tracking_id: "ID de suivi"
|
||||
open_api_clients:
|
||||
add_new_client: "Créer un compte client"
|
||||
|
@ -24,7 +24,7 @@
|
||||
ongoing_reservations: "Pågående reservasjoner"
|
||||
without_reservation: "Ikke reservert"
|
||||
confirmation_required: "Bekreftelse nødvendig"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "{GENDER, select, other {Ønsker du å}} kansellere {USER} sin reservasjon {DATE}, {TIME} for {RESERVATION}?"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Ønsker du å kansellere {USER} sin reservasjon {DATE}, {TIME} for {RESERVATION}?"
|
||||
reservation_was_successfully_cancelled: "Kansellering av reservasjon er gjennomført."
|
||||
reservation_cancellation_failed: "Det gikk ikke an å kansellere reservasjonen."
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "Kan ikke fjerne siste maskinen fra reservasjonen. Slett reservasjonen."
|
||||
@ -325,7 +325,7 @@
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "En feil oppstod: kunne ikke finne kreditten som skal tilbakekalles."
|
||||
an_error_occurred_while_creating_credit_with_the_TRAINING: "Det oppstod en feil under oppretting av kreditt med {TRAINING}."
|
||||
not_set: "Ikke angitt"
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Feil : en kreditnota på denne maskinen med dette abonnementet finnes allerede."
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Feil: en kreditnota på denne maskinen med dette abonnementet finnes allerede."
|
||||
changes_have_been_successfully_saved: "Endringene er lagret."
|
||||
credit_was_successfully_saved: "Kreditten ble lagret."
|
||||
error_creating_credit: "Kan ikke opprette kreditt, feil oppstod"
|
||||
@ -365,7 +365,7 @@
|
||||
these_prices_match_space_hours_rates_html: "Prisene under samsvarer med en time maskinbruk <strong>uten abonnement</strong>."
|
||||
add_a_space_credit: "Legg til en plass/romkreditt"
|
||||
space: "Plass/rom"
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "Feil : en kreditnota på denne maskinen med dette abonnementet finnes allerede."
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "Feil: en kreditnota på denne maskinen med dette abonnementet finnes allerede."
|
||||
status_enabled: "Aktivert"
|
||||
status_disabled: "Deaktivert"
|
||||
status_all: "Alle"
|
||||
@ -673,6 +673,10 @@
|
||||
general_space_code: "Regnskapskode for plasser/rom"
|
||||
accounting_Space_label: "Etikett, plasser/rom"
|
||||
general_space_label: "Regnskapskode for alle plasser/rom"
|
||||
accounting_Pack_code: "Prepaid-pack code"
|
||||
general_pack_code: "Accounting code for prepaid-packs"
|
||||
accounting_Pack_label: "Prepaid-pack label"
|
||||
general_pack_label: "Account label for prepaid-packs"
|
||||
accounting_Error_code: "Kode for feil"
|
||||
general_error_code: "Regnskapskode for fakturafeil"
|
||||
accounting_Error_label: "Etikett for feil"
|
||||
@ -1295,7 +1299,7 @@
|
||||
training_reservations: "Trainings"
|
||||
machine_reservations: "Machines"
|
||||
space_reservations: "Spaces"
|
||||
events_reservations: "Events"
|
||||
events_reservations: "Arrangementer"
|
||||
general:
|
||||
general: "Generelt"
|
||||
title: "Tittel"
|
||||
@ -1322,7 +1326,7 @@
|
||||
public_registrations_allowed: "Public registrations allowed"
|
||||
help: "Hjelp"
|
||||
feature_tour: "Funksjonsgjennomgang"
|
||||
feature_tour_info_html: "<p>When an administrator or a manager in logged-in, a feature tour will be triggered the first time he/she visits each section of the application. You can change this behavior to one of the following values:</p><ul><li>« Once » to keep the default behavior.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » to prevent displaying the tours automatically. It'll still be possible to trigger them by pressing the F1 key or by clicking on « Help » in the user's menu.</li></ul>"
|
||||
feature_tour_info_html: "<p>Når en administrator eller en leder er innlogget En fremvisning utløses første gang han besøker hver del av applikasjonen. Du kan endre denne adferden til en av følgende verdier:</p><ul><li>« Once » for å beholde standardvirkemåten.</li><li>« By session » to display the tours each time you reopen the application.</li><li>« Manual trigger » for å forhindre at turene vises automatisk. Det vil fortsatt være mulig å utløse dem ved å trykke F1-tasten eller ved å klikke på « Hjelp » i brukermenyen.</li></ul>"
|
||||
feature_tour_display_mode: "Modus for funksjonsgjennomgang"
|
||||
display_mode:
|
||||
once: "Én gang"
|
||||
@ -1381,7 +1385,7 @@
|
||||
online_payment: "Is the online payment module active?"
|
||||
invoices: "Is the invoicing module active?"
|
||||
openlab: "Is the project sharing module (OpenLab) active?"
|
||||
tracking_id_info_html: "<p>To enable the statistical tracking of the visits using Google Analytics, set your tracking ID here. It is in the form UA-000000-2. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, remember to write it in your privacy policy, above.</p><p>The host name is also required to use Google Analytics. You can get it by clicking on the adjacent button. This last parameter is used elsewhere, please set it carefully.</p>"
|
||||
tracking_id_info_html: "To enable the statistical tracking of the visits using Google Analytics V4, set your tracking ID here. It is in the form G-XXXXXX. Visit <a href='https://analytics.google.com/analytics/web/' target='_blank'>the Google Analytics website</a> to get one.<br/><strong>Warning:</strong> if you enable this feature, a cookie will be created. Remember to write it down in your privacy policy, above."
|
||||
tracking_id: "Tracking ID"
|
||||
open_api_clients:
|
||||
add_new_client: "Lage ny API-klient"
|
||||
@ -1395,7 +1399,7 @@
|
||||
client_name: "Klientens navn"
|
||||
confirmation_required: "Confirmation required"
|
||||
do_you_really_want_to_delete_this_open_api_client: "Do you really want to delete this OpenAPI client?"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Do you really want to revoke this access ? It will erase and replace the current token."
|
||||
do_you_really_want_to_revoke_this_open_api_access: "Do you really want to revoke this access? It will erase and replace the current token."
|
||||
client_successfully_created: "Client successfully created."
|
||||
client_successfully_updated: "Client successfully updated."
|
||||
client_successfully_deleted: "Client successfully deleted."
|
||||
@ -1595,7 +1599,7 @@
|
||||
content: "Create and manage promotional coupons allowing to offer punctual discounts to their holders."
|
||||
events:
|
||||
welcome:
|
||||
title: "Events"
|
||||
title: "Arrangementer"
|
||||
content: "Create events, track their reservations and organize them from this page."
|
||||
list:
|
||||
title: "The events"
|
||||
|
@ -15,7 +15,7 @@ pt:
|
||||
trainings: "Treinamentos"
|
||||
machines: "Máquinas"
|
||||
spaces: "Espaços"
|
||||
events: "Eventos"
|
||||
events: "Events"
|
||||
availabilities: "Disponíveis"
|
||||
availabilities_notice: "Exportar para Excel livro com todos os slots disponíveis para reserva, e suas ocupações."
|
||||
info: "Informações"
|
||||
@ -24,7 +24,7 @@ pt:
|
||||
ongoing_reservations: "Reservas em curso"
|
||||
without_reservation: "Sem reservas"
|
||||
confirmation_required: "Confirmação Obrigatória"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Você realmente deseja cancelar a reserva do usuário {USER}, em {DATE} ás {TIME}, sobre {RESERVATION}?"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "Realmente deseja cancelar a reserva do usuário {USER}, em {DATE} ás {TIME}, sobre {RESERVATION}?"
|
||||
reservation_was_successfully_cancelled: "A reserva foi cancelada com sucesso"
|
||||
reservation_cancellation_failed: "Cancelamento da reserva falhou."
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "Não é possível remover a última máquina do slot. Delete o slot primeiramente."
|
||||
@ -271,7 +271,7 @@ pt:
|
||||
events_edit:
|
||||
edit_the_event: "Editar evento"
|
||||
confirmation_required: "Confirmação obrigatória"
|
||||
edit_recurring_event: "Você está prestes a atualizar um evento periódico. O que você quer atualizar ?"
|
||||
edit_recurring_event: "Você está prestes a atualizar um evento periódico. O que você quer atualizar?"
|
||||
edit_this_event: "Apenas este evento"
|
||||
edit_this_and_next: "Este evento e os seguintes"
|
||||
edit_all: "Todos eventos"
|
||||
@ -322,10 +322,10 @@ pt:
|
||||
none: "Vazio" #grammar concordance with training.
|
||||
an_error_occurred_while_saving_the_number_of_credits: "Um erro ocorreu enquanto era salvo o número de créditos."
|
||||
an_error_occurred_while_deleting_credit_with_the_TRAINING: "Um erro ocorreu enquanto o crédito era deletado do {TRAINING}."
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "Um erro ocorreu : incapaz de encontrar o crédito para revogar."
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "An error occurred: unable to find the credit to revoke."
|
||||
an_error_occurred_while_creating_credit_with_the_TRAINING: "Ocorreu um erro ao criar o crédito com o {TRAINING}."
|
||||
not_set: "Não definido"
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Erro : um link de crédito entre esta máquina e esta assinatura já existe."
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "Erro: uma conexão de crédito entre esta máquina e esta assinatura já existe."
|
||||
changes_have_been_successfully_saved: "As modificações foram salvas com sucesso."
|
||||
credit_was_successfully_saved: "Crédito salvo com sucesso."
|
||||
error_creating_credit: "Não foi possível criar crédito, um erro ocorreu"
|
||||
@ -673,6 +673,10 @@ pt:
|
||||
general_space_code: "Código de contabilidade para todos os espaços"
|
||||
accounting_Space_label: "Rótulo de espaços"
|
||||
general_space_label: "Rótulo de conta para todos os espaços"
|
||||
accounting_Pack_code: "Prepaid-pack code"
|
||||
general_pack_code: "Accounting code for prepaid-packs"
|
||||
accounting_Pack_label: "Prepaid-pack label"
|
||||
general_pack_label: "Account label for prepaid-packs"
|
||||
accounting_Error_code: "Código do erro"
|
||||
general_error_code: "Código de contabilidade para faturas erradas"
|
||||
accounting_Error_label: "Rótulo dos erros"
|
||||
@ -983,7 +987,7 @@ pt:
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "Adicionar administrador"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Administrator criado com sucesso. {GENDER, select, female{Ela} other{Ele}} receberá {GENDER, select, female{sua} other{seu}} diretivas de conexão por e-mail."
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "Successful creation. Connection directives were sent to the new administrator by e-mail."
|
||||
failed_to_create_admin: "Não é possível criar administrador:"
|
||||
man: "Homem"
|
||||
woman: "Mulher"
|
||||
@ -1001,7 +1005,7 @@ pt:
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "Adicionar Gestor"
|
||||
manager_successfully_created: "Gerente criado com sucesso. {GENDER, select, female{Ela} other{Ele}} receberá {GENDER, select, female{Suas diretrizes de conexão por e-mail} other{Suas diretrizes de conexão por e-mail}}"
|
||||
manager_successfully_created: "Successful creation. Connection directives were sent to the new manager by e-mail."
|
||||
failed_to_create_manager: "Não foi possível criar o gerente:"
|
||||
man: "Homem"
|
||||
woman: "Mulher"
|
||||
@ -1032,7 +1036,7 @@ pt:
|
||||
oauth2_provider_successfully_added: "Provedor OAuth 2.0 adicionado com sucesso."
|
||||
#edit an authentication provider (SSO)
|
||||
authentication_edit:
|
||||
provider: "Provedor :"
|
||||
provider: "Provedor:"
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "É necessário definir a correspondência entre User.uid ea API para adicionar este fornecedor."
|
||||
provider_successfully_updated: "Provedor modificado com sucesso."
|
||||
an_error_occurred_unable_to_update_the_provider: "Um erro ocorreu: não é possível atualizar provedor."
|
||||
@ -1322,7 +1326,7 @@ pt:
|
||||
public_registrations_allowed: "Public registrations allowed"
|
||||
help: "Ajuda"
|
||||
feature_tour: "Tour de recursos"
|
||||
feature_tour_info_html: "<p>Quando um administrador ou um gerente está logado, um tour de recurso será acionado na primeira vez que ele/ela visita cada seção do aplicativo. Você pode mudar esse comportamento para um dos seguintes valores:</p><ul><li>« Uma vez » para manter o comportamento padrão.</li><li>« Por sessão » para exibir os tours cada vez que você reabrir o aplicativo.</li><li>« Ativação manual » para evitar a exibição automática dos tours. Ainda será possível ativá-los pressionando a tecla F1 ou clicando em « Ajuda » no menu do usuário.</li></ul>"
|
||||
feature_tour_info_html: "<p>Quando um administrador ou um gerente está logado, um tour de recurso será acionado na primeira vez que ele visita cada seção do aplicativo. Você pode mudar esse comportamento para um dos seguintes valores:</p><ul><li>« Uma vez » para manter o comportamento padrão.</li><li>« Por sessão » para exibir os tours cada vez que você reabrir o aplicativo.</li><li>« Ativação manual » para evitar a exibição automática dos tours. Ainda será possível ativá-los pressionando a tecla F1 ou clicando em « Ajuda » no menu do usuário.</li></ul>"
|
||||
feature_tour_display_mode: "Modo de exibição de recursos do tour"
|
||||
display_mode:
|
||||
once: "Uma vez"
|
||||
@ -1381,7 +1385,7 @@ pt:
|
||||
online_payment: "O módulo de pagamento online está ativo?"
|
||||
invoices: "O módulo de faturação está ativo?"
|
||||
openlab: "O módulo de compartilhamento de projetos (OpenLab) está ativo?"
|
||||
tracking_id_info_html: "<p>Para ativar o rastreamento estatístico das visitas usando o Google Analytics, defina seu ID de rastreamento aqui. Está na forma de UA-000000-2. Visite <a href='https://analytics.google.com/analytics/web/' target='_blank'>o site do Google Analytics</a> para obter um.<br/><strong>Aviso:</strong> se você ativar este recurso, lembre-se de escrevê-lo na sua política de privacidade.</p><p>O nome do host também é necessário para usar o Google Analytics. Você pode obtê-lo clicando no botão adjacente. Este último parâmetro é usado em outro lugar, por favor, defina-o com cuidado.</p>"
|
||||
tracking_id_info_html: "Para ativar o rastreamento estatístico das visitas usando o Google Analytics, defina seu ID de rastreamento aqui. Está na forma de G-XXXXXX. Visite <a href='https://analytics.google.com/analytics/web/' target='_blank'>o site do Google Analytics</a> para obter um.<br/><strong>Aviso:</strong> se você ativar este recurso, um cookie será criado. Lembre-se de escrevê-lo na sua política de privacidade."
|
||||
tracking_id: "ID de rastreamento"
|
||||
open_api_clients:
|
||||
add_new_client: "Criar novo cliente de API"
|
||||
|
@ -15,7 +15,7 @@ zu:
|
||||
trainings: "crwdns6709:0crwdne6709:0"
|
||||
machines: "crwdns6711:0crwdne6711:0"
|
||||
spaces: "crwdns6713:0crwdne6713:0"
|
||||
events: "crwdns6715:0crwdne6715:0"
|
||||
events: "crwdns22406:0crwdne22406:0"
|
||||
availabilities: "crwdns6717:0crwdne6717:0"
|
||||
availabilities_notice: "crwdns6719:0crwdne6719:0"
|
||||
info: "crwdns20468:0crwdne20468:0"
|
||||
@ -24,7 +24,7 @@ zu:
|
||||
ongoing_reservations: "crwdns6721:0crwdne6721:0"
|
||||
without_reservation: "crwdns20326:0crwdne20326:0"
|
||||
confirmation_required: "crwdns6725:0crwdne6725:0"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "crwdns20296:0GENDER={GENDER}crwdnd20296:0USER={USER}crwdnd20296:0DATE={DATE}crwdnd20296:0TIME={TIME}crwdnd20296:0RESERVATION={RESERVATION}crwdne20296:0"
|
||||
do_you_really_want_to_cancel_the_USER_s_reservation_the_DATE_at_TIME_concerning_RESERVATION: "crwdns22408:0{USER}crwdnd22408:0{DATE}crwdnd22408:0{TIME}crwdnd22408:0{RESERVATION}crwdne22408:0"
|
||||
reservation_was_successfully_cancelled: "crwdns6729:0crwdne6729:0"
|
||||
reservation_cancellation_failed: "crwdns6731:0crwdne6731:0"
|
||||
unable_to_remove_the_last_machine_of_the_slot_delete_the_slot_rather: "crwdns6733:0crwdne6733:0"
|
||||
@ -271,7 +271,7 @@ zu:
|
||||
events_edit:
|
||||
edit_the_event: "crwdns7095:0crwdne7095:0"
|
||||
confirmation_required: "crwdns19784:0crwdne19784:0"
|
||||
edit_recurring_event: "crwdns19786:0crwdne19786:0"
|
||||
edit_recurring_event: "crwdns22410:0crwdne22410:0"
|
||||
edit_this_event: "crwdns19788:0crwdne19788:0"
|
||||
edit_this_and_next: "crwdns19790:0crwdne19790:0"
|
||||
edit_all: "crwdns19792:0crwdne19792:0"
|
||||
@ -322,10 +322,10 @@ zu:
|
||||
none: "crwdns19808:0crwdne19808:0" #grammar concordance with training.
|
||||
an_error_occurred_while_saving_the_number_of_credits: "crwdns7173:0crwdne7173:0"
|
||||
an_error_occurred_while_deleting_credit_with_the_TRAINING: "crwdns7175:0{TRAINING}crwdne7175:0"
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "crwdns7177:0crwdne7177:0"
|
||||
an_error_occurred_unable_to_find_the_credit_to_revoke: "crwdns22412:0crwdne22412:0"
|
||||
an_error_occurred_while_creating_credit_with_the_TRAINING: "crwdns7179:0{TRAINING}crwdne7179:0"
|
||||
not_set: "crwdns7181:0crwdne7181:0"
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "crwdns7183:0crwdne7183:0"
|
||||
error_a_credit_linking_this_machine_with_that_subscription_already_exists: "crwdns22414:0crwdne22414:0"
|
||||
changes_have_been_successfully_saved: "crwdns7185:0crwdne7185:0"
|
||||
credit_was_successfully_saved: "crwdns7187:0crwdne7187:0"
|
||||
error_creating_credit: "crwdns7189:0crwdne7189:0"
|
||||
@ -365,7 +365,7 @@ zu:
|
||||
these_prices_match_space_hours_rates_html: "crwdns20480:0crwdne20480:0"
|
||||
add_a_space_credit: "crwdns7259:0crwdne7259:0"
|
||||
space: "crwdns7261:0crwdne7261:0"
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "crwdns7263:0crwdne7263:0"
|
||||
error_a_credit_linking_this_space_with_that_subscription_already_exists: "crwdns22416:0crwdne22416:0"
|
||||
status_enabled: "crwdns7265:0crwdne7265:0"
|
||||
status_disabled: "crwdns7267:0crwdne7267:0"
|
||||
status_all: "crwdns7269:0crwdne7269:0"
|
||||
@ -482,7 +482,7 @@ zu:
|
||||
no_invoices_for_now: "crwdns7337:0crwdne7337:0"
|
||||
payment_schedules_list: "crwdns21058:0crwdne21058:0"
|
||||
invoicing_settings: "crwdns7339:0crwdne7339:0"
|
||||
warning_invoices_disabled: "crwdns7341:0crwdne7341:0"
|
||||
warning_invoices_disabled: "crwdns22418:0crwdne22418:0"
|
||||
change_logo: "crwdns7343:0crwdne7343:0"
|
||||
john_smith: "crwdns7345:0crwdne7345:0"
|
||||
john_smith_at_example_com: "crwdns7347:0crwdne7347:0"
|
||||
@ -673,6 +673,10 @@ zu:
|
||||
general_space_code: "crwdns7677:0crwdne7677:0"
|
||||
accounting_Space_label: "crwdns7679:0crwdne7679:0"
|
||||
general_space_label: "crwdns7681:0crwdne7681:0"
|
||||
accounting_Pack_code: "crwdns22446:0crwdne22446:0"
|
||||
general_pack_code: "crwdns22448:0crwdne22448:0"
|
||||
accounting_Pack_label: "crwdns22450:0crwdne22450:0"
|
||||
general_pack_label: "crwdns22452:0crwdne22452:0"
|
||||
accounting_Error_code: "crwdns21470:0crwdne21470:0"
|
||||
general_error_code: "crwdns21472:0crwdne21472:0"
|
||||
accounting_Error_label: "crwdns21474:0crwdne21474:0"
|
||||
@ -983,7 +987,7 @@ zu:
|
||||
#add a new administrator to the platform
|
||||
admins_new:
|
||||
add_an_administrator: "crwdns8027:0crwdne8027:0"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "crwdns8029:0GENDER={GENDER}crwdnd8029:0GENDER={GENDER}crwdne8029:0"
|
||||
administrator_successfully_created_he_will_receive_his_connection_directives_by_email: "crwdns22420:0crwdne22420:0"
|
||||
failed_to_create_admin: "crwdns8031:0crwdne8031:0"
|
||||
man: "crwdns8033:0crwdne8033:0"
|
||||
woman: "crwdns8035:0crwdne8035:0"
|
||||
@ -1001,7 +1005,7 @@ zu:
|
||||
#add a new manager to the platform
|
||||
manager_new:
|
||||
add_a_manager: "crwdns20348:0crwdne20348:0"
|
||||
manager_successfully_created: "crwdns20350:0GENDER={GENDER}crwdnd20350:0GENDER={GENDER}crwdne20350:0"
|
||||
manager_successfully_created: "crwdns22422:0crwdne22422:0"
|
||||
failed_to_create_manager: "crwdns20352:0crwdne20352:0"
|
||||
man: "crwdns20354:0crwdne20354:0"
|
||||
woman: "crwdns20356:0crwdne20356:0"
|
||||
@ -1032,7 +1036,7 @@ zu:
|
||||
oauth2_provider_successfully_added: "crwdns8081:0crwdne8081:0"
|
||||
#edit an authentication provider (SSO)
|
||||
authentication_edit:
|
||||
provider: "crwdns8083:0crwdne8083:0"
|
||||
provider: "crwdns22424:0crwdne22424:0"
|
||||
it_is_required_to_set_the_matching_between_User.uid_and_the_API_to_add_this_provider: "crwdns20208:0crwdne20208:0"
|
||||
provider_successfully_updated: "crwdns20210:0crwdne20210:0"
|
||||
an_error_occurred_unable_to_update_the_provider: "crwdns8089:0crwdne8089:0"
|
||||
@ -1322,7 +1326,7 @@ zu:
|
||||
public_registrations_allowed: "crwdns22283:0crwdne22283:0"
|
||||
help: "crwdns20764:0crwdne20764:0"
|
||||
feature_tour: "crwdns20766:0crwdne20766:0"
|
||||
feature_tour_info_html: "crwdns20768:0crwdne20768:0"
|
||||
feature_tour_info_html: "crwdns22426:0crwdne22426:0"
|
||||
feature_tour_display_mode: "crwdns20770:0crwdne20770:0"
|
||||
display_mode:
|
||||
once: "crwdns20772:0crwdne20772:0"
|
||||
@ -1381,7 +1385,7 @@ zu:
|
||||
online_payment: "crwdns19892:0crwdne19892:0"
|
||||
invoices: "crwdns19894:0crwdne19894:0"
|
||||
openlab: "crwdns19896:0crwdne19896:0"
|
||||
tracking_id_info_html: "crwdns20812:0crwdne20812:0"
|
||||
tracking_id_info_html: "crwdns22442:0crwdne22442:0"
|
||||
tracking_id: "crwdns20814:0crwdne20814:0"
|
||||
open_api_clients:
|
||||
add_new_client: "crwdns8443:0crwdne8443:0"
|
||||
@ -1395,7 +1399,7 @@ zu:
|
||||
client_name: "crwdns8459:0crwdne8459:0"
|
||||
confirmation_required: "crwdns8461:0crwdne8461:0"
|
||||
do_you_really_want_to_delete_this_open_api_client: "crwdns8463:0crwdne8463:0"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "crwdns8465:0crwdne8465:0"
|
||||
do_you_really_want_to_revoke_this_open_api_access: "crwdns22428:0crwdne22428:0"
|
||||
client_successfully_created: "crwdns8467:0crwdne8467:0"
|
||||
client_successfully_updated: "crwdns8469:0crwdne8469:0"
|
||||
client_successfully_deleted: "crwdns8471:0crwdne8471:0"
|
||||
|
@ -109,10 +109,10 @@ de:
|
||||
your_previous_trainings: "Ihre vorigen Schulungen"
|
||||
your_approved_trainings: "Ihre bestätigten Trainings"
|
||||
no_trainings: "Keine Schulungen"
|
||||
your_training_credits: "Your training credits"
|
||||
subscribe_for_credits: "Subscribe to benefit from free trainings"
|
||||
register_for_free: "Register for free to the following trainings:"
|
||||
book_here: "Book here"
|
||||
your_training_credits: "Dein Trainingsguthaben"
|
||||
subscribe_for_credits: "Abonnement abschließen, um kostenlose Schulungen zu erhalten"
|
||||
register_for_free: "Melden Sie sich kostenlos für folgende Schulungen an:"
|
||||
book_here: "Hier buchen"
|
||||
#dashboard: my events
|
||||
events:
|
||||
your_next_events: "Ihre nächsten Termine"
|
||||
@ -132,7 +132,7 @@ de:
|
||||
payment_schedules:
|
||||
no_payment_schedules: "Keine Zahlungspläne zum Anzeigen"
|
||||
load_more: "Mehr laden"
|
||||
card_updated_success: "Your card was successfully updated"
|
||||
card_updated_success: "Ihre Karte wurde erfolgreich aktualisiert"
|
||||
#public profil of a member
|
||||
members_show:
|
||||
members_list: "Mitgliederliste"
|
||||
@ -173,30 +173,30 @@ de:
|
||||
DATE_TIME: "{DATE} {TIME}"
|
||||
#modal telling users that they need to pass a training before booking a machine
|
||||
required_training_modal:
|
||||
to_book_MACHINE_requires_TRAINING_html: "To book the \"{MACHINE}\" you must have completed the training <strong>{TRAINING}</strong>."
|
||||
training_or_training_html: "</strong> or the training <strong>"
|
||||
to_book_MACHINE_requires_TRAINING_html: "Um \"{MACHINE}\" zu buchen, müssen Sie <strong>{TRAINING}</strong> abgeschlossen haben."
|
||||
training_or_training_html: "</strong> oder die Schulung <strong>"
|
||||
enroll_now: "Zur Schulung anmelden"
|
||||
no_enroll_for_now: "Ich möchte mich jetzt nicht anmelden"
|
||||
close: "Schließen"
|
||||
propose_packs_modal:
|
||||
available_packs: "Prepaid packs available"
|
||||
packs_proposed: "You can buy a prepaid pack of hours for this machine. These packs allows you to benefit from volume discounts."
|
||||
available_packs: "Prepaid-Pakete verfügbar"
|
||||
packs_proposed: "Sie können ein Paket vorausbezahlter Stunden für diese Maschine kaufen. Über diese Pakete können Sie einen Mengenrabatt erhalten."
|
||||
no_thanks: "Nein, danke"
|
||||
pack_DURATION: "{DURATION} hours"
|
||||
buy_this_pack: "Buy this pack"
|
||||
pack_bought_success: "You have successfully bought this pack of prepaid-hours. Your invoice will ba available soon from your dashboard."
|
||||
validity: "Usable for {COUNT} {PERIODS}"
|
||||
pack_DURATION: "{DURATION} Stunden"
|
||||
buy_this_pack: "Dieses Paket kaufen"
|
||||
pack_bought_success: "Sie haben erfolgreich dieses Paket vorbezahlter Stunden gekauft. Ihre Rechnung wird bald in Ihrem Dashboard verfügbar sein."
|
||||
validity: "Verwendbar für {COUNT} {PERIODS}"
|
||||
period:
|
||||
day: "{COUNT, plural, one{day} other{days}}"
|
||||
week: "{COUNT, plural, one{week} other{weeks}}"
|
||||
month: "{COUNT, plural, one{month} other{months}}"
|
||||
year: "{COUNT, plural, one{year} other{years}}"
|
||||
day: "{COUNT, plural, one {Tag} other {Tage}}"
|
||||
week: "{COUNT, plural, one{Woche} other{Wochen}}"
|
||||
month: "{COUNT, plural, one{Monat} other{Monate}}"
|
||||
year: "{COUNT, plural, one {Jahr} other {Jahre}}"
|
||||
packs_summary:
|
||||
prepaid_hours: "Prepaid hours"
|
||||
remaining_HOURS: "You have {HOURS} prepaid hours remaining for this {ITEM, select, Machine{machine} Space{space} other{}}."
|
||||
no_hours: "You don't have any prepaid hours for this {ITEM, select, Machine{machine} Space{space} other{}}."
|
||||
buy_a_new_pack: "Buy a new pack"
|
||||
unable_to_use_pack_for_subsription_is_expired: "You must have a valid subscription to use your remaining hours."
|
||||
prepaid_hours: "Vorausbezahlte Stunden"
|
||||
remaining_HOURS: "Sie haben {HOURS} vorausbezahlte Stunden für {ITEM, select, Machine{diese Maschine} Space{diesen Raum} other{}} übrig."
|
||||
no_hours: "Sie haben keine vorausbezahlte Nutzungsdauer für {ITEM, select, Machine{diese Maschine} Space{diesen Raum} other{}}."
|
||||
buy_a_new_pack: "Ein neues Paket kaufen"
|
||||
unable_to_use_pack_for_subsription_is_expired: "Sie benötigen für die verbleibenden Stunden ein gültiges Abonnement."
|
||||
#book a training
|
||||
trainings_reserve:
|
||||
trainings_planning: "Schulungsplanung"
|
||||
|
@ -7,7 +7,7 @@ es:
|
||||
you_ve_just_created_a_new_account_on_the_fablab_by_logging_from: "Acaba de crear una nueva cuenta en {GENDER, select, male{el} female{la} neutral{} other{las}} {NAME}, al iniciar sesión desde"
|
||||
we_need_some_more_details: "Para finalizar la configuración de la plataforma, necesitamos algunos detalles más."
|
||||
your_email_is_already_used_by_another_account_on_the_platform: "Parece que su dirección de correo electrónico ya está siendo utilizada por otro usuario. Compruebe su dirección de correo electrónico e ingrese debajo del código que le hemos enviado."
|
||||
or: "or"
|
||||
or: "o"
|
||||
please_fill_the_following_form: "rellene el siguiente formulario, por favor"
|
||||
some_data_may_have_already_been_provided_by_provider_and_cannot_be_modified: "Algunos datos pueden haber sido proporcionados ya por {NAME} y no pueden modificarse"
|
||||
then_click_on_: "haz click en"
|
||||
@ -25,20 +25,20 @@ es:
|
||||
an_unexpected_error_occurred_check_your_authentication_code: "Ha ocurrido un error inesperado, por favor, revise su código de autentificación."
|
||||
send_code_again: "Enviar el código de nuevo"
|
||||
email_address_associated_with_your_account: "Email asociado con su cuenta"
|
||||
email_is_required: "Email address is required"
|
||||
email_is_required: "Se requiere una dirección de email"
|
||||
email_format_is_incorrect: "El formato de email incorrecto"
|
||||
code_successfully_sent_again: "El mail ha sido enviado otra vez con éxito"
|
||||
used_for_statistics: "This data will be used for statistical purposes"
|
||||
your_user_s_profile: "Your user's profile"
|
||||
user_s_profile_is_required: "User's profile is required."
|
||||
i_ve_read_and_i_accept_: "I've read and I accept"
|
||||
_the_fablab_policy: "the FabLab policy"
|
||||
change_my_data: "Change my data"
|
||||
sync_my_profile: "Sync my profile"
|
||||
once_your_data_are_up_to_date_: "Once your data are up to date,"
|
||||
_click_on_the_synchronization_button_opposite_: "click on the synchronization button opposite"
|
||||
_disconnect_then_reconnect_: "disconnect then reconnect"
|
||||
_for_your_changes_to_take_effect: "for your changes to take effect."
|
||||
used_for_statistics: "Estos datos se utilizarán para fines estadísticos"
|
||||
your_user_s_profile: "Perfil de tu usuario"
|
||||
user_s_profile_is_required: "Se requiere perfil de usuario."
|
||||
i_ve_read_and_i_accept_: "He leído y acepto"
|
||||
_the_fablab_policy: "la política de FabLab"
|
||||
change_my_data: "Cambiar mis datos"
|
||||
sync_my_profile: "Sincronizar mi perfil"
|
||||
once_your_data_are_up_to_date_: "Una vez sus datos hayan sido actualizados,"
|
||||
_click_on_the_synchronization_button_opposite_: "haga clic en el botón de sincronización"
|
||||
_disconnect_then_reconnect_: "desconectar y volver a conectar"
|
||||
_for_your_changes_to_take_effect: "para que los cambios surtan efecto."
|
||||
dashboard:
|
||||
#dashboard: public profile
|
||||
profile:
|
||||
@ -65,20 +65,20 @@ es:
|
||||
edit_my_profile: "Editar mi perfil"
|
||||
your_group_has_been_successfully_changed: "Su grupo ha sido cambiado con exito."
|
||||
an_unexpected_error_prevented_your_group_from_being_changed: "Un error inesperado impidió que su grupo fuese cambiado."
|
||||
confirmation_required: "Confirmation required"
|
||||
confirmation_required: "Confirmación requerida"
|
||||
confirm_delete_your_account: "¿Está seguro de querer eliminar su cuenta?"
|
||||
all_data_will_be_lost: "All your data will be destroyed and won't be recoverable."
|
||||
invoicing_data_kept: "According to regulation, all data related to your invoices will be kept separately for 10 years."
|
||||
statistic_data_anonymized: "Some data (sex, date of birth, group) will be anonymized and kept for statistical purposes."
|
||||
no_further_access_to_projects: "Your published projects will be anonymized and you won't get any further ability to edit them."
|
||||
all_data_will_be_lost: "Todos tus datos serán destruidos y no serán recuperables."
|
||||
invoicing_data_kept: "Según la regulación, todos los datos relacionados con sus facturas se mantendrán por separado durante 10 años."
|
||||
statistic_data_anonymized: "Algunos datos (sexo, fecha de nacimiento, grupo) serán anonimizados y conservados con fines estadísticos."
|
||||
no_further_access_to_projects: "Tus proyectos publicados serán anónimos y no tendrás más capacidad para editarlos."
|
||||
your_user_account_has_been_successfully_deleted_goodbye: "Su cuenta ha sido eliminada con éxito. Adiós"
|
||||
an_error_occured_preventing_your_account_from_being_deleted: "Un error inesperado impidió que su cuenta fuese eliminada."
|
||||
used_for_statistics: "This data will be used for statistical purposes"
|
||||
used_for_invoicing: "This data will be used for billing purposes"
|
||||
used_for_reservation: "This data will be used in case of change on one of your bookings"
|
||||
used_for_profile: "This data will only be displayed on your profile"
|
||||
used_for_pricing_stats: "This data will be used to determine the prices to which you are entitled, and for statistical purposes"
|
||||
public_profile: "You will have a public profile and other users will be able to associate you in their projects"
|
||||
used_for_statistics: "Estos datos se utilizarán para fines estadísticos"
|
||||
used_for_invoicing: "Estos datos se utilizarán para fines de facturación"
|
||||
used_for_reservation: "Estos datos se utilizarán en caso de cambio en una de sus reservas"
|
||||
used_for_profile: "Estos datos sólo se mostrarán en tu perfil"
|
||||
used_for_pricing_stats: "Estos datos se utilizarán para determinar los precios a los que tiene derecho, y con fines estadísticos"
|
||||
public_profile: "Tendrás un perfil público y otros usuarios podrán asociarte en sus proyectos"
|
||||
trainings: "Cursos"
|
||||
no_trainings: "Sin cursos"
|
||||
subscription: "Suscripción"
|
||||
@ -94,32 +94,32 @@ es:
|
||||
#dashboard: my projects
|
||||
projects:
|
||||
you_dont_have_any_projects: "Aún no tiene proyectos."
|
||||
add_a_project: "Add a project"
|
||||
add_a_project: "Añadir un proyecto"
|
||||
author: "Autor"
|
||||
collaborator: "Colaborador"
|
||||
rough_draft: "Draft"
|
||||
description: "Description"
|
||||
machines_and_materials: "Machines and materials"
|
||||
machines: "Machines"
|
||||
materials: "Materials"
|
||||
collaborators: "Collaborators"
|
||||
rough_draft: "Borrador"
|
||||
description: "Descripción"
|
||||
machines_and_materials: "Máquinas y materiales"
|
||||
machines: "Máquinas"
|
||||
materials: "Materiales"
|
||||
collaborators: "Colaboradores"
|
||||
#dashboard: my trainings
|
||||
trainings:
|
||||
your_next_trainings: "Sus próximos cursos"
|
||||
your_previous_trainings: "Sus cursos anteriores"
|
||||
your_approved_trainings: "Sus cursos aprobados"
|
||||
no_trainings: "No trainings"
|
||||
your_training_credits: "Your training credits"
|
||||
subscribe_for_credits: "Subscribe to benefit from free trainings"
|
||||
register_for_free: "Register for free to the following trainings:"
|
||||
book_here: "Book here"
|
||||
no_trainings: "Sin cursos"
|
||||
your_training_credits: "Tus créditos de entrenamiento"
|
||||
subscribe_for_credits: "Suscríbete para beneficiarte de entrenamientos gratuitos"
|
||||
register_for_free: "Regístrate gratis en los siguientes entrenamientos:"
|
||||
book_here: "Reservar aquí"
|
||||
#dashboard: my events
|
||||
events:
|
||||
your_next_events: "Sus próximos eventos"
|
||||
no_events_to_come: "No hay próximos eventos"
|
||||
your_previous_events: "Sus eventos anteriores"
|
||||
no_passed_events: "No passed events"
|
||||
NUMBER_normal_places_reserved: "{NUMBER} {NUMBER, plural, =0{} =1{normal place reserved} other{normal places reserved}}"
|
||||
no_passed_events: "Sin eventos anteriores"
|
||||
NUMBER_normal_places_reserved: "¡{NUMBER} {NUMBER, plural, one {} =0{} =1{lugar normal reservado} other{lugares normales reservados}}"
|
||||
NUMBER_of_NAME_places_reserved: "{NUMBER} {NUMBER, plural, =0{} =1{of {NAME} place reserved} other{of {NAME} places reserved}}"
|
||||
#dashboard: my invoices
|
||||
invoices:
|
||||
@ -215,7 +215,7 @@ es:
|
||||
notifications:
|
||||
notifications_center: "Centro de notificaciones"
|
||||
mark_all_as_read: "Marcar como leido"
|
||||
date: "Date"
|
||||
date: "Fecha"
|
||||
notif_title: "Titulo"
|
||||
no_new_notifications: "No hay notificaciones nuevas."
|
||||
archives: "Archivos"
|
||||
|
@ -19,7 +19,7 @@ de:
|
||||
my_trainings: "Meine Trainings"
|
||||
my_events: "Meine Veranstaltungen"
|
||||
my_invoices: "Meine Rechnungen"
|
||||
my_payment_schedules: "My payment schedules"
|
||||
my_payment_schedules: "Meine Zahlungspläne"
|
||||
my_wallet: "Mein Guthaben"
|
||||
#contextual help
|
||||
help: "Hilfe"
|
||||
@ -84,8 +84,8 @@ de:
|
||||
birth_date_is_required: "Geburtsdatum ist erforderlich."
|
||||
phone_number: "Telefonnummer"
|
||||
phone_number_is_required: "Die Angabe der Telefonnummer ist erforderlich."
|
||||
address: "Address"
|
||||
address_is_required: "Address is required"
|
||||
address: "Adresse"
|
||||
address_is_required: "Adresse ist erforderlich"
|
||||
i_authorize_Fablab_users_registered_on_the_site_to_contact_me: "Angemeldete Benutzer dürfen mich kontaktieren"
|
||||
i_accept_to_receive_information_from_the_fablab: "Das Fablab darf mir Informationen schicken"
|
||||
i_ve_read_and_i_accept_: "Ich habe gelesen und akzeptiere"
|
||||
@ -165,6 +165,7 @@ de:
|
||||
openlab_search_not_available_at_the_moment: "Suche über das gesamte Netzwerk ist derzeit nicht verfügbar. Sie können nach Projekten auf dieser Plattform suchen."
|
||||
project_search_result_is_empty: "Leider haben wir keine Ergebnisse gefunden, die Ihren Suchkriterien entsprechen."
|
||||
reset_all_filters: "Alle Filter zurücksetzen"
|
||||
keywords: "Schlüsselwörter"
|
||||
search: "Suche"
|
||||
all_projects: "Alle Projekte"
|
||||
my_projects: "Meine Projekte"
|
||||
@ -211,7 +212,7 @@ de:
|
||||
book: "Buchen"
|
||||
_or_the_: " oder die "
|
||||
machines_filters:
|
||||
show_machines: "Show machines"
|
||||
show_machines: "Maschinen anzeigen"
|
||||
status_enabled: "Aktiviert"
|
||||
status_disabled: "Deaktiviert"
|
||||
status_all: "Alle"
|
||||
@ -251,9 +252,9 @@ de:
|
||||
no_plans: "Für Ihre Gruppe sind keine Pläne verfügbar"
|
||||
AMOUNT_per_month: "{AMOUNT} / monate"
|
||||
my_group: "Meine Gruppe"
|
||||
his_group: "{GENDER, select, male{Seine} female{Ihre} other{Seine}} Gruppe"
|
||||
he_wants_to_change_group: "{ROLE, select, member{Ich möchte} other{Der Benutzer möchte}} die Gruppe wechseln"
|
||||
change_my_group: "Ändere {ROLE, select, member{meine} other{{GENDER, select, male{seine} female{ihre} other{seine}}}} Gruppe"
|
||||
his_group: "User's group"
|
||||
he_wants_to_change_group: "Change group"
|
||||
change_my_group: "Validate group change"
|
||||
summary: "Zusammenfassung"
|
||||
your_subscription_has_expired_on_the_DATE: "Ihr Abonnement ist am {DATE} abgelaufen"
|
||||
subscription_price: "Abonnementspreis"
|
||||
@ -266,10 +267,10 @@ de:
|
||||
an_error_prevented_to_change_the_user_s_group: "Fehler beim Ändern der Benutzergruppe."
|
||||
plans_filter:
|
||||
i_am: "Ich bin"
|
||||
select_group: "select a group"
|
||||
i_want_duration: "I want to subscribe for"
|
||||
all_durations: "All durations"
|
||||
select_duration: "select a duration"
|
||||
select_group: "Wählen Sie eine Gruppe aus"
|
||||
i_want_duration: "Ich möchte mich anmelden für"
|
||||
all_durations: "Alle Laufzeiten"
|
||||
select_duration: "Wählen Sie eine Laufzeit"
|
||||
#Fablab's events list
|
||||
events_list:
|
||||
the_fablab_s_events: "Veranstaltungen des Fablabs"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user