diff --git a/Gemfile.lock b/Gemfile.lock index 816c8acd..0d7b7624 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,31 +1,31 @@ GEM remote: https://rubygems.org/ specs: - action_text-trix (2.1.18) + action_text-trix (2.1.19) railties - actioncable (8.1.3) - actionpack (= 8.1.3) - activesupport (= 8.1.3) + actioncable (8.1.3.1) + actionpack (= 8.1.3.1) + activesupport (= 8.1.3.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (8.1.3) - actionpack (= 8.1.3) - activejob (= 8.1.3) - activerecord (= 8.1.3) - activestorage (= 8.1.3) - activesupport (= 8.1.3) + actionmailbox (8.1.3.1) + actionpack (= 8.1.3.1) + activejob (= 8.1.3.1) + activerecord (= 8.1.3.1) + activestorage (= 8.1.3.1) + activesupport (= 8.1.3.1) mail (>= 2.8.0) - actionmailer (8.1.3) - actionpack (= 8.1.3) - actionview (= 8.1.3) - activejob (= 8.1.3) - activesupport (= 8.1.3) + actionmailer (8.1.3.1) + actionpack (= 8.1.3.1) + actionview (= 8.1.3.1) + activejob (= 8.1.3.1) + activesupport (= 8.1.3.1) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (8.1.3) - actionview (= 8.1.3) - activesupport (= 8.1.3) + actionpack (8.1.3.1) + actionview (= 8.1.3.1) + activesupport (= 8.1.3.1) nokogiri (>= 1.8.5) rack (>= 2.2.4) rack-session (>= 1.0.1) @@ -33,36 +33,36 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (8.1.3) + actiontext (8.1.3.1) action_text-trix (~> 2.1.15) - actionpack (= 8.1.3) - activerecord (= 8.1.3) - activestorage (= 8.1.3) - activesupport (= 8.1.3) + actionpack (= 8.1.3.1) + activerecord (= 8.1.3.1) + activestorage (= 8.1.3.1) + activesupport (= 8.1.3.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (8.1.3) - activesupport (= 8.1.3) + actionview (8.1.3.1) + activesupport (= 8.1.3.1) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (8.1.3) - activesupport (= 8.1.3) + activejob (8.1.3.1) + activesupport (= 8.1.3.1) globalid (>= 0.3.6) - activemodel (8.1.3) - activesupport (= 8.1.3) - activerecord (8.1.3) - activemodel (= 8.1.3) - activesupport (= 8.1.3) + activemodel (8.1.3.1) + activesupport (= 8.1.3.1) + activerecord (8.1.3.1) + activemodel (= 8.1.3.1) + activesupport (= 8.1.3.1) timeout (>= 0.4.0) - activestorage (8.1.3) - actionpack (= 8.1.3) - activejob (= 8.1.3) - activerecord (= 8.1.3) - activesupport (= 8.1.3) + activestorage (8.1.3.1) + actionpack (= 8.1.3.1) + activejob (= 8.1.3.1) + activerecord (= 8.1.3.1) + activesupport (= 8.1.3.1) marcel (~> 1.0) - activesupport (8.1.3) + activesupport (8.1.3.1) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) @@ -144,7 +144,7 @@ GEM cldr-plurals-runtime-rb (1.1.0) cmdparse (3.0.7) coderay (1.1.3) - concurrent-ruby (1.3.7) + concurrent-ruby (1.3.8) connection_pool (3.0.2) crack (1.0.1) bigdecimal @@ -179,7 +179,7 @@ GEM dotenv (3.2.0) drb (2.2.3) email_typo (0.2.3) - erb (6.0.4) + erb (6.0.6) erb_lint (0.9.0) activesupport better_html (>= 2.0.1) @@ -217,7 +217,7 @@ GEM foreman (0.90.0) thor (~> 1.4) geom2d (0.4.1) - globalid (1.3.0) + globalid (1.4.0) activesupport (>= 6.1) google-apis-core (1.0.2) addressable (~> 2.8, >= 2.8.7) @@ -262,7 +262,7 @@ GEM geom2d (~> 0.4, >= 0.4.1) openssl (>= 2.2.1) strscan (>= 3.1.2) - i18n (1.14.8) + i18n (1.15.2) concurrent-ruby (~> 1.0) io-console (0.8.2) irb (1.18.0) @@ -271,7 +271,7 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) jmespath (1.6.2) - json (2.19.9) + json (2.21.1) jwt (3.2.0) base64 language_server-protocol (3.17.0.5) @@ -296,24 +296,24 @@ GEM loofah (2.25.2) crass (~> 1.0.2) nokogiri (>= 1.12.0) - mail (2.9.0) + mail (2.9.1) logger mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.1.0) + marcel (1.2.1) matrix (0.4.3) method_source (1.1.0) mini_mime (1.1.5) minitest (6.0.6) drb (~> 2.0) prism (~> 1.5) - msgpack (1.8.0) + msgpack (1.8.4) multi_json (1.19.1) net-http (0.9.1) uri (>= 0.11.1) - net-imap (0.6.4.1) + net-imap (0.6.6) date net-protocol net-pop (0.1.2) @@ -344,7 +344,7 @@ GEM orm_adapter (0.5.0) os (1.1.4) package_json (0.2.0) - pagy (43.4.4) + pagy (43.6.1) json uri yaml @@ -357,7 +357,7 @@ GEM pg (1.6.3-arm64-darwin) pg (1.6.3-x86_64-linux) pg (1.6.3-x86_64-linux-musl) - pp (0.6.3) + pp (0.6.4) prettyprint pretender (1.0.0) actionpack (>= 7.2) @@ -369,9 +369,6 @@ GEM reline (>= 0.6.0) pry-rails (0.3.11) pry (>= 0.13.0) - psych (5.3.1) - date - stringio public_suffix (7.0.5) puma (8.0.2) nio4r (~> 2.0) @@ -386,20 +383,20 @@ GEM rack (>= 1.3) rackup (2.3.1) rack (>= 3) - rails (8.1.3) - actioncable (= 8.1.3) - actionmailbox (= 8.1.3) - actionmailer (= 8.1.3) - actionpack (= 8.1.3) - actiontext (= 8.1.3) - actionview (= 8.1.3) - activejob (= 8.1.3) - activemodel (= 8.1.3) - activerecord (= 8.1.3) - activestorage (= 8.1.3) - activesupport (= 8.1.3) + rails (8.1.3.1) + actioncable (= 8.1.3.1) + actionmailbox (= 8.1.3.1) + actionmailer (= 8.1.3.1) + actionpack (= 8.1.3.1) + actiontext (= 8.1.3.1) + actionview (= 8.1.3.1) + activejob (= 8.1.3.1) + activemodel (= 8.1.3.1) + activerecord (= 8.1.3.1) + activestorage (= 8.1.3.1) + activesupport (= 8.1.3.1) bundler (>= 1.15.0) - railties (= 8.1.3) + railties (= 8.1.3.1) rails-dom-testing (2.3.0) activesupport (>= 5.0.0) minitest @@ -410,9 +407,9 @@ GEM rails-i18n (8.1.0) i18n (>= 0.7, < 2) railties (>= 8.0.0, < 9) - railties (8.1.3) - actionpack (= 8.1.3) - activesupport (= 8.1.3) + railties (8.1.3.1) + actionpack (= 8.1.3.1) + activesupport (= 8.1.3.1) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -421,9 +418,14 @@ GEM zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.4.2) - rdoc (7.2.0) + rbs (4.1.0) + logger + prism (>= 1.6.0) + tsort + rdoc (8.0.0) erb - psych (>= 4.0.0) + prism (>= 1.6.0) + rbs (>= 4.0.0) tsort redis-client (0.29.0) connection_pool @@ -525,12 +527,11 @@ GEM simplecov-html (0.13.2) simplecov_json_formatter (0.1.4) smart_properties (1.17.0) - sqlite3 (2.9.2-aarch64-linux-gnu) - sqlite3 (2.9.2-aarch64-linux-musl) - sqlite3 (2.9.2-arm64-darwin) - sqlite3 (2.9.2-x86_64-linux-gnu) - sqlite3 (2.9.2-x86_64-linux-musl) - stringio (3.2.0) + sqlite3 (2.9.5-aarch64-linux-gnu) + sqlite3 (2.9.5-aarch64-linux-musl) + sqlite3 (2.9.5-arm64-darwin) + sqlite3 (2.9.5-x86_64-linux-gnu) + sqlite3 (2.9.5-x86_64-linux-musl) strip_attributes (2.0.1) activemodel (>= 3.0, < 9.0) strscan (3.1.8) @@ -570,14 +571,14 @@ GEM crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) webrick (1.9.2) - websocket-driver (0.8.0) + websocket-driver (0.8.2) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) yaml (0.4.0) - zeitwerk (2.7.5) + zeitwerk (2.8.2) PLATFORMS aarch64-linux diff --git a/app/controllers/account_configs_controller.rb b/app/controllers/account_configs_controller.rb index 079866d7..23d82d94 100644 --- a/app/controllers/account_configs_controller.rb +++ b/app/controllers/account_configs_controller.rb @@ -37,7 +37,7 @@ class AccountConfigsController < ApplicationController end def destroy - raise InvalidKey unless allowed_keys.include?(@account_config.key) + raise InvalidKey unless allowed_destroy_keys.include?(@account_config.key) @account_config.destroy! @@ -50,6 +50,10 @@ class AccountConfigsController < ApplicationController ALLOWED_KEYS end + def allowed_destroy_keys + ALLOWED_KEYS + end + def load_account_config raise InvalidKey unless allowed_keys.include?(account_config_params[:key]) diff --git a/app/controllers/mfa_setup_controller.rb b/app/controllers/mfa_setup_controller.rb index 2ea90412..1860c1ed 100644 --- a/app/controllers/mfa_setup_controller.rb +++ b/app/controllers/mfa_setup_controller.rb @@ -20,6 +20,8 @@ class MfaSetupController < ApplicationController redirect_to settings_profile_index_path, notice: I18n.t('2fa_has_been_configured') else + RateLimit.call("mfa-setup-otp-#{current_user.id}", limit: 5, ttl: 5.minutes, enabled: true) + @provision_url = current_user.otp_provisioning_uri(current_user.email, issuer: Docuseal.product_name) @error_message = I18n.t('code_is_invalid') @@ -34,6 +36,8 @@ class MfaSetupController < ApplicationController redirect_to settings_profile_index_path, notice: I18n.t('2fa_has_been_removed') else + RateLimit.call("mfa-setup-otp-#{current_user.id}", limit: 5, ttl: 5.minutes, enabled: true) + @error_message = I18n.t('code_is_invalid') render turbo_stream: turbo_stream.replace(:modal, template: 'mfa_setup/edit'), status: :unprocessable_content diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb new file mode 100644 index 00000000..73aa4daf --- /dev/null +++ b/app/controllers/settings_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class SettingsController < ApplicationController + skip_authorization_check + + def index; end +end diff --git a/app/controllers/submission_events_controller.rb b/app/controllers/submission_events_controller.rb index 0dad2336..b3b892f1 100644 --- a/app/controllers/submission_events_controller.rb +++ b/app/controllers/submission_events_controller.rb @@ -24,5 +24,7 @@ class SubmissionEventsController < ApplicationController load_and_authorize_resource :submission - def index; end + def index + render :index, layout: 'plain' + end end diff --git a/app/controllers/submissions_controller.rb b/app/controllers/submissions_controller.rb index 31e568e2..96ae4972 100644 --- a/app/controllers/submissions_controller.rb +++ b/app/controllers/submissions_controller.rb @@ -33,6 +33,8 @@ class SubmissionsController < ApplicationController def new authorize!(:new, Submission) + + render :new, layout: 'plain' end def create diff --git a/app/controllers/submitters_controller.rb b/app/controllers/submitters_controller.rb index 7a40101f..48610854 100644 --- a/app/controllers/submitters_controller.rb +++ b/app/controllers/submitters_controller.rb @@ -8,6 +8,8 @@ class SubmittersController < ApplicationController if @submitter.preferences['email_message_uuid'].present? @submitter.account.email_messages.find_by(uuid: @submitter.preferences['email_message_uuid']) end + + render :edit, layout: 'plain' end def update diff --git a/app/controllers/templates_controller.rb b/app/controllers/templates_controller.rb index b0d3446f..c45fe6cd 100644 --- a/app/controllers/templates_controller.rb +++ b/app/controllers/templates_controller.rb @@ -25,7 +25,9 @@ class TemplatesController < ApplicationController redirect_to root_path end - def new; end + def new + render :new, layout: 'plain' + end def edit @template_data = Templates.serialize_for_builder(@template) diff --git a/app/controllers/templates_form_preview_controller.rb b/app/controllers/templates_form_preview_controller.rb index 5c4f23c6..fef1be33 100644 --- a/app/controllers/templates_form_preview_controller.rb +++ b/app/controllers/templates_form_preview_controller.rb @@ -13,11 +13,13 @@ class TemplatesFormPreviewController < ApplicationController @submitter.submission.submitters = @template.submitters.map { |item| Submitter.new(uuid: item['uuid']) } + Submissions::CreateFromSubmitters.maybe_set_dynamic_documents(@submitter.submission, preview: true) + Submissions.preload_with_pages(@submitter.submission) @attachments_index = ActiveStorage::Attachment.where(record: @submitter.submission.submitters, name: :attachments) .preload(:blob).index_by(&:uuid) - @form_configs = Submitters::FormConfigs.call(@submitter) + @form_configs = Submitters::FormConfigs.call(@submitter, SubmitFormController::CONFIG_KEYS) end end diff --git a/app/controllers/templates_preferences_controller.rb b/app/controllers/templates_preferences_controller.rb index b49202d0..449a58c6 100644 --- a/app/controllers/templates_preferences_controller.rb +++ b/app/controllers/templates_preferences_controller.rb @@ -14,7 +14,9 @@ class TemplatesPreferencesController < ApplicationController completed_notification_email_body] }.freeze - def show; end + def show + render :show, layout: 'plain' + end def create authorize!(:update, @template) diff --git a/app/controllers/templates_share_link_controller.rb b/app/controllers/templates_share_link_controller.rb index 5dfed111..8600ce95 100644 --- a/app/controllers/templates_share_link_controller.rb +++ b/app/controllers/templates_share_link_controller.rb @@ -3,7 +3,9 @@ class TemplatesShareLinkController < ApplicationController load_and_authorize_resource :template - def show; end + def show + render :show, layout: 'plain' + end def create authorize!(:update, @template) diff --git a/app/javascript/application.js b/app/javascript/application.js index 458a7a4e..6e8eec57 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -56,6 +56,9 @@ import OpenModal from './elements/open_modal' import BarChart from './elements/bar_chart' import FieldCondition from './elements/field_condition' import ConfirmUpload from './elements/confirm_upload' +import ScrollFade from './elements/scroll_fade' +import OpenModalMobile from './elements/open_modal_mobile' +import HistoryBack from './elements/history_back' import * as TurboInstantClick from './lib/turbo_instant_click' @@ -150,10 +153,14 @@ safeRegisterElement('open-modal', OpenModal) safeRegisterElement('bar-chart', BarChart) safeRegisterElement('field-condition', FieldCondition) safeRegisterElement('confirm-upload', ConfirmUpload) +safeRegisterElement('scroll-fade', ScrollFade) +safeRegisterElement('open-modal-mobile', OpenModalMobile) +safeRegisterElement('history-back', HistoryBack) safeRegisterElement('template-builder', class extends HTMLElement { connectedCallback () { document.addEventListener('turbo:submit-end', this.onSubmit) + document.addEventListener('turbo:before-cache', this.onBeforeCache) this.appElem = document.createElement('div') @@ -181,7 +188,10 @@ safeRegisterElement('template-builder', class extends HTMLElement { authenticityToken: document.querySelector('meta[name="csrf-token"]')?.content, withCustomFields: true, withPayment: this.dataset.withPayment === 'true', - isPaymentConnected: this.dataset.isPaymentConnected === 'true', + isStripeConnected: this.dataset.isPaymentConnected === 'true' || this.dataset.isStripeConnected === 'true', + withStripe: this.dataset.withStripe !== 'false', + withPaypal: this.dataset.withPaypal === 'true', + isPaypalConnected: this.dataset.isPaypalConnected === 'true', withFormula: this.dataset.withFormula === 'true', withSendButton: this.dataset.withSendButton !== 'false', withSignYourselfButton: this.dataset.withSignYourselfButton !== 'false', @@ -234,8 +244,14 @@ safeRegisterElement('template-builder', class extends HTMLElement { } } + onBeforeCache = () => { + this.app?.unmount() + this.appElem?.remove() + } + disconnectedCallback () { document.removeEventListener('turbo:submit-end', this.onSubmit) + document.removeEventListener('turbo:before-cache', this.onBeforeCache) this.app?.unmount() this.appElem?.remove() @@ -244,6 +260,8 @@ safeRegisterElement('template-builder', class extends HTMLElement { safeRegisterElement('import-list', class extends HTMLElement { connectedCallback () { + document.addEventListener('turbo:before-cache', this.onBeforeCache) + this.appElem = document.createElement('div') this.app = createApp(ImportList, { @@ -258,7 +276,14 @@ safeRegisterElement('import-list', class extends HTMLElement { this.appendChild(this.appElem) } + onBeforeCache = () => { + this.app?.unmount() + this.appElem?.remove() + } + disconnectedCallback () { + document.removeEventListener('turbo:before-cache', this.onBeforeCache) + this.app?.unmount() this.appElem?.remove() } diff --git a/app/javascript/application.scss b/app/javascript/application.scss index fd02cecf..1050df66 100644 --- a/app/javascript/application.scss +++ b/app/javascript/application.scss @@ -114,6 +114,13 @@ button[disabled] .enabled, button.btn-disabled .enabled { bottom: auto; } +@media (hover: none), (pointer: coarse) { + .tooltip-no-touch:before, + .tooltip-no-touch:after { + display: none; + } +} + .autocomplete { background: white; z-index: 1000; diff --git a/app/javascript/elements/history_back.js b/app/javascript/elements/history_back.js new file mode 100644 index 00000000..3c44ad61 --- /dev/null +++ b/app/javascript/elements/history_back.js @@ -0,0 +1,15 @@ +export default class extends HTMLElement { + connectedCallback () { + this.addEventListener('click', this.onClick) + } + + disconnectedCallback () { + this.removeEventListener('click', this.onClick) + } + + onClick = (e) => { + e.preventDefault() + + window.history.back() + } +} diff --git a/app/javascript/elements/open_modal_mobile.js b/app/javascript/elements/open_modal_mobile.js new file mode 100644 index 00000000..4096f1f6 --- /dev/null +++ b/app/javascript/elements/open_modal_mobile.js @@ -0,0 +1,17 @@ +export default class extends HTMLElement { + connectedCallback () { + if (this.dataset.disabled === 'true') return + if (!this.isMobile()) return + if (window.innerWidth >= 768) return + + this.querySelectorAll('a[data-turbo-frame]').forEach((link) => { + link.dataset.turboFrame = '_top' + }) + } + + isMobile () { + const isTouchWebkit = 'ontouchstart' in window && navigator.maxTouchPoints > 0 && /AppleWebKit|android/i.test(navigator.userAgent) + + return isTouchWebkit || /iPhone|iPad|iPod/i.test(navigator.userAgent) + } +} diff --git a/app/javascript/elements/scroll_fade.js b/app/javascript/elements/scroll_fade.js new file mode 100644 index 00000000..20c4906a --- /dev/null +++ b/app/javascript/elements/scroll_fade.js @@ -0,0 +1,40 @@ +export default class extends HTMLElement { + connectedCallback () { + this.addEventListener('scroll', this.updateFade, { passive: true }) + window.addEventListener('resize', this.updateFade) + + this.updateFade() + } + + disconnectedCallback () { + window.removeEventListener('resize', this.updateFade) + } + + updateFade = () => { + const maxScroll = this.scrollWidth - this.clientWidth + const fadeGradient = { + right: 'linear-gradient(to right, black calc(100% - 24px), transparent)', + left: 'linear-gradient(to right, transparent, black 24px)', + both: 'linear-gradient(to right, transparent, black 24px, black calc(100% - 24px), transparent)' + } + + let state = 'none' + + if (maxScroll > 4) { + if (this.scrollLeft <= 4) { + state = 'right' + } else if (this.scrollLeft >= maxScroll - 4) { + state = 'left' + } else { + state = 'both' + } + } + + this.applyFade(fadeGradient[state] || '') + } + + applyFade (gradient) { + this.style.maskImage = gradient + this.style.webkitMaskImage = gradient + } +} diff --git a/app/javascript/elements/turbo_modal.js b/app/javascript/elements/turbo_modal.js index 69c20549..89460ee6 100644 --- a/app/javascript/elements/turbo_modal.js +++ b/app/javascript/elements/turbo_modal.js @@ -6,7 +6,7 @@ export default actionable(class extends HTMLElement { document.addEventListener('keyup', this.onEscKey) - document.addEventListener('turbo:before-cache', this.close) + document.addEventListener('turbo:before-cache', this.onBeforeCache) if (this.dataset.closeAfterSubmit !== 'false') { document.addEventListener('turbo:submit-end', this.onSubmit) @@ -18,7 +18,7 @@ export default actionable(class extends HTMLElement { document.removeEventListener('keyup', this.onEscKey) document.removeEventListener('turbo:submit-end', this.onSubmit) - document.removeEventListener('turbo:before-cache', this.close) + document.removeEventListener('turbo:before-cache', this.onBeforeCache) } onSubmit = (e) => { @@ -33,6 +33,12 @@ export default actionable(class extends HTMLElement { } } + onBeforeCache = () => { + if (this.closest('turbo-frame')?.src) { + this.remove() + } + } + close = (e) => { e?.preventDefault() diff --git a/app/javascript/form.js b/app/javascript/form.js index 75158250..ab9535ca 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -35,6 +35,7 @@ safeRegisterElement('submission-form', class extends HTMLElement { scrollPadding: this.dataset.scrollPadding || '-80px', signatureText: this.dataset.signatureText, language: this.dataset.language, + paymentProvider: this.dataset.paymentProvider, dryRun: this.dataset.dryRun === 'true', expand: ['true', 'false'].includes(this.dataset.expand) ? this.dataset.expand === 'true' : null, withSignatureId: this.dataset.withSignatureId === 'true', diff --git a/app/javascript/submission_form/accessibility_areas.vue b/app/javascript/submission_form/accessibility_areas.vue index 6e720e93..8f05d4c9 100644 --- a/app/javascript/submission_form/accessibility_areas.vue +++ b/app/javascript/submission_form/accessibility_areas.vue @@ -69,8 +69,8 @@ :attachments-index="attachmentsIndex" /> 10) return '' + + return field.preferences.formula.replace(/{{(.*?)}}/g, (match, uuid) => { + const formulaField = this.fieldsUuidIndex[uuid] + + if (formulaField?.preferences?.formula) { + if (formulaField.type === 'text') { + return this.evalTextFormula(formulaField, depth + 1) + } else if (this.isMathLoaded) { + return this.calculateFormula(formulaField) + } + } + + const value = this.readonlyValues[uuid] ?? this.values[uuid] + + return Array.isArray(value) ? value.join(', ') : (value ?? '') + }) } } } diff --git a/app/javascript/submission_form/i18n.js b/app/javascript/submission_form/i18n.js index 71f73125..1da0bd06 100644 --- a/app/javascript/submission_form/i18n.js +++ b/app/javascript/submission_form/i18n.js @@ -107,6 +107,7 @@ const en = { email_has_been_sent: 'Email has been sent', processing: 'Processing', pay_with_stripe: 'Pay with Stripe', + pay_with_paypal: 'Pay with PayPal', reupload: 'Reupload', upload: 'Upload', files: 'Files', @@ -225,6 +226,7 @@ const es = { email_has_been_sent: 'El correo electrónico ha sido enviado', processing: 'Procesando', pay_with_stripe: 'Pagar con Stripe', + pay_with_paypal: 'Pagar con PayPal', reupload: 'Volver a subir', upload: 'Subir', files: 'Archivos', @@ -343,6 +345,7 @@ const it = { email_has_been_sent: "L'email è stata inviata", processing: 'Elaborazione', pay_with_stripe: 'Paga con Stripe', + pay_with_paypal: 'Paga con PayPal', reupload: 'Ricarica', upload: 'Carica', files: 'File', @@ -461,6 +464,7 @@ const de = { email_has_been_sent: 'E-Mail wurde gesendet', processing: 'Verarbeitung', pay_with_stripe: 'Mit Stripe bezahlen', + pay_with_paypal: 'Mit PayPal bezahlen', reupload: 'Erneut hochladen', upload: 'Hochladen', files: 'Dateien', @@ -579,6 +583,7 @@ const fr = { email_has_been_sent: "L'e-mail a été envoyé", processing: 'Traitement en cours', pay_with_stripe: 'Payer avec Stripe', + pay_with_paypal: 'Payer avec PayPal', reupload: 'Retéléverser', upload: 'Téléverser', files: 'Fichiers', @@ -697,6 +702,7 @@ const pl = { email_has_been_sent: 'E-mail został wysłany', processing: 'Przetwarzanie', pay_with_stripe: 'Zapłać za pomocą Stripe', + pay_with_paypal: 'Zapłać za pomocą PayPal', reupload: 'Ponowne przesłanie', upload: 'Przesyłanie', files: 'Pliki', @@ -815,6 +821,7 @@ const uk = { email_has_been_sent: 'Електронний лист був відправлений', processing: 'Обробка', pay_with_stripe: 'Сплатити за допомогою Stripe', + pay_with_paypal: 'Сплатити за допомогою PayPal', reupload: 'Перезавантажити', upload: 'Завантажити', files: 'Файли', @@ -933,6 +940,7 @@ const cs = { email_has_been_sent: 'E-mail byl odeslán', processing: 'Zpracování', pay_with_stripe: 'Zaplatit přes Stripe', + pay_with_paypal: 'Zaplatit přes PayPal', reupload: 'Znovu nahrát', upload: 'Nahrát', files: 'Soubory', @@ -1051,6 +1059,7 @@ const pt = { email_has_been_sent: 'Email enviado', processing: 'Processamento', pay_with_stripe: 'Pagar com Stripe', + pay_with_paypal: 'Pagar com PayPal', reupload: 'Recarregar', upload: 'Carregar', files: 'Arquivos', @@ -1169,6 +1178,7 @@ const he = { email_has_been_sent: 'האימייל נשלח', processing: 'מעבד', pay_with_stripe: 'שלם עם סטרייפ', + pay_with_paypal: 'שלם עם פייפאל', reupload: 'העלה שוב', upload: 'העלאה', files: 'קבצים', @@ -1287,6 +1297,7 @@ const nl = { email_has_been_sent: 'E-mail is verzonden', processing: 'Verwerken', pay_with_stripe: 'Betalen met Stripe', + pay_with_paypal: 'Betalen met PayPal', reupload: 'Opnieuw uploaden', upload: 'Uploaden', files: 'Bestanden', @@ -1405,6 +1416,7 @@ const ar = { email_has_been_sent: 'تم إرسال البريد الإلكتروني', processing: 'جارٍ المعالجة', pay_with_stripe: 'الدفع بواسطة Stripe', + pay_with_paypal: 'الدفع بواسطة PayPal', reupload: 'إعادة التحميل', upload: 'تحميل', files: 'الملفات', @@ -1523,6 +1535,7 @@ const ko = { email_has_been_sent: '이메일이 전송되었습니다', processing: '처리 중', pay_with_stripe: '스트라이프로 결제', + pay_with_paypal: 'PayPal로 결제', reupload: '다시 업로드', upload: '업로드', files: '파일', @@ -1641,6 +1654,7 @@ const ja = { email_has_been_sent: 'メールが送信されました', processing: '処理中', pay_with_stripe: 'Stripeで支払う', + pay_with_paypal: 'PayPalで支払う', reupload: '再アップロード', upload: 'アップロード', files: 'ファイル', diff --git a/app/javascript/submission_form/payment_step.vue b/app/javascript/submission_form/payment_step.vue index e1afbf40..f1ebabcc 100644 --- a/app/javascript/submission_form/payment_step.vue +++ b/app/javascript/submission_form/payment_step.vue @@ -1,6 +1,6 @@