loading button

pull/150/merge^2
iozeey 2 years ago
parent 3801c73cb0
commit d7e653b1f1

@ -10,24 +10,15 @@
width="20" width="20"
class="animate-spin" class="animate-spin"
/> />
<IconUpload <IconUpload v-else width="20" />
v-else <span v-if="isLoading"> Uploading... </span>
width="20" <span v-else-if="isProcessing"> Processing... </span>
/> <span v-else> Add Document </span>
<span v-if="isLoading">
Uploading...
</span>
<span v-else-if="isProcessing">
Processing...
</span>
<span v-else>
Add Document
</span>
</label> </label>
<form <label class="btn btn-outline w-full mt-2" @click="addBlankPage">
ref="form" <span> Add blank page </span>
class="hidden" </label>
> <form ref="form" class="hidden">
<input <input
:id="inputId" :id="inputId"
ref="input" ref="input"
@ -36,111 +27,118 @@
:accept="acceptFileTypes" :accept="acceptFileTypes"
multiple multiple
@change="upload" @change="upload"
> />
</form> </form>
</div> </div>
</template> </template>
<script> <script>
import { IconUpload, IconInnerShadowTop } from '@tabler/icons-vue' import { IconUpload, IconInnerShadowTop } from "@tabler/icons-vue";
import { PDFDocument, rgb } from "pdf-lib";
export default { export default {
name: 'DocumentsUpload', name: "DocumentsUpload",
components: { components: {
IconUpload, IconUpload,
IconInnerShadowTop IconInnerShadowTop,
}, },
inject: ['baseFetch'], inject: ["baseFetch"],
props: { props: {
templateId: { templateId: {
type: [Number, String], type: [Number, String],
required: true required: true,
}, },
acceptFileTypes: { acceptFileTypes: {
type: String, type: String,
required: false, required: false,
default: 'image/*, application/pdf' default: "image/*, application/pdf",
}, },
isDirectUpload: { isDirectUpload: {
type: Boolean, type: Boolean,
required: true, required: true,
default: false default: false,
} },
}, },
emits: ['success'], emits: ["success"],
data () { data() {
return { return {
isLoading: false, isLoading: false,
isProcessing: false isProcessing: false,
} };
}, },
computed: { computed: {
inputId () { inputId() {
return 'el' + Math.random().toString(32).split('.')[1] return "el" + Math.random().toString(32).split(".")[1];
} },
}, },
mounted () { mounted() {
if (this.isDirectUpload) { if (this.isDirectUpload) {
import('@rails/activestorage') import("@rails/activestorage");
} }
}, },
methods: { methods: {
async upload () { async upload() {
this.isLoading = true this.isLoading = true;
if (this.isDirectUpload) { if (this.isDirectUpload) {
const { DirectUpload } = await import('@rails/activestorage') const { DirectUpload } = await import("@rails/activestorage");
const blobs = await Promise.all( const blobs = await Promise.all(
Array.from(this.$refs.input.files).map(async (file) => { Array.from(this.$refs.input.files).map(async (file) => {
const upload = new DirectUpload( const upload = new DirectUpload(
file, file,
'/direct_uploads', "/direct_uploads",
this.$refs.input this.$refs.input
) );
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
upload.create((error, blob) => { upload.create((error, blob) => {
if (error) { if (error) {
console.error(error) console.error(error);
return reject(error) return reject(error);
} else { } else {
return resolve(blob) return resolve(blob);
} }
}) });
}).catch((error) => { }).catch((error) => {
console.error(error) console.error(error);
}) });
}) })
).finally(() => { ).finally(() => {
this.isLoading = false this.isLoading = false;
}) });
this.isProcessing = true this.isProcessing = true;
this.baseFetch(`/api/templates/${this.templateId}/documents`, { this.baseFetch(`/api/templates/${this.templateId}/documents`, {
method: 'POST', method: "POST",
body: JSON.stringify({ blobs }), body: JSON.stringify({ blobs }),
headers: { 'Content-Type': 'application/json' } headers: { "Content-Type": "application/json" },
}).then(resp => resp.json()).then((data) => {
this.$emit('success', data)
this.$refs.input.value = ''
}).finally(() => {
this.isProcessing = false
}) })
.then((resp) => resp.json())
.then((data) => {
this.$emit("success", data);
this.$refs.input.value = "";
})
.finally(() => {
this.isProcessing = false;
});
} else { } else {
this.baseFetch(`/api/templates/${this.templateId}/documents`, { this.baseFetch(`/api/templates/${this.templateId}/documents`, {
method: 'POST', method: "POST",
body: new FormData(this.$refs.form) body: new FormData(this.$refs.form),
}).then(resp => resp.json()).then((data) => {
this.$emit('success', data)
this.$refs.input.value = ''
}).finally(() => {
this.isLoading = false
}) })
.then((resp) => resp.json())
.then((data) => {
this.$emit("success", data);
this.$refs.input.value = "";
})
.finally(() => {
this.isLoading = false;
});
} }
} },
} },
} };
</script> </script>

@ -33,15 +33,34 @@
<% end %> <% end %>
<% end %> <% end %>
<% if !template.deleted_at? && can?(:update, template) %> <% if !template.deleted_at? && can?(:update, template) %>
<%= link_to edit_template_path(template), class: 'btn btn-outline btn-sm' do %> <%= link_to edit_template_path(template), class: 'btn btn-outline btn-sm', id: 'edit-template-link' do %>
<span class="flex items-center justify-center space-x-2"> <span class="flex items-center justify-center space-x-2">
<%= svg_icon('pencil', class: 'w-6 h-6') %> <%= svg_icon('pencil', class: 'w-6 h-6') %>
<span>Edit</span> <span>Edit</span>
</span> </span>
<% end %> <% end %>
<% end %> <% end %>
<div id="loading-spinner" style="display: none;">
Loading...
</div>
<% if template.deleted_at? && can?(:create, template) %> <% if template.deleted_at? && can?(:create, template) %>
<%= button_to button_title(title: 'Restore', disabled_with: 'Restoring', icon: svg_icon('rotate', class: 'w-6 h-6')), template_restore_index_path(template), class: 'btn btn-outline btn-sm' %> <%= button_to button_title(title: 'Restore', disabled_with: 'Restoring', icon: svg_icon('rotate', class: 'w-6 h-6')), template_restore_index_path(template), class: 'btn btn-outline btn-sm' %>
<% end %> <% end %>
</div> </div>
</div> </div>
<script>
function showLoading() {
document.getElementById('edit-template-link').style.display = 'none';
document.getElementById('loading-spinner').style.display = 'block';
}
document.getElementById('edit-template-link').addEventListener('click', function(event) {
event.preventDefault();
showLoading();
setTimeout(function() {
window.location.href = '<%= edit_template_path(template) %>';
}, 5000);
});
</script>

Loading…
Cancel
Save