Browse Source

Improve document content preview

master
Alex Puiu 2 years ago
parent
commit
ad998d37db
  1. 3
      app/Http/Controllers/FileController.php
  2. 2
      app/SearchDisplace/Documents/DocumentFile.php
  3. 55
      app/SearchDisplace/SearchAndDisplaceXML.php
  4. 38482
      package-lock.json
  5. 3
      package.json
  6. 54
      resources/js/components/ProcessFile/ProcessFile.ts
  7. 19
      resources/js/components/ProcessFile/ProcessFile.vue

3
app/Http/Controllers/FileController.php

@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Storage;
use Illuminate\Http\UploadedFile;
use GuzzleHttp\Exception\BadResponseException;
use App\SearchDisplace\Convertor\Convertor;
use App\SearchDisplace\SearchAndDisplaceXML;
class FileController extends Controller
{
@ -77,7 +78,7 @@ class FileController extends Controller
$file = (object) request()->input('file');
$xml = $this->storage->path("contracts/{$file->id}/document_sdapplied.xml");
$original = Convertor::convert($file->type, $xml, true);
$original = SearchAndDisplaceXML::prepareForDownload($file->type, $xml);
return response()->json([
'path' => "tmp/$original"

2
app/SearchDisplace/Documents/DocumentFile.php

@ -63,7 +63,7 @@ class DocumentFile
public static function updateImagesPath($document, $id)
{
$html = new DOMDocument();
$html->loadHTMLFile($document);
$html->loadHTMLFile($document, LIBXML_NOERROR);
$url = url('/') . "/contracts-images/$id/";
foreach($html->getElementsByTagName('img') as $image) {

55
app/SearchDisplace/SearchAndDisplaceXML.php

@ -5,6 +5,7 @@ namespace App\SearchDisplace;
use App\SearchDisplace\Documents\DocumentFile;
use Illuminate\Support\Facades\Storage;
use App\SearchDisplace\Convertor\Convertor;
use DOMDocument;
class SearchAndDisplaceXML
{
@ -12,6 +13,7 @@ class SearchAndDisplaceXML
protected $searchers;
protected $storage;
protected $searchOnly;
protected $markedStyleCreated;
public function __construct($file, $searchers, $searchOnly)
{
@ -19,6 +21,7 @@ class SearchAndDisplaceXML
$this->searchers = $searchers;
$this->storage = Storage::disk('local');
$this->searchOnly = $searchOnly;
$this->markedStyleCreated = false;
}
public function execute()
@ -89,7 +92,8 @@ class SearchAndDisplaceXML
*
* @return void
*/
protected function replace($content, $element, $dom) {
protected function replace($content, $element, $dom)
{
$search = new SearchAndDisplace(
stripslashes($content),
[
@ -117,17 +121,62 @@ class SearchAndDisplaceXML
foreach($indexes[$searcher] as $change) {
$first = substr($content, 0, $change['start']);
$changed = "<mark>" . substr($content, $change['start'], $change['end'] - $change['start'] + 1) . "</mark>";
$changed = substr($content, $change['start'], $change['end'] - $change['start'] + 1);
$last = substr($content, $change['end'] + 1);
$element->textContent = $first;
$changed = $dom->createElement("text:span", $changed);
$last = $dom->createElement("text:span", $last);
// $changed->setAttribute('style', 'background-color: red');
//text:style-name="mark"
$changed->setAttribute('text:style-name', 'mark');
$element->appendChild($changed);
$element->appendChild($last);
}
}
if(!$this->markedStyleCreated) {
$this->createMarkedStyle($dom);
}
$this->markedStyleCreated = true;
}
}
/**
* Create marked style for browser preview
*
*/
private function createMarkedStyle($dom)
{
$style = $dom->createElement("style:style");
$style->setAttribute("style:name", 'mark');
$style->setAttribute("style:family", 'text');
$child = $dom->createElement('style:text-properties');
$child->setAttribute("officeooo:rsid", '0014890a');
$child->setAttribute("fo:background-color", '#ffff00');
$style->appendChild($child);
$dom->getElementsByTagName('automatic-styles')->item(0)->appendChild($style);
}
/**
* Remove marked style used in browser and convert XML file to original file type
*
* @param $type file type
* @param $file absolute file path
*
* @return string $path
*/
public static function prepareForDownload($type, $file)
{
// remove marked style from XML
$dom = new DOMDocument();
$dom->load($file);
$style = $dom->getElementsByTagName('automatic-styles')->item(0);
$style->removeChild($style->lastChild);
$dom->save($file);
return Convertor::convert($type, $file, true);
}
}

38482
package-lock.json
File diff suppressed because it is too large
View File

3
package.json

@ -29,8 +29,9 @@
"vue-template-compiler": "^2.6.12"
},
"dependencies": {
"@types/jquery": "^3.5.14",
"@types/marked": "^2.0.3",
"marked": "^2.0.5",
"jquery": "^3.6.0",
"mitt": "^2.1.0",
"primeflex": "^2.0.0",
"primeicons": "^5.0.0",

54
resources/js/components/ProcessFile/ProcessFile.ts

@ -4,6 +4,7 @@ import { eventBus } from '@/app';
import DefineSearcher from '../Searchers/DefineSearcher.vue';
import RadioButton from "primevue/radiobutton";
import {isServerError} from "@/SearchDisplace/helpers";
import $ from 'jquery';
@Component({
components: {
@ -39,7 +40,7 @@ export default class ProcessFile extends Vue {
// The processed document content
private processedFileContent: string = '';
private processedFileContentPreview: string = '';
private processedFileContentPreview: boolean = false;
private documentDiffIndexes: { [key: string]: Array<{ start: number; end: number; }>; } = {};
@ -128,7 +129,7 @@ export default class ProcessFile extends Vue {
/**
* MD-to-HTML compiled processed file content with diff highlight
*/
get compiledProcessedFileContentPreview(): string {
get compiledProcessedFileContentPreview(): boolean {
return this.processedFileContentPreview;
}
@ -341,9 +342,8 @@ export default class ProcessFile extends Vue {
const response = await this.$api.filterDocument(this.file.id, searchers);
this.processedFileContent = response.content;
this.documentDiffIndexes = response.indexes;
this.createDiffPreview();
this.processedFileContentPreview = true;
this.showDiffHighlight = true;
this.processing = false;
} catch (e) {
this.$emit('error', 'Server error.');
@ -371,9 +371,8 @@ export default class ProcessFile extends Vue {
const response = await this.$api.filterDocument(this.file.id, searchers, true);
this.processedFileContent = response.content;
// this.documentDiffIndexes = response;
this.createDiffPreview();
this.processedFileContentPreview = true;
this.showDiffHighlight = true;
this.processing = false;
} catch (e) {
this.$emit('error', 'Server error.');
@ -384,36 +383,6 @@ export default class ProcessFile extends Vue {
}
}
/**
* Create the diff preview for the document
*/
private createDiffPreview() {
this.processedFileContentPreview = this.processedFileContent;
let indexes: Array<{ start: number; end: number }> = [];
for (let searcher in this.documentDiffIndexes) {
const searcherIndexes = this.documentDiffIndexes[searcher];
searcherIndexes.forEach(index => {
indexes.push(index);
});
}
indexes.sort((a, b) => {
return b.start - a.start;
});
this.processedFileContentPreview = indexes.reduce(
(r, a) => {
r[a.start] = '<mark>' + r[a.start];
r[a.end] += '</mark>';
return r;
},
this.processedFileContent.split('')
).join('');
}
/**
* Download the document in ODT format
*/
@ -595,7 +564,14 @@ export default class ProcessFile extends Vue {
*/
@Watch('showDiffHighlight')
private onDiffHighlightChanged(newValue: boolean, oldValue: boolean): void {
//
let spans = $('.processed-content').find('span');
$(spans).each(index => {
if(this.showDiffHighlight) {
$(spans[index]).css('background', '#FFFF00');
} else {
$(spans[index]).css('background', '#FFF');
}
})
}
@Watch('selectedSearchers', { deep: true, })

19
resources/js/components/ProcessFile/ProcessFile.vue

@ -2,8 +2,8 @@
<div class="p-d-flex p-flex-row p-jc-between p-ai-stretch">
<Card class="p-mr-2 p-as-stretch file-card">
<template #header>
<Toolbar>
<template #right>
<div>
<template>
<Button @click="onAddNewSearcher"
type="button"
label="Add new searcher"
@ -22,7 +22,7 @@
class="p-button-success p-button-outlined p-button-sm"
@click="toggleUploadDialog()"/>
</template>
</Toolbar>
</div>
</template>
<template #title>
@ -56,8 +56,8 @@
<Card class="p-mr-2 p-as-stretch file-card">
<template #header>
<Toolbar>
<template #right>
<div>
<template>
<label for="show-diff-highlight" class="switch-label">Highlight differences:</label>
<InputSwitch
v-model="showDiffHighlight"
@ -93,14 +93,14 @@
:disabled="!canRunSearchers()"
@click="runSearchers"/>
</template>
</Toolbar>
</div>
</template>
<template #title>
Processed document content
</template>
<template #content>
<div class="md-viewer" style="text-align: start; font-size: 0.7em;">
<div class="md-viewer processed-content" style="text-align: start; font-size: 0.7em;">
<template v-if="processing === true">
<Skeleton/>
<br/>
@ -117,9 +117,8 @@
<Skeleton/>
<br/>
</template>
<template v-else-if="processedFileContentPreview !== ''">
<div v-html="compiledProcessedFileContentPreview" v-if="showDiffHighlight"></div>
<div v-html="compiledProcessedFileContent" v-else></div>
<template v-else-if="processedFileContentPreview !== false">
<div v-html="compiledProcessedFileContent"></div>
</template>
<template v-else>
<Message severity="info" :closable="false">

Loading…
Cancel
Save