autosave builder changes

pull/105/head
Alex Turchyn 2 years ago
parent c9e255f589
commit a258ca6c79

@ -32,7 +32,8 @@ class SubmissionsController < ApplicationController
end
end
redirect_to template_submissions_path(@template), notice: "#{submissions.size} recepients added"
redirect_to template_submissions_path(@template),
notice: "#{submissions.size} #{'recipient'.pluralize(submissions.size)} added"
end
def destroy

@ -52,7 +52,7 @@ button[disabled] .enabled {
}
.base-textarea {
@apply textarea textarea-bordered bg-white;
@apply textarea textarea-bordered bg-white rounded-3xl;
}
.base-button {

@ -24,6 +24,7 @@
:compact="true"
:menu-classes="'dropdown-content bg-white menu menu-xs p-2 shadow rounded-box w-52 rounded-t-none -left-[1px]'"
:submitters="template.submitters"
@update:model-value="save"
@click="selectedAreaRef.value = area"
/>
<FieldType
@ -31,7 +32,7 @@
:button-width="27"
:button-classes="'px-1'"
:menu-classes="'bg-white rounded-t-none'"
@update:model-value="maybeUpdateOptions"
@update:model-value="[maybeUpdateOptions(), save()]"
@click="selectedAreaRef.value = area"
/>
<span
@ -111,7 +112,7 @@ export default {
FieldSubmitter,
IconX
},
inject: ['template', 'selectedAreaRef'],
inject: ['template', 'selectedAreaRef', 'save'],
props: {
area: {
type: Object,
@ -127,6 +128,7 @@ export default {
data () {
return {
isResize: false,
isDragged: false,
isNameFocus: false,
dragFrom: { x: 0, y: 0 }
}
@ -204,6 +206,8 @@ export default {
this.field.name = ''
this.$refs.name.innerText = this.defaultName
}
this.save()
},
onNameEnter (e) {
this.$refs.name.blur()
@ -216,6 +220,8 @@ export default {
},
drag (e) {
if (e.toElement.id === 'mask') {
this.isDragged = true
this.area.x = (e.layerX - this.dragFrom.x) / e.toElement.clientWidth
this.area.y = (e.layerY - this.dragFrom.y) / e.toElement.clientHeight
}
@ -236,6 +242,12 @@ export default {
document.removeEventListener('mousemove', this.drag)
document.removeEventListener('mouseup', this.stopDrag)
if (this.isDragged) {
this.save()
}
this.isDragged = false
this.$emit('stop-drag')
},
startResize () {
@ -251,6 +263,8 @@ export default {
document.removeEventListener('mouseup', this.stopResize)
this.$emit('stop-resize')
this.save()
}
}
}

@ -17,24 +17,32 @@
</div>
<div class="space-x-3 flex items-center">
<a
:href="`/templates/${template.id}/submissions`"
:href="`/templates/${template.id}/submissions/new`"
data-turbo-frame="modal"
class="btn btn-primary"
>
<IconUsersPlus
width="20"
class="mr-2 inline"
class="inline"
/>
Recipients
</a>
<a
:href="`/`"
<button
class="base-button"
:class="{ disabled: isSaving }"
v-bind="isSaving ? { disabled: true } : {}"
@click.prevent="onSaveClick"
><IconDeviceFloppy
width="20"
class="mr-2"
/>Save</a>
>
<IconInnerShadowTop
v-if="isSaving"
width="20"
class="animate-spin"
/>
<IconDeviceFloppy
v-else
width="20"
/>Save
</button>
</div>
</div>
<div
@ -131,7 +139,7 @@ import Document from './document'
import Logo from './logo'
import Contenteditable from './contenteditable'
import DocumentPreview from './preview'
import { IconUsersPlus, IconDeviceFloppy } from '@tabler/icons-vue'
import { IconUsersPlus, IconDeviceFloppy, IconInnerShadowTop } from '@tabler/icons-vue'
import { v4 } from 'uuid'
import i18n from './i18n'
import { ref, computed } from 'vue'
@ -145,6 +153,7 @@ export default {
Fields,
Logo,
DocumentPreview,
IconInnerShadowTop,
Contenteditable,
IconUsersPlus,
IconDeviceFloppy
@ -152,6 +161,7 @@ export default {
provide () {
return {
template: this.template,
save: this.save,
selectedAreaRef: computed(() => this.selectedAreaRef)
}
},
@ -239,6 +249,8 @@ export default {
if (!field.areas.length) {
this.template.fields.splice(this.template.fields.indexOf(field), 1)
}
this.save()
},
onDraw (area) {
if (this.drawField) {
@ -281,6 +293,8 @@ export default {
}
this.selectedAreaRef.value = area
this.save()
},
onDropfield (area) {
const field = {
@ -343,6 +357,8 @@ export default {
this.selectedAreaRef.value = fieldArea
this.template.fields.push(field)
this.save()
},
updateFromUpload ({ schema, documents }) {
this.template.schema.push(...schema)
@ -387,7 +403,7 @@ export default {
this.isSaving = true
this.save().then(() => {
// window.Turbo.visit('/')
window.Turbo.visit(`/templates/${this.template.id}/submissions`)
}).finally(() => {
this.isSaving = false
})
@ -404,7 +420,14 @@ export default {
return fetch(`/api/templates/${this.template.id}`, {
method: 'PUT',
body: JSON.stringify({ template: this.template }),
body: JSON.stringify({
template: {
name: this.template.name,
schema: this.template.schema,
submitters: this.template.submitters,
fields: this.template.fields
}
}),
headers: { 'Content-Type': 'application/json' }
}).then((resp) => {
console.log(resp)

@ -14,7 +14,7 @@
<FieldType
v-model="field.type"
:button-width="20"
@update:model-value="maybeUpdateOptions"
@update:model-value="[maybeUpdateOptions(), save()]"
@click="scrollToFirstArea"
/>
<Contenteditable
@ -157,10 +157,11 @@
class="w-full input input-primary input-xs text-sm"
type="text"
required
@blur="save"
>
<button
class="text-sm w-3.5"
@click="field.options.splice(index, 1)"
@click="[field.options.splice(index, 1), save()]"
>
&times;
</button>
@ -168,7 +169,7 @@
<button
v-if="field.options"
class="text-center text-sm w-full pb-1"
@click="field.options.push('')"
@click="[field.options.push(''), save()]"
>
+ Add option
</button>
@ -191,7 +192,7 @@ export default {
IconTrashX,
FieldType
},
inject: ['template'],
inject: ['template', 'save'],
props: {
field: {
type: Object,
@ -250,9 +251,13 @@ export default {
}
this.isNameFocus = false
this.save()
},
removeArea (area) {
this.field.areas.splice(this.field.areas.indexOf(area), 1)
this.save()
}
}
}

@ -26,6 +26,7 @@
class="cursor-text"
:icon-inline="true"
:icon-width="18"
@update:model-value="$emit('name-change', selectedSubmitter)"
/>
</div>
<span>
@ -116,7 +117,7 @@ export default {
default: 'dropdown-content menu p-2 shadow bg-base-100 rounded-box w-full z-10'
}
},
emits: ['update:model-value', 'remove'],
emits: ['update:model-value', 'remove', 'new-submitter', 'name-change'],
computed: {
colors () {
return [
@ -158,6 +159,7 @@ export default {
this.submitters.push(newSubmitter)
this.$emit('update:model-value', newSubmitter.uuid)
this.$emit('new-submitter', newSubmitter)
},
closeDropdown () {
document.activeElement.blur()

@ -4,7 +4,9 @@
:model-value="selectedSubmitter.uuid"
class="w-full bg-base-100"
:submitters="submitters"
@new-submitter="save"
@remove="removeSubmitter"
@name-change="save"
@update:model-value="$emit('change-submitter', submitters.find((s) => s.uuid === $event))"
/>
</div>
@ -79,6 +81,7 @@ export default {
Field,
FieldSubmitter
},
inject: ['save'],
props: {
fields: {
type: Array,
@ -116,6 +119,8 @@ export default {
if (this.selectedSubmitter === submitter) {
this.$emit('change-submitter', this.submitters[0])
}
this.save()
},
move (field, direction) {
const currentIndex = this.submitterFields.indexOf(field)
@ -134,9 +139,13 @@ export default {
} else {
this.fields.splice(fieldsIndex + direction, 0, field)
}
this.save()
},
removeField (field) {
this.fields.splice(this.fields.indexOf(field), 1)
this.save()
},
addField (type, area = null) {
const field = {
@ -152,6 +161,8 @@ export default {
}
this.fields.push(field)
this.save()
}
}
}

@ -1,7 +1,7 @@
# frozen_string_literal: true
class SubmitterMailer < ApplicationMailer
DEFAULT_MESSAGE = "You've been invited to submit documents."
DEFAULT_MESSAGE = "You've been invited to submit the following documents:"
def invitation_email(submitter, message: DEFAULT_MESSAGE)
@submitter = submitter

@ -32,12 +32,12 @@
<% if signature.signature_handler.signer_certificate.public_key.to_der == trusted_certs.first.public_key.to_der %>
<%= svg_icon('circle_check', class: 'w-6 h-6 text-green-500') %>
<span>
Signed with DocuSeal Certificate
Signed with DocuSeal certificate
</span>
<% else %>
<%= svg_icon('x_circle', class: 'w-6 h-6 text-red-500') %>
<span>
Signed with External Certificate
Signed with external certificate
</span>
<% end %>
</p>

@ -1,3 +1,4 @@
<!DOCTYPE html>
<html data-theme="docuseal">
<head>
<title>
@ -12,5 +13,6 @@
<body>
<% if flash.present? %><%= render 'shared/flash' %><% end %>
<%= yield %>
<turbo-frame id="modal"></turbo-frame>
</body>
</html>

@ -32,10 +32,10 @@
</div>
</div>
<div class="flex justify-between mb-4">
<h1 class="text-3xl font-bold">Recepients</h1>
<h1 class="text-3xl font-bold">Recipients</h1>
<%= link_to new_template_submission_path(@template), class: 'btn btn-primary btn-sm gap-2', data: { turbo_frame: 'modal' } do %>
<%= svg_icon('plus', class: 'w-6 h-6') %>
<span class="hidden md:block">Add Recepients</span>
<span class="hidden md:block">Add Recipients</span>
<% end %>
</div>
<div class="overflow-x-auto">

@ -1,4 +1,4 @@
<%= render 'shared/turbo_modal', title: 'New Recepients' do %>
<%= render 'shared/turbo_modal', title: 'New Recipients' do %>
<%= form_for '', url: template_submissions_path(@template), html: { class: 'space-y-4' }, data: { turbo_frame: :_top } do |f| %>
<% if @template.submitters.size == 1 %>
<div class="form-control">
@ -11,14 +11,14 @@
<div class="card card-compact bg-base-200" data-targets="dynamic-list.items">
<div class="card-body">
<div class="absolute right-4 top-5">
<a href="#" data-action="click:dynamic-list#removeItem" class="block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
<a href="#" data-action="click:dynamic-list#removeItem" class="-top-3 relative block w-6 h-6 rounded-lg text-neutral-700 text-center bg-base-300 p-1 hidden hover:bg-neutral hover:text-white">
<%= svg_icon('trash', class: 'w-4 h-4') %>
</a>
</div>
<div class="grid md:grid-cols-2 gap-4">
<% @template.submitters.each do |item| %>
<div class="form-control">
<label class="label">
<label class="label pt-0 pb-1 text-xs">
<span class="label-text"> <%= item['name'] %></span>
</label>
<input type="hidden" name="submission[1][submitters][][uuid]" value="<%= item['uuid'] %>" >
@ -54,7 +54,7 @@
</div>
</div>
<div class="form-control">
<%= f.button button_title(title: 'Confirm', disabled_with: 'Processing'), class: 'base-button' %>
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
</div>
<% end %>
<% end %>

Loading…
Cancel
Save