#280 highlight diffs in dictionary proposed changes

This commit is contained in:
Avris 2021-11-29 19:25:23 +01:00
parent 9564a27032
commit ac35da3077
9 changed files with 231 additions and 85 deletions

View File

@ -16,7 +16,7 @@
@import "~bootstrap/scss/button-group";
//TODO @import "~bootstrap/scss/input-group";
//TODO @import "~bootstrap/scss/custom-forms";
//@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/nav";
//@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/card";
//@import "~bootstrap/scss/accordion";

View File

@ -42,79 +42,36 @@
<template v-slot:row="s"><template v-if="s">
<td>
<ul class="list-singular">
<li v-for="w in s.el.masc">
{{ w }}
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in s.el.mascPl">
<Spelling :text="w"/>
</li>
</ul>
<Noun :noun="s.el" gender="masc"/>
<small v-if="s.el.base && nouns[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-singular">
<li v-for="w in nouns[s.el.base].masc">
<Spelling :text="w"/>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in nouns[s.el.base].mascPl">
<Spelling :text="w"/>
</li>
</ul>
<Diff switchable>
<template v-slot:before><Noun :noun="nouns[s.el.base]" gender="masc"/></template>
<template v-slot:after><Noun :noun="s.el" gender="masc"/></template>
</Diff>
</small>
</td>
<td>
<ul class="list-singular">
<li v-for="w in s.el.fem">
<Spelling :text="w"/>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in s.el.femPl">
<Spelling :text="w"/>
</li>
</ul>
<Noun :noun="s.el" gender="fem"/>
<small v-if="s.el.base && nouns[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-singular">
<li v-for="w in nouns[s.el.base].fem">
<Spelling :text="w"/>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in nouns[s.el.base].femPl">
<Spelling :text="w"/>
</li>
</ul>
<Diff switchable>
<template v-slot:before><Noun :noun="nouns[s.el.base]" gender="fem"/></template>
<template v-slot:after><Noun :noun="s.el" gender="fem"/></template>
</Diff>
</small>
</td>
<td>
<ul class="list-singular">
<li v-for="w in s.el.neutr">
<Declension v-if="config.nouns.declension" :word="w" tooltip/>
<template v-else><Spelling :text="w"/></template>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in s.el.neutrPl">
<Declension v-if="config.nouns.declension" :word="w" plural :singularOptions="s.el.neutr" tooltip/>
<template v-else><Spelling :text="w"/></template>
</li>
</ul>
<Noun :noun="s.el" gender="neutr"/>
<small v-if="s.el.base && nouns[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-singular">
<li v-for="w in nouns[s.el.base].neutr"><Spelling :text="w"/></li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in nouns[s.el.base].neutrPl"><Spelling :text="w"/></li>
</ul>
<Diff switchable>
<template v-slot:before><Noun :noun="nouns[s.el.base]" gender="neutr"/></template>
<template v-slot:after><Noun :noun="s.el" gender="neutr"/></template>
</Diff>
</small>
<div v-if="s.el.sourcesData.length" class="div-three-columns">

100
components/Diff.vue Normal file
View File

@ -0,0 +1,100 @@
<template>
<component :is="block || switchable ? 'div' : 'span'">
<ul v-if="switchable" class="nav nav-tabs">
<li v-for="v in views" class="nav-item">
<a :class="['nav-link', v === selectedView ? 'active' : '']" href="#" @click.prevent="selectedView = v">
{{ v }}
<span v-if="v === 'diff' && countChanges > 0" class="badge bg-warning">{{ countChanges }}</span>
</a>
</li>
</ul>
<component :is="block || switchable ? 'div' : 'span'" :class="block || switchable ? 'tab-content bg-white p-3' : ''">
<span ref="before" v-show="selectedView === 'before'">
<slot name="before"></slot>
</span>
<span ref="after" v-show="selectedView === 'after'">
<slot name="after"></slot>
</span>
<span ref="diff" v-show="selectedView === 'diff'"></span>
</component>
</component>
</template>
<script>
import diff from 'generic-diff';
export default {
props: {
view: {'default': 'diff'},
switchable: {type: Boolean},
block: {type: Boolean}
},
data() {
return {
views: ['before', 'after', 'diff'],
selectedView: this.view,
diff: [],
}
},
mounted() {
this.update();
this.observerBefore = new MutationObserver(this.update);
this.observerBefore.observe(this.$refs.before, {
childList: true,
subtree: true
});
this.observerAfter = new MutationObserver(this.update);
this.observerAfter.observe(this.$refs.after, {
childList: true,
subtree: true
});
},
beforeUnmount() {
this.observerBefore.disconnect();
this.observerAfter.disconnect();
},
methods: {
update() {
this.diff = diff(
this.$refs.before.innerHTML,
this.$refs.after.innerHTML,
)
this.$refs.diff.innerHTML = this.diff.map(function (edit) {
if (edit.added) {
return '<ins>' + edit.items.join('') + '</ins>'
} else if (edit.removed) {
return '<del>' + edit.items.join('') + '</del>'
} else {
return edit.items.join('')
}
}).join('');
},
},
computed: {
countChanges() {
return this.diff.filter(d => d.added || d.removed).length;
}
}
};
</script>
<style lang="scss">
@import "assets/variables";
ins {
background-color: $green-200;
padding: .2em;
&:empty::before {
content: '<<< +++ block';
}
}
del {
background-color: $red-200;
padding: .2em;
&:empty::before {
content: '<<< --- block';
}
}
</style>

View File

@ -50,7 +50,7 @@
<template v-slot:row="s"><template v-if="s">
<td>
<ul class="list-untyled">
<ul>
<li v-for="w in s.el.insteadOf" class="text-strike"><LinkedText :text="w" noicons/></li>
</ul>
@ -64,29 +64,57 @@
<div v-if="s.el.base && entries[s.el.base]" class="small">
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-untyled">
<li v-for="w in entries[s.el.base].insteadOf" class="text-strike"><LinkedText :text="w" noicons/></li>
</ul>
<ul class="list-inline">
<li v-for="category in entries[s.el.base].categories" class="list-inline-item">
<span class="badge bg-primary text-white">
{{category}}
</span>
</li>
</ul>
<Diff switchable>
<template v-slot:before>
<ul>
<li v-for="w in entries[s.el.base].insteadOf" class="text-strike"><LinkedText :text="w" noicons/></li>
</ul>
<ul class="list-inline">
<li v-for="category in entries[s.el.base].categories" class="list-inline-item">
<span class="badge bg-primary text-white">
{{category}}
</span>
</li>
</ul>
</template>
<template v-slot:after>
<ul>
<li v-for="w in s.el.insteadOf" class="text-strike"><LinkedText :text="w" noicons/></li>
</ul>
<ul class="list-inline">
<li v-for="category in s.el.categories" class="list-inline-item">
<span class="badge bg-primary text-white">
{{category}}
</span>
</li>
</ul>
</template>
</Diff>
</div>
</td>
<td>
<ul class="list-untyled">
<ul>
<li v-for="w in s.el.say"><LinkedText :text="w" noicons/></li>
</ul>
<small v-if="s.el.base && entries[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-untyled">
<li v-for="w in entries[s.el.base].say"><LinkedText :text="w" noicons/></li>
</ul>
<Diff switchable>
<template v-slot:before>
<ul>
<li v-for="w in entries[s.el.base].say"><LinkedText :text="w" noicons/></li>
</ul>
</template>
<template v-slot:after>
<ul>
<li v-for="w in s.el.say"><LinkedText :text="w" noicons/></li>
</ul>
</template>
</Diff>
</small>
</td>
<td>
@ -103,16 +131,33 @@
<small v-if="s.el.base && entries[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<p v-for="p in entries[s.el.base].because.split('\n\n')"><LinkedText :text="p" noicons/></p>
<ul class="list-unstyled small">
<li v-for="link in entries[s.el.base].links">
<a :href="link" target="_blank" rel="noopener">
<Icon v="external-link"/>
{{clearUrl(link)}}
</a>
</li>
</ul>
<Diff switchable>
<template v-slot:before>
<p v-for="p in entries[s.el.base].because.split('\n\n')"><LinkedText :text="p" noicons/></p>
<ul class="list-unstyled small">
<li v-for="link in entries[s.el.base].links">
<a :href="link" target="_blank" rel="noopener">
<Icon v="external-link"/>
{{clearUrl(link)}}
</a>
</li>
</ul>
</template>
<template v-slot:after>
<p v-for="p in s.el.because.split('\n\n')"><LinkedText :text="p" noicons/></p>
<ul class="list-unstyled small">
<li v-for="link in s.el.links">
<a :href="link" target="_blank" rel="noopener">
<Icon v="external-link"/>
{{clearUrl(link)}}
</a>
</li>
</ul>
</template>
</Diff>
</small>
</td>
<td>

25
components/Noun.vue Normal file
View File

@ -0,0 +1,25 @@
<template>
<div>
<ul class="list-singular">
<li v-for="w in noun[gender]">
<Declension v-if="gender === 'neutr' && config.nouns.declension" :word="w" tooltip/>
<Spelling v-else :text="w"/>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in noun[gender + 'Pl']">
<Declension v-if="gender === 'neutr' && config.nouns.declension" :word="w" plural :singularOptions="noun.neutr" tooltip/>
<Spelling v-else :text="w"/>
</li>
</ul>
</div>
</template>
<script>
export default {
props: {
noun: {required: true},
gender: {required: true},
},
}
</script>

View File

@ -44,7 +44,10 @@
<div class="small" v-if="s.el.base && entries[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<Term :term="entries[s.el.base]" flags/>
<Diff switchable>
<template v-slot:before><Term :term="entries[s.el.base]" flags/></template>
<template v-slot:after><Term :term="s.el" flags/></template>
</Diff>
</div>
</td>
<td>

View File

@ -24,6 +24,7 @@
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
"generic-diff": "^1.0.1",
"grant": "^5.4.5",
"html-loader": "^1.3.2",
"ics": "^2.31.0",

View File

@ -76,7 +76,10 @@
<small v-if="name.base && names[name.base]">
<hr/>
<p><strong><T>nouns.edited</T>:</strong></p>
<Name :name="names[name.base]"/>
<Diff switchable>
<template v-slot:before><Name :name="names[name.base]"/></template>
<template v-slot:after><Name :name="name"/></template>
</Diff>
</small>
</li>
</template>

View File

@ -4582,6 +4582,13 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
generic-diff@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/generic-diff/-/generic-diff-1.0.1.tgz#21d40763a18fc5acd52065c11a8d9b2f95572259"
integrity sha1-IdQHY6GPxazVIGXBGo2bL5VXIlk=
dependencies:
object-assign "^2.0.0"
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@ -6878,6 +6885,11 @@ oauth-sign@^0.9.0, oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-assign@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
integrity sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"