Browse Source

Merge

master
Orzu Ionut 3 years ago
parent
commit
89ffcdd8eb
  1. 12
      app/SearchDisplace/SearchAndDisplace.php
  2. 67
      package-lock.json
  3. 3
      package.json
  4. 11
      public/css/app.css
  5. 11845
      public/js/app.js
  6. 7
      resources/js/app.ts
  7. 15
      resources/js/components/ProcessFile/ProcessFile.scss
  8. 93
      resources/js/components/ProcessFile/ProcessFile.ts
  9. 40
      resources/js/components/ProcessFile/ProcessFile.vue
  10. 28
      resources/js/components/Regex/Create.vue
  11. 1
      resources/js/components/Searchers/Index.vue
  12. 79
      resources/js/components/Searchers/Show.vue
  13. 13
      resources/sass/app.sass

12
app/SearchDisplace/SearchAndDisplace.php

@ -58,10 +58,14 @@ class SearchAndDisplace
$updatedDocumentContent = $updatedDocumentContent . $replacements[$searcher];
$replacementIndexes[$searcher][] = [
'start' => $start,
'end' => strlen($updatedDocumentContent) - 1,
];
$end = strlen($updatedDocumentContent) - 1;
if ($start <= $end) {
$replacementIndexes[$searcher][] = [
'start' => $start,
'end' => $end,
];
}
$currentIndex = $searcherResult['end'] + 1;
}

67
package-lock.json

@ -1559,6 +1559,11 @@
"@types/mdurl": "*"
}
},
"@types/marked": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/marked/-/marked-2.0.3.tgz",
"integrity": "sha512-lbhSN1rht/tQ+dSWxawCzGgTfxe9DB31iLgiT1ZVT5lshpam/nyOA1m3tKHRoNPctB2ukSL22JZI5Fr+WI/zYg=="
},
"@types/mdurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
@ -9849,14 +9854,6 @@
"integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
"dev": true
},
"linkify-it": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.2.tgz",
"integrity": "sha512-gDBO4aHNZS6coiZCKVhSNh43F9ioIL4JwRjLZPkoLIY4yZFwg264Y5lu2x6rb1Js42Gh6Yqm2f6L2AJcnkzinQ==",
"requires": {
"uc.micro": "^1.0.1"
}
},
"loader-runner": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz",
@ -10017,29 +10014,10 @@
"object-visit": "^1.0.0"
}
},
"markdown-it": {
"version": "12.0.6",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.0.6.tgz",
"integrity": "sha512-qv3sVLl4lMT96LLtR7xeRJX11OUFjsaD5oVat2/SNBIb21bJXwal2+SklcRbTwGwqWpWH/HRtYavOoJE+seL8w==",
"requires": {
"argparse": "^2.0.1",
"entities": "~2.1.0",
"linkify-it": "^3.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
},
"dependencies": {
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"entities": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
}
}
"marked": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/marked/-/marked-2.0.5.tgz",
"integrity": "sha512-yfCEUXmKhBPLOzEC7c+tc4XZdIeTdGoRCZakFMkCxodr7wDXqoapIME4wjcpBPJLNyUnKJ3e8rb8wlAgnLnaDw=="
},
"md5": {
"version": "2.3.0",
@ -10069,11 +10047,6 @@
"integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
"dev": true
},
"mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -15177,11 +15150,6 @@
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
"dev": true
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
},
"uglify-js": {
"version": "3.4.10",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
@ -15550,23 +15518,6 @@
"vue-style-loader": "^4.1.0"
}
},
"vue-markdown-render": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/vue-markdown-render/-/vue-markdown-render-1.1.1.tgz",
"integrity": "sha512-NkkGOC4ip6C3Cp0dyFBCEPZ9dDF2yI2wrePSwoU2xamyhvcs0eJk0t9VZcUiKCz1bm5SvVeTelIU0qzVgi6jVQ==",
"requires": {
"markdown-it": "^12.0.4",
"punycode": "^2.1.1",
"vue": "^2.6.12"
},
"dependencies": {
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
}
}
},
"vue-property-decorator": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz",

3
package.json

@ -27,13 +27,14 @@
"vue-template-compiler": "^2.6.12"
},
"dependencies": {
"@types/marked": "^2.0.3",
"marked": "^2.0.5",
"primeflex": "^2.0.0",
"primeicons": "^4.1.0",
"primevue": "^2.4.1",
"tsconfig-paths-webpack-plugin": "^3.5.1",
"vue": "^2.6.12",
"vue-class-component": "^7.2.6",
"vue-markdown-render": "^1.1.1",
"vue-property-decorator": "^8.1.0"
}
}

11
public/css/app.css

@ -10906,16 +10906,13 @@ body {
}
.box {
border: 1px solid black;
min-width: 100px;
min-height: 100px;
padding: 10px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
margin-left: 1rem;
margin-bottom: 1rem;
background-color: var(--surface-e);
text-align: center;
padding: 1rem;
border-radius: 4px;
}
.box.selected {
border-color: dodgerblue;

11845
public/js/app.js
File diff suppressed because it is too large
View File

7
resources/js/app.ts

@ -4,7 +4,6 @@ import Vue from 'vue';
/**
* Import vendor classes
*/
import VueMarkdown from "vue-markdown-render";
import PrimeVue from 'primevue/config';
import Button from 'primevue/button';
import Panel from 'primevue/panel';
@ -32,6 +31,8 @@ import ProgressSpinner from 'primevue/progressspinner';
import InputText from 'primevue/inputtext';
import Dialog from 'primevue/dialog';
import Message from 'primevue/message';
import Timeline from 'primevue/timeline';
import ScrollPanel from 'primevue/scrollpanel';
// Own components
import AppHeader from './components/layout/Header.vue';
@ -51,7 +52,6 @@ Vue.use(PrimeVue, {
Vue.use(ToastService);
Vue.use(ApiPlugin);
Vue.component('vue-markdown', VueMarkdown);
Vue.component('Button', Button);
Vue.component('Panel', Panel);
Vue.component('Card', Card);
@ -76,6 +76,8 @@ Vue.component('ProgressSpinner', ProgressSpinner);
Vue.component('InputText', InputText);
Vue.component('Dialog', Dialog);
Vue.component('Message', Message);
Vue.component('Timeline', Timeline);
Vue.component('ScrollPanel', ScrollPanel);
// Layout
Vue.component('app-header', AppHeader);
@ -89,6 +91,7 @@ Vue.component('regex-create', RegexCreate);
Vue.component('searchers-index', SearchersIndex);
Vue.component('searchers-create', SearchersCreate);
Vue.component('searchers-show', SearchersShow);
Vue.component('searchers-index', SearchersIndex);
// Includes
Vue.component('process-file', ProcessFile);

15
resources/js/components/ProcessFile/ProcessFile.scss

@ -2,9 +2,6 @@
flex: 0 1 49%;
}
// .filters-card {
// flex: 0 1 24%
// }
.p-overlaypanel {
// width: 450px;
min-width: 450px;
@ -35,17 +32,23 @@ button.add-searchers {
height: 100%;
}
.p-button.sidebar-toggle-button {
position: absolute;
left: calc(-16px - 2.357rem);
top: 50px;
border-radius: 3px 0 0 3px;
}
.p-col.sidebar-title {
display: flex;
align-content: flex-start;
justify-content: flex-start;
}
.p-grid.sidebar-title-container {
padding-top: 50px;
label.switch-label {
padding-right: 10px;
}
// @TODO Does not work, fix this.
.md-viewer {
text-align: start !important;

93
resources/js/components/ProcessFile/ProcessFile.ts

@ -1,7 +1,6 @@
import axios from 'axios';
// import OverlayPanel from 'primevue/overlaypanel/OverlayPanel';
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
import {FileData} from '@/interfaces/FileData';
import marked from 'marked';
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
import { FileData } from '@/interfaces/FileData';
@Component
export default class ProcessFile extends Vue {
@ -30,6 +29,10 @@ export default class ProcessFile extends Vue {
// The processed document content
private processedFileContent: string = '';
private processedFileContentPreview: string = '';
private documentDiffIndexes: { [key:string]: Array<{ start: number; end: number; }>; } = {};
// Flag to determine whether the text is processing or not
private processing: boolean = false;
@ -54,6 +57,9 @@ export default class ProcessFile extends Vue {
// The list of options applied to the searchers (for the moment, only replace_with)
private searchersOptions: { [key: string]: string } = {};
// Flag to determine whether or not we will show the diff highlights
private showDiffHighlight: boolean = false;
/**
*
*/
@ -61,6 +67,27 @@ export default class ProcessFile extends Vue {
this.intervalId = setInterval(this.waitForFile, 3000);
}
/**
* MD-to-HTML compiled file content
*/
get compiledFileContent(): string {
return marked(this.fileContent);
}
/**
* MD-to-HTML compiled processed file content
*/
get compiledProcessedFileContent(): string {
return marked(this.processedFileContent);
}
/**
* MD-to-HTML compiled processed file content with diff highlight
*/
get compiledProcessedFileContentPreview(): string {
return marked(this.processedFileContentPreview);
}
/**
* Toggle the sidebar containing the searchers
*/
@ -114,7 +141,12 @@ export default class ProcessFile extends Vue {
}
private onSelectedSearchersReorder($event: any) {
/**
*
* @param $event
*/
private onSelectedSearchersReorder($event: any)
{
this.selectedSearchers = $event.value;
}
@ -135,15 +167,62 @@ export default class ProcessFile extends Vue {
const response = await this.$api.filterDocument(this.fileContent, searchers);
console.log(response);
this.processedFileContent = response.content;
this.documentDiffIndexes = response.indexes;
this.createDiffPreview();
this.processing = false;
}
/**
* 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
*/
private async downloadOdt() {
let response = await this.$api.convertFile(this.processedFileContent);
window.open(`${window.location.origin}/file/download/` + response.path);
}
/**
* Watch the `showDiffHighlight` property for changes
*
* @param {boolean} newValue
* @param {boolean} oldValue
*/
@Watch('showDiffHighlight')
private onDiffHighlightChanged(newValue: boolean, oldValue: boolean): void
{
console.log('OLD: ', oldValue);
console.log('NEW: ', newValue);
}
}

40
resources/js/components/ProcessFile/ProcessFile.vue

@ -28,7 +28,7 @@
<br/>
</template>
<template v-else>
<vue-markdown :source="fileContent"/>
<div v-html="compiledFileContent"></div>
</template>
</div>
</template>
@ -42,24 +42,26 @@
</template>
<template #right>
<label for="show-diff-highlight" class="switch-label">Highlight differences:</label>
<InputSwitch
v-model="showDiffHighlight"
name="show-diff-highlight"
inputId="show-diff-highlight"
:disabled="processedFileContent == ''"/>
<Button
label="Download document"
icon="pi pi-download"
class="p-button-secondary p-button-outlined p-button-sm"
:disabled="processedFileContent == ''"
@click="downloadOdt()"/>
<Button
label="Run filters"
icon="pi pi-play"
class="p-button-success p-button-outlined p-button-sm"
:disabled="fileContent == ''"
:disabled="fileContent == '' || selectedSearchers.length === 0"
@click="runSearchers()"/>
<Button
label="Toggle filters list"
icon="pi pi-list"
class="p-button-info p-button-outlined p-button-sm"
@click="toggleSearchersSidebar()"/>
</template>
</Toolbar>
</template>
@ -82,8 +84,9 @@
<Skeleton/>
<br/>
</template>
<template v-else-if="processedFileContent !== ''">
<vue-markdown :source="processedFileContent"/>
<template v-else-if="processedFileContentPreview !== ''">
<div v-html="compiledProcessedFileContentPreview" v-if="showDiffHighlight"></div>
<div v-html="compiledProcessedFileContent" v-else></div>
</template>
<template v-else>
<Message severity="info" :closable="false">
@ -95,10 +98,21 @@
</Card>
<Sidebar
:visible.sync="searchersSidebarVisible"
:showCloseIcon="true"
class="p-sidebar-md"
:visible="true"
:showCloseIcon="false"
:class="{'p-sidebar-md': true, 'p-sidebar-leave-to': !searchersSidebarVisible}"
:dismissable="true"
:modal="false"
:autoZIndex="true"
:baseZIndex="1000"
position="right">
<div class="p-grid p-jc-start">
<Button
icon="pi pi-list"
class="p-button-info p-button-icon-only sidebar-toggle-button"
@click="toggleSearchersSidebar()"/>
</div>
<div class="p-grid p-jc-between sidebar-title-container">
<div class="p-col sidebar-title">
<h3>Document searchers</h3>

28
resources/js/components/Regex/Create.vue

@ -4,14 +4,24 @@
<template v-if=" ! regex">
<h1> New regex searcher </h1>
<InputText v-model="name"
type="text"
placeholder="Enter searcher name"
class="input">
</InputText>
<div class="p-field">
<span class="p-float-label">
<InputText v-model="name"
type="text"
class="p-inputtext-sm"
name="name"
id="name">
</InputText>
</span>
</div>
<label for="name">Enter searcher name</label>
</template>
<Button @click="onSave" :disabled="( ! name && ! regex) || ! pattern">
<Button @click="onSave"
:disabled="( ! name && ! regex) || ! pattern"
class="p-button-sm p-button-raised">
Save
</Button>
</div>
@ -101,3 +111,9 @@ export default class Create extends Vue {
}
};
</script>
<style lang="scss" scoped>
#regex-create {
margin-top: 25px;
}
</style>

1
resources/js/components/Searchers/Index.vue

@ -83,4 +83,3 @@ export default class Index extends Vue {
}
};
</script>

79
resources/js/components/Searchers/Show.vue

@ -97,6 +97,61 @@
@click="confirmDelete"/>
</template>
</Dialog>
<!-- <Panel :header="searcher.name">-->
<!-- <template #icons>-->
<!-- <a-->
<!-- class="p-panel-header-icon p-link"-->
<!-- v-if="editable"-->
<!-- :href="`/searchers/${searcher.id}/edit`"-->
<!-- >-->
<!-- <span class="pi pi-cog"></span>-->
<!-- </a>-->
<!-- </template>-->
<!-- <div class="p-d-flex p-jc-start">-->
<!-- <h5>{{ searcher.description }}</h5>-->
<!-- <Timeline :value="searcher.rows">-->
<!-- <template #opposite="slotProps">-->
<!-- <small class="p-text-secondary">-->
<!-- {{ slotProps.index + 1 }}-->
<!-- </small>-->
<!-- </template>-->
<!-- <template #content="slotProps">-->
<!-- <ScrollPanel-->
<!-- style="max-width: 90vw; height: 125px"-->
<!-- class="searcher-list"-->
<!-- >-->
<!-- <div-->
<!-- v-for="(-->
<!-- searcherItem, columnIndex-->
<!-- ) in slotProps.item"-->
<!-- :key="`column-${columnIndex}`"-->
<!-- >-->
<!-- <div class="box is-plain p-shadow-5">-->
<!-- <template-->
<!-- v-if="-->
<!-- searcherItem.hasOwnProperty('name')-->
<!-- "-->
<!-- >-->
<!-- <searcher-show-->
<!-- :editable="false"-->
<!-- :searcher="searcherItem"-->
<!-- ></searcher-show>-->
<!-- </template>-->
<!-- <template v-else>-->
<!-- <b>{{ searcherItem.expression }}</b>-->
<!-- </template>-->
<!-- </div>-->
<!-- </div>-->
<!-- </ScrollPanel>-->
<!-- <Divider />-->
<!-- </template>-->
<!-- </Timeline>-->
<!-- </div>-->
<!-- </Panel>-->
</div>
</template>
@ -189,3 +244,27 @@ export default class Show extends Vue {
}
};
</script>
<style lang="scss" scoped>
::v-deep .p-timeline-event-opposite {
flex: 0 !important;
}
::v-deep .p-timeline-event-content {
margin-bottom: 25px;
}
::v-deep .searcher-list {
.p-scrollpanel-content {
display: flex;
flex-direction: row;
padding-top: 25px
}
.p-scrollpanel-bar {
background-color: #1976d2;
opacity: 1;
transition: background-color 0.3s;
}
}
</style>

13
resources/sass/app.sass

@ -8,8 +8,6 @@
@import '~primeflex/src/_elevation'
@import '~primevue/resources/themes/fluent-light/theme.css'
// @import '~primevue/resources/themes/vela-green/theme.css'
//@import '~primevue/resources/themes/mdc-light-indigo/theme.css'
@import '~primevue/resources/primevue.min.css'
@import '~primeicons/primeicons.css'
@ -44,16 +42,13 @@ body
// Temp location
.box
border: 1px solid black
min-width: 100px
min-height: 100px
padding: 10px
display: flex
justify-content: center
align-items: center
cursor: pointer
margin-left: 1rem
margin-bottom: 1rem
background-color: var(--surface-e)
text-align: center
padding: 1rem
border-radius: 4px
&.selected
border-color: dodgerblue

Loading…
Cancel
Save