Merge from docusealco/wip
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class PwaController < ActionController::Base
|
||||
end
|
||||
@@ -31,7 +31,7 @@
|
||||
:with-label="withLabel && !withFieldPlaceholder && step.length < 2"
|
||||
:is-value-set="step.some((f) => f.uuid in values)"
|
||||
:attachments-index="attachmentsIndex"
|
||||
@click="$emit('focus-step', stepIndex)"
|
||||
@click="[$emit('focus-step', stepIndex), maybeScrollOnClick(field, area)]"
|
||||
/>
|
||||
</Teleport>
|
||||
</template>
|
||||
@@ -109,6 +109,14 @@ export default {
|
||||
areaRefs: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isMobileContainer () {
|
||||
const root = this.$root.$el.parentNode.getRootNode()
|
||||
const container = root.body || root.querySelector('div')
|
||||
|
||||
return container.style.overflow === 'hidden'
|
||||
}
|
||||
},
|
||||
beforeUpdate () {
|
||||
this.areaRefs = []
|
||||
},
|
||||
@@ -121,14 +129,16 @@ export default {
|
||||
this.scrollIntoArea(field.areas[0])
|
||||
}
|
||||
},
|
||||
maybeScrollOnClick (field, area) {
|
||||
if (['text', 'number', 'cells'].includes(field.type) && this.isMobileContainer) {
|
||||
this.scrollIntoArea(area)
|
||||
}
|
||||
},
|
||||
scrollIntoArea (area) {
|
||||
const areaRef = this.areaRefs.find((a) => a.area === area)
|
||||
|
||||
if (areaRef) {
|
||||
const root = this.$root.$el.parentNode.getRootNode()
|
||||
const container = root.body || root.querySelector('div')
|
||||
|
||||
if (container.style.overflow === 'hidden') {
|
||||
if (this.isMobileContainer) {
|
||||
this.scrollInContainer(areaRef.$el)
|
||||
} else {
|
||||
const targetRect = areaRef.$refs.scrollToElem.getBoundingClientRect()
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<MarkdownContent :string="field.description" />
|
||||
</div>
|
||||
<FileDropzone
|
||||
:message="`${t('upload')} ${field.name || t('files')}${field.required ? '' : ` (${t('optional')})`}`"
|
||||
:message="`${t('upload')} ${(field.title || field.name) || t('files')}${field.required ? '' : ` (${t('optional')})`}`"
|
||||
:submitter-slug="submitterSlug"
|
||||
:multiple="true"
|
||||
:dry-run="dryRun"
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
<template>
|
||||
<div dir="auto">
|
||||
<div
|
||||
class="flex justify-between items-center w-full"
|
||||
class="flex justify-between items-end w-full mb-3.5 sm:mb-4"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
>
|
||||
<label
|
||||
v-if="showFieldNames"
|
||||
:for="field.uuid"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0"
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>
|
||||
{{ field.name && showFieldNames ? field.name : t('date') }}
|
||||
<template v-if="!field.required">
|
||||
{{ field.name || t('date') }}
|
||||
</template>
|
||||
<template v-if="!field.required">
|
||||
<span
|
||||
class="ml-1"
|
||||
:class="{ 'hidden sm:inline': (field.title || field.name || t('date') ).length > 10 }"
|
||||
>
|
||||
({{ t('optional') }})
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
</label>
|
||||
<button
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
v-if="showFieldNames && (currentField.name || currentField.title)"
|
||||
:for="currentField.uuid"
|
||||
dir="auto"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
:class="{ 'mb-2': !currentField.description }"
|
||||
>
|
||||
<MarkdownContent
|
||||
@@ -173,7 +173,11 @@
|
||||
/>
|
||||
<template v-else>
|
||||
{{ currentField.name }}
|
||||
<template v-if="!currentField.required">({{ t('optional') }})</template>
|
||||
</template>
|
||||
<template v-if="!currentField.required">
|
||||
<span :class="{ 'hidden sm:inline': (currentField.title || currentField.name).length > 20 }">
|
||||
({{ t('optional') }})
|
||||
</span>
|
||||
</template>
|
||||
</label>
|
||||
<div
|
||||
@@ -221,7 +225,7 @@
|
||||
v-if="showFieldNames && (currentField.name || currentField.title)"
|
||||
:for="currentField.uuid"
|
||||
dir="auto"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
:class="{ 'mb-2': !currentField.description }"
|
||||
>
|
||||
<MarkdownContent
|
||||
@@ -230,7 +234,11 @@
|
||||
/>
|
||||
<template v-else>
|
||||
{{ currentField.name }}
|
||||
<template v-if="!currentField.required">({{ t('optional') }})</template>
|
||||
</template>
|
||||
<template v-if="!currentField.required">
|
||||
<span :class="{ 'hidden sm:inline': (currentField.title || currentField.name).length > 20 }">
|
||||
({{ t('optional') }})
|
||||
</span>
|
||||
</template>
|
||||
</label>
|
||||
<div
|
||||
@@ -466,7 +474,7 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="(currentField.type !== 'payment' && currentField.type !== 'verification') || submittedValues[currentField.uuid]"
|
||||
:class="currentField.type === 'signature' ? 'mt-2' : 'mt-6 md:mt-8'"
|
||||
:class="currentField.type === 'signature' ? 'mt-2' : 'mt-4 md:mt-6'"
|
||||
>
|
||||
<button
|
||||
id="submit_form_button"
|
||||
@@ -522,9 +530,9 @@
|
||||
/>
|
||||
<div
|
||||
v-if="stepFields.length < 80"
|
||||
class="flex justify-center"
|
||||
class="flex justify-center mt-3 sm:mt-4 mb-0 sm:mb-1"
|
||||
>
|
||||
<div class="flex items-center mt-4 mb-1 flex-wrap">
|
||||
<div class="flex items-center flex-wrap">
|
||||
<a
|
||||
v-for="(step, index) in stepFields"
|
||||
:key="step[0].uuid"
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
<template>
|
||||
<div v-if="modelValue">
|
||||
<div class="flex justify-between items-center w-full mb-2">
|
||||
<div class="flex justify-between items-end w-full mb-3.5 md:mb-4">
|
||||
<label
|
||||
class="label text-2xl"
|
||||
>{{ showFieldNames && field.name ? field.name : t('image') }}</label>
|
||||
v-if="showFieldNames"
|
||||
:for="field.uuid"
|
||||
class="label text-xl sm:text-2xl py-0"
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>
|
||||
{{ field.name || t('image') }}
|
||||
</template>
|
||||
</label>
|
||||
<button
|
||||
class="btn btn-outline btn-sm"
|
||||
@click.prevent="remove"
|
||||
@@ -35,7 +45,7 @@
|
||||
<MarkdownContent :string="field.description" />
|
||||
</div>
|
||||
<FileDropzone
|
||||
:message="`${t('upload')} ${field.name || t('image')}${field.required ? '' : ` (${t('optional')})`}`"
|
||||
:message="`${t('upload')} ${(field.title || field.name) || t('image')}${field.required ? '' : ` (${t('optional')})`}`"
|
||||
:submitter-slug="submitterSlug"
|
||||
:dry-run="dryRun"
|
||||
:accept="'image/*'"
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
<template>
|
||||
<div dir="auto">
|
||||
<div
|
||||
class="flex justify-between items-center w-full"
|
||||
class="flex justify-between items-end w-full mb-3.5 md:mb-4"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
>
|
||||
<label
|
||||
class="label text-2xl"
|
||||
v-if="showFieldNames"
|
||||
class="label text-xl sm:text-2xl py-0"
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>
|
||||
{{ showFieldNames && field.name ? field.name : t('initials') }}
|
||||
{{ field.name || t('initials') }}
|
||||
</template>
|
||||
</label>
|
||||
<div class="space-x-2 flex">
|
||||
<div class="space-x-2 flex flex-none">
|
||||
<span
|
||||
v-if="isDrawInitials"
|
||||
class="tooltip"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="mt-6 md:mt-8"
|
||||
class="mt-4 md:mt-6"
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
|
||||
@@ -3,13 +3,19 @@
|
||||
v-if="showFieldNames && (field.name || field.title)"
|
||||
:for="field.uuid"
|
||||
dir="auto"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
><MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>{{ field.name }}</template>
|
||||
<template v-if="!field.required">
|
||||
<span :class="{ 'hidden sm:inline': (field.title || field.name).length > 20 }">
|
||||
({{ t('optional') }})
|
||||
</span>
|
||||
</template>
|
||||
</label>
|
||||
<div
|
||||
v-if="field.description"
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
v-if="showFieldNames && (field.name || field.title)"
|
||||
:for="field.uuid"
|
||||
dir="auto"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
><MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>{{ field.name }}</template>
|
||||
<template v-if="!field.required">
|
||||
({{ t('optional') }})
|
||||
<span :class="{ 'hidden sm:inline': (field.title || field.name).length > 20 }">
|
||||
({{ t('optional') }})
|
||||
</span>
|
||||
</template>
|
||||
</label>
|
||||
<div
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<label
|
||||
v-if="!modelValue && !sessionId"
|
||||
class="label text-2xl mb-2"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<label
|
||||
v-if="showFieldNames"
|
||||
:for="isCodeSent ? 'one_time_code' : field.uuid"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
>
|
||||
<MarkdownContent
|
||||
@@ -10,10 +11,7 @@
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>
|
||||
{{ showFieldNames && field.name ? field.name : t('verified_phone_number') }}
|
||||
<template v-if="!field.required">
|
||||
({{ t('optional') }})
|
||||
</template>
|
||||
{{ field.name || t('verified_phone_number') }}
|
||||
</template>
|
||||
</label>
|
||||
<div
|
||||
|
||||
@@ -4,21 +4,22 @@
|
||||
class="relative"
|
||||
>
|
||||
<div
|
||||
class="flex justify-between items-center w-full"
|
||||
class="flex justify-between items-end w-full mb-3.5 md:mb-4"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
>
|
||||
<label
|
||||
class="label text-2xl"
|
||||
v-if="showFieldNames"
|
||||
class="label text-xl sm:text-2xl py-0"
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>
|
||||
{{ showFieldNames && field.name ? field.name : t('signature') }}
|
||||
{{ field.name || t('signature') }}
|
||||
</template>
|
||||
</label>
|
||||
<div class="space-x-2 flex">
|
||||
<div class="space-x-2 flex flex-none">
|
||||
<span
|
||||
v-if="isTextSignature && format !== 'typed' && format !== 'upload'"
|
||||
class="tooltip"
|
||||
@@ -39,6 +40,7 @@
|
||||
<span
|
||||
v-else-if="withTypedSignature && format !== 'typed' && format !== 'drawn' && format !== 'upload'"
|
||||
class="tooltip ml-2"
|
||||
:class="{ 'hidden sm:inline': modelValue || computedPreviousValue }"
|
||||
:data-tip="t('type_text')"
|
||||
>
|
||||
<a
|
||||
@@ -56,6 +58,7 @@
|
||||
<span
|
||||
v-if="format !== 'typed' && format !== 'drawn' && format !== 'upload' && format !== 'drawn_or_typed'"
|
||||
class="tooltip"
|
||||
:class="{ 'hidden sm:inline': modelValue || computedPreviousValue }"
|
||||
:data-tip="t('take_photo')"
|
||||
>
|
||||
<label
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
v-if="showFieldNames && (field.name || field.title)"
|
||||
:for="field.uuid"
|
||||
dir="auto"
|
||||
class="label text-2xl"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
:class="{ 'mb-2': !field.description }"
|
||||
><MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
:string="field.title"
|
||||
/>
|
||||
<template v-else>{{ field.name }}</template>
|
||||
<template v-if="!field.required">
|
||||
({{ t('optional') }})
|
||||
<span :class="{ 'hidden sm:inline': (field.title || field.name).length > 20 }">
|
||||
({{ t('optional') }})
|
||||
</span>
|
||||
</template>
|
||||
</label>
|
||||
<div
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<label
|
||||
class="label text-2xl mb-2"
|
||||
class="label text-xl sm:text-2xl py-0 mb-2 sm:mb-3.5"
|
||||
>
|
||||
<MarkdownContent
|
||||
v-if="field.title"
|
||||
@@ -31,6 +31,15 @@
|
||||
class="animate-spin h-10"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="redirectUrl">
|
||||
<a
|
||||
:href="redirectUrl"
|
||||
target="_blank"
|
||||
class="white-button w-full"
|
||||
>
|
||||
{{ t('verify_id') }}
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
ref="widgetContainer"
|
||||
/>
|
||||
@@ -87,6 +96,7 @@ export default {
|
||||
return {
|
||||
isCreatingCheckout: false,
|
||||
isMathLoaded: false,
|
||||
redirectUrl: '',
|
||||
isLoading: false,
|
||||
eidEasyData: {}
|
||||
}
|
||||
@@ -147,14 +157,26 @@ export default {
|
||||
}).then(async (resp) => {
|
||||
this.eidEasyData = await resp.json()
|
||||
|
||||
const eidEasyWidget = document.createElement('eideasy-widget')
|
||||
if (this.eidEasyData.available_methods[0] === 'itsme-qes-signature' &&
|
||||
this.eidEasyData.available_methods.length === 1) {
|
||||
const redirectUrl = new URL('https://id.eideasy.com/sign_contract_external')
|
||||
|
||||
for (const key in this.widgetSettings) {
|
||||
eidEasyWidget[key] = this.widgetSettings[key]
|
||||
redirectUrl.searchParams.append('client_id', this.eidEasyData.client_id)
|
||||
redirectUrl.searchParams.append('doc_id', this.eidEasyData.doc_id)
|
||||
redirectUrl.searchParams.append('country', this.countryCode)
|
||||
redirectUrl.searchParams.append('lang', this.locale)
|
||||
|
||||
this.redirectUrl = redirectUrl.toString()
|
||||
} else {
|
||||
const eidEasyWidget = document.createElement('eideasy-widget')
|
||||
|
||||
for (const key in this.widgetSettings) {
|
||||
eidEasyWidget[key] = this.widgetSettings[key]
|
||||
}
|
||||
|
||||
this.$refs.widgetContainer.innerHTML = ''
|
||||
this.$refs.widgetContainer.appendChild(eidEasyWidget)
|
||||
}
|
||||
|
||||
this.$refs.widgetContainer.innerHTML = ''
|
||||
this.$refs.widgetContainer.appendChild(eidEasyWidget)
|
||||
})
|
||||
},
|
||||
async submit () {
|
||||
|
||||
@@ -366,6 +366,7 @@
|
||||
:with-help="withHelp"
|
||||
:default-submitters="defaultSubmitters"
|
||||
:draw-field-type="drawFieldType"
|
||||
:with-fields-search="withFieldsSearch"
|
||||
:default-fields="[...defaultRequiredFields, ...defaultFields]"
|
||||
:template="template"
|
||||
:default-required-fields="defaultRequiredFields"
|
||||
@@ -623,6 +624,11 @@ export default {
|
||||
required: false,
|
||||
default: true
|
||||
},
|
||||
withFieldsSearch: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
withFieldsList: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
|
||||
@@ -177,7 +177,7 @@ export default {
|
||||
fields () {
|
||||
if (this.item.submitter_uuid) {
|
||||
return this.template.fields.reduce((acc, f) => {
|
||||
if (f !== this.item && f.submitter_uuid === this.item.submitter_uuid) {
|
||||
if (f !== this.item) {
|
||||
acc.push(f)
|
||||
}
|
||||
|
||||
|
||||
@@ -229,6 +229,11 @@ export default {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
withFieldsSearch: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
template: {
|
||||
type: Object,
|
||||
required: true
|
||||
@@ -297,7 +302,11 @@ export default {
|
||||
fieldNames: FieldType.computed.fieldNames,
|
||||
fieldIcons: FieldType.computed.fieldIcons,
|
||||
isShowFieldSearch () {
|
||||
return this.submitterDefaultFields.length > 15
|
||||
if (this.withFieldsSearch === false) {
|
||||
return false
|
||||
} else {
|
||||
return this.submitterDefaultFields.length > 15
|
||||
}
|
||||
},
|
||||
defaultFieldsIndex () {
|
||||
return this.defaultFields.reduce((acc, field) => {
|
||||
|
||||
@@ -8,6 +8,12 @@ class SendSubmitterInvitationEmailJob
|
||||
|
||||
return if submitter.submission.source == 'invite' && !Accounts.can_send_emails?(submitter.account, on_events: true)
|
||||
|
||||
unless Accounts.can_send_invitation_emails?(submitter.account)
|
||||
Rollbar.warning("Skip email: #{submitter.account.id}") if defined?(Rollbar)
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
mail = SubmitterMailer.invitation_email(submitter)
|
||||
|
||||
Submitters::ValidateSending.call(submitter, mail)
|
||||
@@ -17,6 +23,6 @@ class SendSubmitterInvitationEmailJob
|
||||
SubmissionEvent.create!(submitter:, event_type: 'send_email')
|
||||
|
||||
submitter.sent_at ||= Time.current
|
||||
submitter.save
|
||||
submitter.save!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
<html data-theme="docuseal" lang="<%= I18n.locale %>">
|
||||
<head>
|
||||
<%= render 'layouts/head_tags' %>
|
||||
<% if Docuseal.enable_pwa? %>
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
<% end %>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<%= csrf_meta_tags %>
|
||||
<%= csp_meta_tag %>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "<%= Docuseal.product_name %>",
|
||||
"short_name": "<%= Docuseal.product_name %>",
|
||||
"id": "/",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/logo.svg",
|
||||
"type": "image/svg+xml",
|
||||
"sizes": "any"
|
||||
},
|
||||
{
|
||||
"src": "/apple-touch-icon.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"scope": "/",
|
||||
"orientation": "natural",
|
||||
"description": "<%= Docuseal.product_name %> is an open source platform that provides secure and efficient digital document signing and processing.",
|
||||
"categories": ["productivity", "utilities"],
|
||||
"theme_color": "#FAF7F4",
|
||||
"background_color": "#FAF7F4"
|
||||
}
|
||||
@@ -2,5 +2,9 @@
|
||||
---
|
||||
</p>
|
||||
<p>
|
||||
<%= t('sent_using_product_name_free_document_signing_html', product_url: "#{Docuseal::PRODUCT_EMAIL_URL}/start", product_name: Docuseal.product_name) %>
|
||||
<% if @current_account&.testing? %>
|
||||
<%= t('sent_using_product_name_in_testing_mode_html', product_url: "#{Docuseal::PRODUCT_EMAIL_URL}/start", product_name: Docuseal.product_name) %>
|
||||
<% else %>
|
||||
<%= t('sent_using_product_name_free_document_signing_html', product_url: "#{Docuseal::PRODUCT_EMAIL_URL}/start", product_name: Docuseal.product_name) %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<% data_attachments = attachments_index.values.select { |e| e.record_id == submitter.id }.to_json(only: %i[uuid created_at], methods: %i[url filename content_type]) %>
|
||||
<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %>
|
||||
<% data_fields = Submissions.filtered_conditions_fields(submitter).to_json %>
|
||||
<% invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %>
|
||||
<% optional_invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['optional_invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %>
|
||||
<submission-form data-is-demo="<%= Docuseal.demo? %>" data-schema="<%= schema.to_json %>" data-reuse-signature="<%= configs[:reuse_signature] %>" data-require-signing-reason="<%= configs[:require_signing_reason] %>" data-with-signature-id="<%= configs[:with_signature_id] %>" data-with-confetti="<%= configs[:with_confetti] %>" data-completed-redirect-url="<%= submitter.preferences['completed_redirect_url'].presence || submitter.submission.template.preferences['completed_redirect_url'] %>" data-completed-message="<%= (configs[:completed_message]&.compact_blank.presence || submitter.submission.template.preferences['completed_message'] || {}).to_json %>" data-completed-button="<%= configs[:completed_button].to_json %>" data-go-to-last="<%= submitter.preferences.key?('go_to_last') ? submitter.preferences['go_to_last'] : submitter.opened_at? %>" data-submitter="<%= submitter.to_json(only: %i[uuid slug name phone email]) %>" data-can-send-email="<%= Accounts.can_send_emails?(submitter.submission.account) %>" data-optional-invite-submitters="<%= optional_invite_submitters %>" data-invite-submitters="<%= invite_submitters %>" data-attachments="<%= data_attachments %>" data-fields="<%= data_fields %>" data-values="<%= submitter.values.to_json %>" data-with-typed-signature="<%= configs[:with_typed_signature] %>" data-previous-signature-value="<%= local_assigns[:signature_attachment]&.uuid %>" data-remember-signature="<%= configs[:prefill_signature] %>" data-dry-run="<%= local_assigns[:dry_run] %>" data-expand="<%= local_assigns[:expand] %>" data-scroll-padding="<%= local_assigns[:scroll_padding] %>" data-language="<%= I18n.locale.to_s.split('-').first %>"></submission-form>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<% if Docuseal.demo? %><%= render 'shared/demo_alert' %><% end %>
|
||||
<div class="flex justify-between items-center w-full mb-4">
|
||||
<div class="flex items-center flex-grow min-w-0">
|
||||
<% if has_archived || @pagy.count > 0 %>
|
||||
<% if has_archived || @pagy.count > 0 || @template_folders.present? %>
|
||||
<div class="mr-2">
|
||||
<%= render 'dashboard/toggle_view', selected: 'templates' %>
|
||||
</div>
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<%= user.last_sign_in_at ? l(user.last_sign_in_at.in_time_zone(current_account.timezone), format: :short, locale: current_account.locale) : '-' %>
|
||||
<%= user.current_sign_in_at ? l(user.current_sign_in_at.in_time_zone(current_account.timezone), format: :short, locale: current_account.locale) : '-' %>
|
||||
</td>
|
||||
<td class="flex items-center space-x-2 justify-end">
|
||||
<% if params[:status].blank? && can?(:update, user) && user.archived_at.blank? %>
|
||||
|
||||
@@ -42,6 +42,7 @@ en: &en
|
||||
hello_name: Hello %{name}
|
||||
you_are_invited_to_product_name: You are invited to %{product_name}
|
||||
you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_: 'You have been invited to %{account_name} %{product_name}. Please sign up using the link below:'
|
||||
sent_using_product_name_in_testing_mode_html: 'Sent using <a href="%{product_url}">%{product_name}</a> in testing mode'
|
||||
sent_using_product_name_free_document_signing_html: 'Sent using <a href="%{product_url}">%{product_name}</a> free document signing.'
|
||||
sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature: Sign documents with trusted certificate provided by DocuSeal. Your documents and data are never shared with DocuSeal. PDF checksum is provided to generate a trusted signature.
|
||||
you_have_been_invited_to_submit_the_name_form: 'You have been invited to submit the "%{name}" form.'
|
||||
@@ -690,6 +691,9 @@ en: &en
|
||||
extremely_satisfied: Extremely Satisfied
|
||||
your_pro_plan_payment_is_overdue: Your Pro plan payment is overdue.
|
||||
click_here_to_update_your_payment_details_and_clear_the_invoice_to_ensure_uninterrupted_service_html: <a href="%{url}" class="link">Click here</a> to update your payment details and clear the invoice to ensure uninterrupted service.
|
||||
overdue_payment: Overdue Payment
|
||||
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Your Pro Plan has been suspended due to unpaid invoices. You can update your payment details to settle the invoice and continue using DocuSeal or cancel your subscription.
|
||||
manage_subscription: Manage Subscription
|
||||
submission_event_names:
|
||||
send_email_to_html: '<b>Email sent</b> to %{submitter_name}'
|
||||
send_reminder_email_to_html: '<b>Reminder email sent</b> to %{submitter_name}'
|
||||
@@ -752,6 +756,7 @@ es: &es
|
||||
hello_name: Hola %{name}
|
||||
you_are_invited_to_product_name: Estás invitado a %{product_name}
|
||||
you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_: 'Has sido invitado a %{account_name} %{product_name}. Por favor, regístrate usando el enlace a continuación:'
|
||||
sent_using_product_name_in_testing_mode_html: 'Enviado usando <a href="%{product_url}">%{product_name}</a> en Modo de Prueba'
|
||||
sent_using_product_name_free_document_signing_html: 'Enviado usando la firma de documentos gratuita de <a href="%{product_url}">%{product_name}</a>.'
|
||||
sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature: Firme documentos con un certificado de confianza proporcionado por DocuSeal. Sus documentos y datos nunca se comparten con DocuSeal. Se proporciona un checksum de PDF para generar una firma de confianza.
|
||||
hi_there: Hola
|
||||
@@ -1400,6 +1405,9 @@ es: &es
|
||||
extremely_satisfied: Extremadamente satisfecho
|
||||
your_pro_plan_payment_is_overdue: El pago de tu plan Pro está atrasado.
|
||||
click_here_to_update_your_payment_details_and_clear_the_invoice_to_ensure_uninterrupted_service_html: '<a href="%{url}" class="link">Haz clic aquí</a> para actualizar tus datos de pago y liquidar la factura para garantizar un servicio ininterrumpido.'
|
||||
overdue_payment: Pago Atrasado
|
||||
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Tu plan Pro ha sido suspendido debido a facturas impagas. Puedes actualizar tus datos de pago para liquidar la factura y seguir usando DocuSeal o cancelar tu suscripción.
|
||||
manage_subscription: Gestionar Suscripción
|
||||
submission_event_names:
|
||||
send_email_to_html: '<b>Correo electrónico enviado</b> a %{submitter_name}'
|
||||
send_reminder_email_to_html: '<b>Correo de recordatorio enviado</b> a %{submitter_name}'
|
||||
@@ -1461,6 +1469,7 @@ it: &it
|
||||
hello_name: Ciao %{name}
|
||||
you_are_invited_to_product_name: Sei stato invitato a %{product_name}
|
||||
you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_: 'Sei stato invitato a %{account_name} %{product_name}. Registrati utilizzando il link qui sotto:'
|
||||
sent_using_product_name_in_testing_mode_html: 'Inviato utilizzando <a href="%{product_url}">%{product_name}</a> in Modalità di Test'
|
||||
sent_using_product_name_free_document_signing_html: 'Inviato utilizzando la firma di documenti gratuita di <a href="%{product_url}">%{product_name}</a>.'
|
||||
sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature: "Firma documenti con un certificato di fiducia fornito da DocuSeal. I tuoi documenti e i tuoi dati non vengono mai condivisi con DocuSeal. Il checksum PDF è fornito per generare una firma di fiducia."
|
||||
hi_there: Ciao
|
||||
@@ -2109,6 +2118,9 @@ it: &it
|
||||
extremely_satisfied: Estremamente soddisfatto
|
||||
your_pro_plan_payment_is_overdue: Il pagamento del tuo piano Pro è in ritardo.
|
||||
click_here_to_update_your_payment_details_and_clear_the_invoice_to_ensure_uninterrupted_service_html: '<a href="%{url}" class="link">Fai clic qui</a> per aggiornare i tuoi dati di pagamento e saldare la fattura per garantire un servizio ininterrotto.'
|
||||
overdue_payment: Pagamento Scaduto
|
||||
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Il tuo piano Pro è stato sospeso a causa di fatture non pagate. Puoi aggiornare i tuoi dati di pagamento per saldare la fattura e continuare a utilizzare DocuSeal o annullare l'abbonamento.
|
||||
manage_subscription: Gestisci Abbonamento
|
||||
submission_event_names:
|
||||
send_email_to_html: '<b>E-mail inviato</b> a %{submitter_name}'
|
||||
send_reminder_email_to_html: '<b>E-mail di promemoria inviato</b> a %{submitter_name}'
|
||||
@@ -2171,6 +2183,7 @@ fr: &fr
|
||||
hello_name: Bonjour %{name}
|
||||
you_are_invited_to_product_name: Vous êtes invité à %{product_name}
|
||||
you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_: 'Vous avez été invité à %{account_name} %{product_name}. Veuillez vous inscrire en utilisant le lien ci-dessous:'
|
||||
sent_using_product_name_in_testing_mode_html: 'Envoyé en utilisant <a href="%{product_url}">%{product_name}</a> en Mode Test'
|
||||
sent_using_product_name_free_document_signing_html: 'Envoyé en utilisant la signature de documents gratuite de <a href="%{product_url}">%{product_name}</a>.'
|
||||
sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature: Signez des documents avec un certificat de confiance fourni par DocuSeal. Vos documents et données ne sont jamais partagés avec DocuSeal. Un checksum PDF est fourni pour générer une signature de confiance.
|
||||
hi_there: Bonjour
|
||||
@@ -2820,6 +2833,9 @@ fr: &fr
|
||||
extremely_satisfied: Extrêmement satisfait
|
||||
your_pro_plan_payment_is_overdue: Le paiement de votre plan Pro est en retard.
|
||||
click_here_to_update_your_payment_details_and_clear_the_invoice_to_ensure_uninterrupted_service_html: '<a href="%{url}" class="link">Cliquez ici</a> pour mettre à jour vos informations de paiement et régler la facture afin de garantir un service ininterrompu.'
|
||||
overdue_payment: Paiement En Retard
|
||||
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Votre plan Pro a été suspendu en raison de factures impayées. Vous pouvez mettre à jour vos informations de paiement pour régler la facture et continuer à utiliser DocuSeal ou annuler votre abonnement.
|
||||
manage_subscription: Gérer l'Abonnement
|
||||
submission_event_names:
|
||||
send_email_to_html: '<b>E-mail envoyé</b> à %{submitter_name}'
|
||||
send_reminder_email_to_html: '<b>E-mail de rappel envoyé</b> à %{submitter_name}'
|
||||
@@ -2882,6 +2898,7 @@ pt: &pt
|
||||
hello_name: Olá %{name}
|
||||
you_are_invited_to_product_name: Você está convidado para %{product_name}
|
||||
you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_: 'Você foi convidado para %{account_name} %{product_name}. Inscreva-se usando o link abaixo:'
|
||||
sent_using_product_name_in_testing_mode_html: 'Enviado usando <a href="%{product_url}">%{product_name}</a> no Modo de Teste'
|
||||
sent_using_product_name_free_document_signing_html: 'Enviado usando a assinatura gratuita de documentos de <a href="%{product_url}">%{product_name}</a>.'
|
||||
sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature: Assine documentos com certificado confiável fornecido pela DocuSeal. Seus documentos e dados nunca são compartilhados com a DocuSeal. O checksum do PDF é fornecido para gerar uma assinatura confiável.
|
||||
hi_there: Olá
|
||||
@@ -3530,6 +3547,9 @@ pt: &pt
|
||||
extremely_satisfied: Extremamente satisfeito
|
||||
your_pro_plan_payment_is_overdue: O pagamento do seu plano Pro está atrasado.
|
||||
click_here_to_update_your_payment_details_and_clear_the_invoice_to_ensure_uninterrupted_service_html: '<a href="%{url}" class="link">Clique aqui</a> para atualizar seus dados de pagamento e quitar a fatura para garantir um serviço ininterrupto.'
|
||||
overdue_payment: Pagamento Atrasado
|
||||
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Seu plano Pro foi suspenso devido a faturas não pagas. Você pode atualizar seus dados de pagamento para quitar a fatura e continuar usando o DocuSeal ou cancelar sua assinatura.
|
||||
manage_subscription: Gerenciar Assinatura
|
||||
submission_event_names:
|
||||
send_email_to_html: '<b>E-mail enviado</b> para %{submitter_name}'
|
||||
send_reminder_email_to_html: '<b>E-mail de lembrete enviado</b> para %{submitter_name}'
|
||||
@@ -3592,6 +3612,7 @@ de: &de
|
||||
hello_name: Hallo %{name}
|
||||
you_are_invited_to_product_name: Sie sind eingeladen zu %{product_name}
|
||||
you_have_been_invited_to_account_name_product_name_please_sign_up_using_the_link_below_: 'Sie wurden zu %{account_name} %{product_name} eingeladen. Bitte registrieren Sie sich über den folgenden Link:'
|
||||
sent_using_product_name_in_testing_mode_html: 'Gesendet über <a href="%{product_url}">%{product_name}</a> im Testmodus'
|
||||
sent_using_product_name_free_document_signing_html: 'Gesendet mit der kostenlosen Dokumentensignierung von <a href="%{product_url}">%{product_name}</a>.'
|
||||
sign_documents_with_trusted_certificate_provided_by_docu_seal_your_documents_and_data_are_never_shared_with_docu_seal_p_d_f_checksum_is_provided_to_generate_a_trusted_signature: Unterzeichnen Sie Dokumente mit einem vertrauenswürdigen Zertifikat von DocuSeal. Ihre Dokumente und Daten werden niemals mit DocuSeal geteilt. Eine PDF-Prüfziffer wird bereitgestellt, um eine vertrauenswürdige Signatur zu generieren.
|
||||
hi_there: Hallo
|
||||
@@ -4240,6 +4261,9 @@ de: &de
|
||||
extremely_satisfied: Extrem zufrieden
|
||||
your_pro_plan_payment_is_overdue: Ihre Zahlung für den Pro-Plan ist überfällig.
|
||||
click_here_to_update_your_payment_details_and_clear_the_invoice_to_ensure_uninterrupted_service_html: '<a href="%{url}" class="link">Klicken Sie hier</a>, um Ihre Zahlungsdaten zu aktualisieren und die Rechnung zu begleichen, um einen unterbrechungsfreien Service sicherzustellen.'
|
||||
overdue_payment: Überfällige Zahlung
|
||||
your_pro_plan_has_been_suspended_due_to_unpaid_invoices_you_can_update_your_payment_details_to_settle_the_invoice_and_continue_using_docuseal_or_cancel_your_subscription: Ihr Pro-Plan wurde aufgrund unbezahlter Rechnungen ausgesetzt. Sie können Ihre Zahlungsdaten aktualisieren, um die Rechnung zu begleichen und DocuSeal weiterhin zu nutzen, oder Ihr Abonnement kündigen.
|
||||
manage_subscription: Abonnement Verwalten
|
||||
submission_event_names:
|
||||
send_email_to_html: '<b>E-Mail gesendet</b> an %{submitter_name}'
|
||||
send_reminder_email_to_html: '<b>Erinnerungs-E-Mail gesendet</b> an %{submitter_name}'
|
||||
|
||||
@@ -12,6 +12,7 @@ Rails.application.routes.draw do
|
||||
root 'dashboard#index'
|
||||
|
||||
get 'up' => 'rails/health#show'
|
||||
get 'manifest' => 'pwa#manifest'
|
||||
|
||||
devise_for :users,
|
||||
path: '/', only: %i[sessions passwords omniauth_callbacks],
|
||||
|
||||
@@ -25,7 +25,7 @@ module Abilities
|
||||
account_ids = [user.account_id, TemplateSharing::ALL_ID]
|
||||
|
||||
template.template_sharings.any? do |e|
|
||||
e.account_id.in?(account_ids) && (ability.nil? || e.ability == ability)
|
||||
e.account_id.in?(account_ids) && (ability.nil? || e.ability == 'manage' || e.ability == ability)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -153,6 +153,10 @@ module Accounts
|
||||
EncryptedConfig.exists?(key: EncryptedConfig::EMAIL_SMTP_KEY)
|
||||
end
|
||||
|
||||
def can_send_invitation_emails?(_account)
|
||||
true
|
||||
end
|
||||
|
||||
def normalize_timezone(timezone)
|
||||
tzinfo = TZInfo::Timezone.get(ActiveSupport::TimeZone::MAPPING[timezone] || timezone)
|
||||
|
||||
|
||||
@@ -69,6 +69,10 @@ module Docuseal
|
||||
@default_pkcs ||= GenerateCertificate.load_pkcs(Docuseal::CERTS)
|
||||
end
|
||||
|
||||
def enable_pwa?
|
||||
true
|
||||
end
|
||||
|
||||
def trusted_certs
|
||||
@trusted_certs ||=
|
||||
ENV['TRUSTED_CERTS'].to_s.gsub('\\n', "\n").split("\n\n").map do |base64|
|
||||
|
||||
+37
-11
@@ -142,31 +142,57 @@ module Submissions
|
||||
|
||||
values ||= submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) }
|
||||
|
||||
next unless check_document_conditions(item, values, fields_uuid_index, include_submitter_uuid:)
|
||||
next unless check_item_conditions(item, values, fields_uuid_index, include_submitter_uuid:)
|
||||
end
|
||||
|
||||
item
|
||||
end
|
||||
end
|
||||
|
||||
def check_document_conditions(item, values, fields_index, include_submitter_uuid: nil)
|
||||
def filtered_conditions_fields(submitter, only_submitter_fields: true)
|
||||
fields = submitter.submission.template_fields || submitter.submission.template.fields
|
||||
|
||||
fields_uuid_index = nil
|
||||
values = nil
|
||||
|
||||
fields.filter_map do |field|
|
||||
next if field['submitter_uuid'] != submitter.uuid && only_submitter_fields
|
||||
|
||||
if field['conditions'].present?
|
||||
fields_uuid_index ||= fields.index_by { |f| f['uuid'] }
|
||||
values ||= submitter.submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) }
|
||||
|
||||
submitter_conditions = []
|
||||
|
||||
next unless check_item_conditions(field, values, fields_uuid_index,
|
||||
include_submitter_uuid: submitter.uuid,
|
||||
submitter_conditions_acc: submitter_conditions)
|
||||
|
||||
field = field.merge('conditions' => submitter_conditions) if submitter_conditions != field['conditions']
|
||||
end
|
||||
|
||||
field
|
||||
end
|
||||
end
|
||||
|
||||
def check_item_conditions(item, values, fields_index, include_submitter_uuid: nil, submitter_conditions_acc: nil)
|
||||
return true if item['conditions'].blank?
|
||||
|
||||
item['conditions'].all? do |condition|
|
||||
item['conditions'].each_with_object([]) do |condition, acc|
|
||||
result =
|
||||
if fields_index[condition['field_uuid']]['submitter_uuid'] == include_submitter_uuid
|
||||
submitter_conditions_acc << condition if submitter_conditions_acc
|
||||
|
||||
true
|
||||
else
|
||||
Submitters::SubmitValues.check_field_condition(condition, values, fields_index)
|
||||
end
|
||||
|
||||
item['conditions'].each_with_object([]) do |c, acc|
|
||||
if c['operation'] == 'or'
|
||||
acc.push(acc.pop || result)
|
||||
else
|
||||
acc.push(result)
|
||||
end
|
||||
end.exclude?(false)
|
||||
end
|
||||
if condition['operation'] == 'or'
|
||||
acc.push(acc.pop || result)
|
||||
else
|
||||
acc.push(result)
|
||||
end
|
||||
end.exclude?(false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -186,10 +186,21 @@ module Submitters
|
||||
attachments_index =
|
||||
Submissions.filtered_conditions_schema(submitter.submission).index_by { |i| i['attachment_uuid'] }
|
||||
|
||||
submitter_values = nil
|
||||
is_other_submitter_conditions = submitter.submission.template_submitters.size > 1
|
||||
|
||||
submitter.submission.template_fields.each do |field|
|
||||
next if field['submitter_uuid'] != submitter.uuid
|
||||
|
||||
submitter.values.delete(field['uuid']) unless check_field_conditions(submitter, field, fields_uuid_index)
|
||||
submitter_values ||= submitter.values
|
||||
|
||||
is_other_submitter_conditions &&= field_conditions_other_submitter?(submitter, field, fields_uuid_index)
|
||||
|
||||
if is_other_submitter_conditions
|
||||
submitter_values = submitter.submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) }
|
||||
end
|
||||
|
||||
submitter.values.delete(field['uuid']) unless check_field_conditions(submitter_values, field, fields_uuid_index)
|
||||
|
||||
if field['areas'].present? && field['areas'].none? { |area| attachments_index[area['attachment_uuid']] }
|
||||
submitter.values.delete(field['uuid'])
|
||||
@@ -199,10 +210,14 @@ module Submitters
|
||||
submitter.values
|
||||
end
|
||||
|
||||
def check_field_conditions(submitter, field, fields_uuid_index)
|
||||
return true if field['conditions'].blank?
|
||||
def field_conditions_other_submitter?(submitter, field, fields_uuid_index)
|
||||
field['conditions'].to_a.any? do |c|
|
||||
fields_uuid_index.dig(c['field_uuid'], 'submitter_uuid') != submitter.uuid
|
||||
end
|
||||
end
|
||||
|
||||
submitter_values = submitter.values
|
||||
def check_field_conditions(submitter_values, field, fields_uuid_index)
|
||||
return true if field['conditions'].blank?
|
||||
|
||||
field['conditions'].each_with_object([]) do |c, acc|
|
||||
if c['operation'] == 'or'
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,11 @@
|
||||
self.addEventListener('install', () => {
|
||||
console.log('DocuSeal App installed')
|
||||
})
|
||||
|
||||
self.addEventListener('activate', () => {
|
||||
console.log('DocuSeal App activated')
|
||||
})
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
event.respondWith(fetch(event.request))
|
||||
})
|
||||
Reference in New Issue
Block a user