delete image and add blank page basics

pull/150/merge^2
iozeey 2 years ago
parent 6c38173e1e
commit 0c8ffa04c3

@ -23,5 +23,31 @@ module Api
)
}
end
def del_image
template = Template.find(params[:template_id])
attachment_id = params[:attachment_id]
document_id = params[:documentId]
page_number = template.documents.find(document_id).preview_images.find_index { |pic| pic.id == attachment_id }
if page_number
Templates::ProcessDocument.delete_picture(template, attachment_id, page_number)
render json: { success: true, message: 'New blank image added successfully' }
else
page_number = "No image found for deletion"
render json: { success: false, message: "Error: #{page_number}" }, status: :unprocessable_entity
end
end
def add_new_image
byebug
template = Template.find(params[:template_id])
begin
Templates::ProcessDocument.upload_new_blank_image(template)
render json: { success: true, message: 'New blank image added successfully' }
rescue StandardError => e
render json: { success: false, message: "Error adding new blank image: #{e.message}" }, status: :unprocessable_entity
end
end
end
end

@ -742,7 +742,7 @@ export default {
headers: { 'Content-Type': 'application/json' }
})
},
removeImage (imageId) {
removeImage ({ item, imageId }) {
console.log(this.template.documents[0].preview_secured_images)
// output: 0: {id: 26, name: 'preview_images', uuid: 'db2de68e-c52f-41e0-a743-550a5ba26ec0', record_type: 'ActiveStorage::Attachment', record_id: 25, } 1 : {id: 27, name: 'preview_images', uuid: '4f2cd882-95fb-4344-8571-78c9bb5a20aa', record_type: 'ActiveStorage::Attachment', record_id: 25, } 2: {id: 28, name: 'preview_images', uuid: '28bb656a-0799-4a73-b665-692aab2c690b', record_type: 'ActiveStorage::Attachment', record_id: 25, } length: 3, imageId: 27
// const indexToRemove = this.template.documents.findIndex(item => item.id === imageId)
@ -750,17 +750,78 @@ export default {
// Check if the document has a preview_images array
if (Array.isArray(document.preview_images)) {
// Find the index of the preview image with the matching id
console.log('simple preview', document.preview_images, ': secured', document.preview_secured_images)
const indexToRemove = document.preview_images.findIndex(
(previewImage) => previewImage.id === imageId
)
// console.log('simple preview', document.preview_images, ': secured', document.preview_secured_images)
console.log(indexToRemove)
if (indexToRemove !== -1) {
document.preview_images.splice(indexToRemove, 1)
// Optionally, emit a 'change' event if needed
// this.$emit('change');
// here I want to send call to a controller named template_document
const documentId = document.id
const apiUrl = `/api/templates/${this.template.id}/documents/${documentId}/del_image`
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
template: this.template.id,
attachment_id: imageId,
documentId
// page_number: document.preview_images.find(x => x.id === imageId).name
})
})
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`)
}
return response.json()
})
.then((data) => {
// remove from frontend
document.preview_images.splice(indexToRemove, 1)
console.log('Success:', data)
})
.catch((error) => {
console.error('Error:', error)
})
}
}
})
},
addBlankPage (item) {
console.log(this.sortedDocuments)
// console.log(this.template)
const documentId = item.id
console.log(documentId)
const apiUrl = `/api/templates/${this.template.id}/documents/${documentId}/add_new_image`
fetch(apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
template: this.template.id,
document: item
})
})
// this.baseFetch(`/api/templates/${this.templateId}/documents/add_new_image`, {
// method: 'POST',
// body: JSON.stringify({ template: this.template }),
// headers: { 'Content-Type': 'application/json' }
// })
.then((response) => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`)
}
return response.json()
})
.then((data) => {
console.log('Success:', data)
})
.catch((error) => {
console.error('Error:', error)
})
}
}
}

@ -73,7 +73,7 @@
<button
class="btn border-base-200 bg-white text-base-content btn-xs rounded hover:text-base-100 hover:bg-base-content hover:border-base-content w-full transition-colors"
style="width: 24px; height: 24px"
@click.stop="$emit('remove-image', previewImage.id)"
@click.stop="$emit('remove-image', { item, previewImageId: previewImage.id })"
>
&times;
</button>

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

@ -43,7 +43,10 @@ Rails.application.routes.draw do
end
resources :templates, only: %i[update show index destroy] do
resources :submissions, only: %i[index create]
resources :documents, only: %i[create], controller: 'templates_documents'
resources :documents, only: %i[create], controller: 'templates_documents'do
post 'add_new_image', on: :member
post 'del_image', on: :member
end
end
end

@ -105,11 +105,14 @@ module Templates
def generate_pdf_secured_preview_images(template, attachment, data)
ActiveStorage::Attachment.where(name: SECURED_ATTACHMENT_NAME, record: attachment).destroy_all
# delete field image from pdf document throught hexapdf
number_of_pages = PDF::Reader.new(StringIO.new(data)).pages.size - 1
(0..number_of_pages).each do |page_number|
pdf = Vips::Image.new_from_buffer(data, '', dpi: DPI, page: page_number)
pdf = pdf.resize(MAX_WIDTH / pdf.width.to_f)
redacted_boxes = template.fields.select { |field| field['type'] == 'redact' && field['areas'][0]['page'] == page_number }
# deleted_page_field = template.fields.select { |field| field['type'] == 'deleted_page' && field['areas'][0]['page'] == page_number }
# break if !deleted_page_field.empty?
if !redacted_boxes.empty?
redacted_boxes.each do |box|
x = (box['areas'][0]['x'] * pdf.width).to_i
@ -134,5 +137,50 @@ module Templates
end
end
def delete_picture(template, attachment_id, page_number)
attachment = ActiveStorage::Attachment.find_by(id: attachment_id)
byebug
return unless attachment
attachment.purge
deleted_page_field = {
'type' => 'deleted_page',
'areas' => [{
'page' => page_number,
'x' => 0,
'y' => 0,
'w' => 1,
'h' => 1
}]
}
template.fields << deleted_page_field
template.save!
end
def upload_new_blank_image(template)
existing_document = template.documents.first
blank_image = generate_blank_image
blank_blob = create_blob_from_image(blank_image)
upload_new_attachment(template, blank_blob, ATTACHMENT_NAME)
# puts '-----New blank image uploaded successfully!-----'
Rails.logger.info('New blank image uploaded successfully!')
rescue StandardError => e
Rails.logger.error("Error uploading new blank image: #{e.message}")
end
def generate_blank_image
height = 2000
Vips::Image.black(MAX_WIDTH, height)
end
def create_blob_from_image(image)
ActiveStorage::Blob.create_and_upload!(
io: StringIO.new(image.write_to_buffer(FORMAT, Q: Q, interlace: true)),
filename: "#{SecureRandom.uuid}#{FORMAT}",
metadata: { analyzed: true, identified: true, width: image.width, height: image.height }
)
end
def upload_new_attachment(template, blob, attachment_name)
template.documents.attach(blob)
template.documents.last.update!(name: attachment_name)
end
end
end

Loading…
Cancel
Save