Browse Source

#61: make shortcut optional in front and show simplified shortcut

pull/73/head
Bramble Xu 5 years ago
parent
commit
14e3437722
13 changed files with 144 additions and 23 deletions
  1. 16
      app/server/static/bundle/document_classification.js
  2. 14
      app/server/static/bundle/label.js
  3. 2
      app/server/static/bundle/seq2seq.js
  4. 16
      app/server/static/bundle/sequence_labeling.js
  5. 3
      app/server/static/js/document_classification.js
  6. 10
      app/server/static/js/filter.js
  7. 48
      app/server/static/js/label.js
  8. 8
      app/server/static/js/mixin.js
  9. 3
      app/server/static/js/sequence_labeling.js
  10. 38
      app/server/templates/admin/label.html
  11. 4
      app/server/templates/annotation/document_classification.html
  12. 4
      app/server/templates/annotation/sequence_labeling.html
  13. 1
      app/server/templates/base.html

16
app/server/static/bundle/document_classification.js
File diff suppressed because it is too large
View File

14
app/server/static/bundle/label.js

@ -452,6 +452,18 @@ eval("var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn th
/***/ }), /***/ }),
/***/ "./static/js/filter.js":
/*!*****************************!*\
!*** ./static/js/filter.js ***!
\*****************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return simpleShortcut; });\nfunction simpleShortcut(shortcut) {\n if (shortcut === null) {\n shortcut = '';\n } else {\n shortcut = shortcut.replace('ctrl', 'C');\n shortcut = shortcut.replace('shift', 'S');\n shortcut = shortcut.split(' ').join('-');\n }\n return shortcut;\n}\n\n\n//# sourceURL=webpack:///./static/js/filter.js?");
/***/ }),
/***/ "./static/js/http.js": /***/ "./static/js/http.js":
/*!***************************!*\ /*!***************************!*\
!*** ./static/js/http.js ***! !*** ./static/js/http.js ***!
@ -472,7 +484,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var axio
/***/ (function(module, __webpack_exports__, __webpack_require__) { /***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict"; "use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var _http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./http */ \"./static/js/http.js\");\n\n\n\n\nconst vm = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#mail-app',\n delimiters: ['[[', ']]'],\n data: {\n labels: [],\n labelText: '',\n selectedShortkey: '',\n backgroundColor: '#209cee',\n textColor: '#ffffff',\n },\n\n methods: {\n addLabel() {\n const payload = {\n text: this.labelText,\n shortcut: this.selectedShortkey,\n background_color: this.backgroundColor,\n text_color: this.textColor,\n };\n _http__WEBPACK_IMPORTED_MODULE_1__[\"default\"].post('labels/', payload).then((response) => {\n this.reset();\n this.labels.push(response.data);\n });\n },\n\n removeLabel(label) {\n const labelId = label.id;\n _http__WEBPACK_IMPORTED_MODULE_1__[\"default\"].delete(`labels/${labelId}`).then((response) => {\n const index = this.labels.indexOf(label);\n this.labels.splice(index, 1);\n });\n },\n\n reset() {\n this.labelText = '';\n this.selectedShortkey = '';\n this.backgroundColor = '#209cee';\n this.textColor = '#ffffff';\n },\n },\n created() {\n _http__WEBPACK_IMPORTED_MODULE_1__[\"default\"].get('labels').then((response) => {\n this.labels = response.data;\n });\n },\n});\n\n\n//# sourceURL=webpack:///./static/js/label.js?");
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.js\");\n/* harmony import */ var _http__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./http */ \"./static/js/http.js\");\n/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./filter */ \"./static/js/filter.js\");\n\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].filter('simpleShortcut', _filter__WEBPACK_IMPORTED_MODULE_2__[\"default\"]);\n\n\nconst vm = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#mail-app',\n delimiters: ['[[', ']]'],\n data: {\n labels: [],\n labelText: '',\n selectedKey: '',\n checkedKey: [],\n shortcutKey: '',\n backgroundColor: '#209cee',\n textColor: '#ffffff',\n },\n\n computed: {\n /**\n * combineKeys: Combine selectedKey and checkedKey to get shortcutKey\n * saveKeys: Save null to database if shortcutKey is empty string\n */\n combineKeys: function () {\n this.shortcutKey = '';\n\n // If checkedKey exits, add it to shortcutKey\n if (this.checkedKey.length > 0) {\n this.checkedKey.sort();\n this.shortcutKey = this.checkedKey.join(' ');\n\n // If selectedKey exist, add it to shortcutKey\n if (this.selectedKey.length !== 0) {\n this.shortcutKey = this.shortcutKey + ' ' + this.selectedKey;\n }\n }\n\n // If only selectedKey exist, assign to shortcutKey\n if (this.shortcutKey.length === 0 && this.selectedKey.length !== 0) {\n this.shortcutKey = this.selectedKey;\n }\n return this.shortcutKey;\n },\n\n saveKeys: function () {\n this.shortcutKey = this.combineKeys;\n if (this.shortcutKey === '') {\n return null;\n }\n return this.shortcutKey;\n },\n },\n \n methods: {\n addLabel() {\n const payload = {\n text: this.labelText,\n shortcut: this.saveKeys,\n background_color: this.backgroundColor,\n text_color: this.textColor,\n };\n _http__WEBPACK_IMPORTED_MODULE_1__[\"default\"].post('labels/', payload).then((response) => {\n this.reset();\n this.labels.push(response.data);\n });\n },\n\n removeLabel(label) {\n const labelId = label.id;\n _http__WEBPACK_IMPORTED_MODULE_1__[\"default\"].delete(`labels/${labelId}`).then((response) => {\n const index = this.labels.indexOf(label);\n this.labels.splice(index, 1);\n });\n },\n\n reset() {\n this.labelText = '';\n this.selectedKey = '';\n this.checkedKey = [];\n this.shortcutKey = '';\n this.backgroundColor = '#209cee';\n this.textColor = '#ffffff';\n },\n },\n created() {\n _http__WEBPACK_IMPORTED_MODULE_1__[\"default\"].get('labels').then((response) => {\n this.labels = response.data;\n });\n },\n});\n\n\n//# sourceURL=webpack:///./static/js/label.js?");
/***/ }) /***/ })

2
app/server/static/bundle/seq2seq.js
File diff suppressed because it is too large
View File

16
app/server/static/bundle/sequence_labeling.js
File diff suppressed because it is too large
View File

3
app/server/static/js/document_classification.js

@ -1,11 +1,14 @@
import Vue from 'vue'; import Vue from 'vue';
import annotationMixin from './mixin'; import annotationMixin from './mixin';
import HTTP from './http'; import HTTP from './http';
import simpleShortcut from './filter';
Vue.use(require('vue-shortkey'), { Vue.use(require('vue-shortkey'), {
prevent: ['input', 'textarea'], prevent: ['input', 'textarea'],
}); });
Vue.filter('simpleShortcut', simpleShortcut);
const vm = new Vue({ const vm = new Vue({
el: '#mail-app', el: '#mail-app',

10
app/server/static/js/filter.js

@ -0,0 +1,10 @@
export default function simpleShortcut(shortcut) {
if (shortcut === null) {
shortcut = '';
} else {
shortcut = shortcut.replace('ctrl', 'C');
shortcut = shortcut.replace('shift', 'S');
shortcut = shortcut.split(' ').join('-');
}
return shortcut;
}

48
app/server/static/js/label.js

@ -1,5 +1,8 @@
import Vue from 'vue'; import Vue from 'vue';
import HTTP from './http'; import HTTP from './http';
import simpleShortcut from './filter';
Vue.filter('simpleShortcut', simpleShortcut);
const vm = new Vue({ const vm = new Vue({
@ -8,16 +11,53 @@ const vm = new Vue({
data: { data: {
labels: [], labels: [],
labelText: '', labelText: '',
selectedShortkey: '',
selectedKey: '',
checkedKey: [],
shortcutKey: '',
backgroundColor: '#209cee', backgroundColor: '#209cee',
textColor: '#ffffff', textColor: '#ffffff',
}, },
computed: {
/**
* combineKeys: Combine selectedKey and checkedKey to get shortcutKey
* saveKeys: Save null to database if shortcutKey is empty string
*/
combineKeys: function () {
this.shortcutKey = '';
// If checkedKey exits, add it to shortcutKey
if (this.checkedKey.length > 0) {
this.checkedKey.sort();
this.shortcutKey = this.checkedKey.join(' ');
// If selectedKey exist, add it to shortcutKey
if (this.selectedKey.length !== 0) {
this.shortcutKey = this.shortcutKey + ' ' + this.selectedKey;
}
}
// If only selectedKey exist, assign to shortcutKey
if (this.shortcutKey.length === 0 && this.selectedKey.length !== 0) {
this.shortcutKey = this.selectedKey;
}
return this.shortcutKey;
},
saveKeys: function () {
this.shortcutKey = this.combineKeys;
if (this.shortcutKey === '') {
return null;
}
return this.shortcutKey;
},
},
methods: { methods: {
addLabel() { addLabel() {
const payload = { const payload = {
text: this.labelText, text: this.labelText,
shortcut: this.selectedShortkey,
shortcut: this.saveKeys,
background_color: this.backgroundColor, background_color: this.backgroundColor,
text_color: this.textColor, text_color: this.textColor,
}; };
@ -37,7 +77,9 @@ const vm = new Vue({
reset() { reset() {
this.labelText = ''; this.labelText = '';
this.selectedShortkey = '';
this.selectedKey = '';
this.checkedKey = [];
this.shortcutKey = '';
this.backgroundColor = '#209cee'; this.backgroundColor = '#209cee';
this.textColor = '#ffffff'; this.textColor = '#ffffff';
}, },

8
app/server/static/js/mixin.js

@ -117,6 +117,14 @@ const annotationMixin = {
this.annotations[this.pageNumber].splice(index, 1); this.annotations[this.pageNumber].splice(index, 1);
}); });
}, },
replaceNull(shortcut) {
if (shortcut === null) {
shortcut = '';
}
shortcut = shortcut.split(' ');
return shortcut;
},
}, },
watch: { watch: {

3
app/server/static/js/sequence_labeling.js

@ -1,11 +1,14 @@
import Vue from 'vue'; import Vue from 'vue';
import annotationMixin from './mixin'; import annotationMixin from './mixin';
import HTTP from './http'; import HTTP from './http';
import simpleShortcut from './filter';
Vue.use(require('vue-shortkey'), { Vue.use(require('vue-shortkey'), {
prevent: ['input', 'textarea'], prevent: ['input', 'textarea'],
}); });
Vue.filter('simpleShortcut', simpleShortcut);
Vue.component('annotator', { Vue.component('annotator', {
template: '<div @click="setSelectedRange">\ template: '<div @click="setSelectedRange">\
<span class="text-sequence"\ <span class="text-sequence"\

38
app/server/templates/admin/label.html

@ -16,7 +16,6 @@
<div class="card-content"> <div class="card-content">
<div class="has-text-right"> <div class="has-text-right">
<div class="field is-grouped is-grouped-multiline has-text-weight-bold pbrem075"> <div class="field is-grouped is-grouped-multiline has-text-weight-bold pbrem075">
<div class="control" v-for="label in labels"> <div class="control" v-for="label in labels">
<div class="tags has-addons"> <div class="tags has-addons">
@ -24,7 +23,7 @@
<button class="delete is-small tweaked-margin" @click="removeLabel(label)"></button> <button class="delete is-small tweaked-margin" @click="removeLabel(label)"></button>
[[ label.text ]] [[ label.text ]]
</span> </span>
<span class="tag is-medium">[[ label.shortcut ]]</span>
<span class="tag is-medium"><kbd>[[ label.shortcut | simpleShortcut ]]</kbd></span>
</div> </div>
</div> </div>
</div> </div>
@ -36,23 +35,29 @@
<a class="tag is-medium" v-bind:style="{ color: textColor, backgroundColor: backgroundColor }"> <a class="tag is-medium" v-bind:style="{ color: textColor, backgroundColor: backgroundColor }">
[[ labelText ]] [[ labelText ]]
</a> </a>
<span class="tag is-medium">[[ selectedShortkey ]]</span>
<span class="tag is-medium"><kbd>[[ combineKeys | simpleShortcut ]]</kbd></span>
</div> </div>
</div> </div>
</div> </div>
<div class="field is-horizontal bordered-row"> <div class="field is-horizontal bordered-row">
<label class="label column is-3 mb0">Label Name</label>
<div class="column is-3 mb0">
<label class="label mb0">Label Name</label>
<p class="is-small has-text-grey">required</p>
</div>
<div class="control column is-6"> <div class="control column is-6">
<input class="input" type="text" placeholder="Text input" v-model="labelText"> <input class="input" type="text" placeholder="Text input" v-model="labelText">
</div> </div>
</div> </div>
<div class="field is-horizontal bordered-row"> <div class="field is-horizontal bordered-row">
<label class="label column is-3 mb0">Shortcut Key</label>
<div class="control column is-6">
<div class="column is-3 mb0">
<label class="label mb0">Shortcut Key</label>
<p class="is-small has-text-grey">optional</p>
</div>
<div class="control column is-narrow">
<div class="select"> <div class="select">
<select v-model="selectedShortkey">
<select v-model="selectedKey">
<option disabled value="">Please select one</option> <option disabled value="">Please select one</option>
{% for ch in 'abcdefghijklmnopqrstuvwxyz' %} {% for ch in 'abcdefghijklmnopqrstuvwxyz' %}
<option>{{ ch }}</option> <option>{{ ch }}</option>
@ -60,18 +65,31 @@
</select> </select>
</div> </div>
</div> </div>
<div class="is-narrow">
<input class="is-checkradio" type="checkbox" id="ctrl" value="ctrl" v-model="checkedKey">
<label for="ctrl"><kbd>C: Ctrl</kbd></label>
</div>
<div class="is-narrow">
<input class="is-checkradio" type="checkbox" id="shift" value="shift" v-model="checkedKey">
<label for="shift"><kbd>S: Shift</kbd></label>
</div>
</div> </div>
<div class="field is-horizontal bordered-row"> <div class="field is-horizontal bordered-row">
<label class="label column is-3 mb0">Background Color</label>
<div class="column is-3 mb0">
<label class="label mb0">Background Color</label>
<p class="is-small has-text-grey">optional</p>
</div>
<div class="control column is-6"> <div class="control column is-6">
<input class="input" type="color" v-model="backgroundColor"> <input class="input" type="color" v-model="backgroundColor">
</div> </div>
</div> </div>
<div class="field is-horizontal bordered-row"> <div class="field is-horizontal bordered-row">
<label class="label column is-3 mb0">Text Color</label>
<div class="column is-3 mb0">
<label class="label mb0">Text Color</label>
<p class="is-small has-text-grey">optional</p>
</div>
<div class="control column is-6"> <div class="control column is-6">
<input class="input" type="color" v-model="textColor"> <input class="input" type="color" v-model="textColor">
</div> </div>

4
app/server/templates/annotation/document_classification.html

@ -8,10 +8,10 @@
<div class="control" v-for="(label, item) in labels"> <div class="control" v-for="(label, item) in labels">
<div class="tags has-addons"> <div class="tags has-addons">
<a class="tag is-medium" v-bind:style="{ color: label.text_color, backgroundColor: label.background_color }" v-on:click="addLabel(label)" <a class="tag is-medium" v-bind:style="{ color: label.text_color, backgroundColor: label.background_color }" v-on:click="addLabel(label)"
v-shortkey.once="[ label.shortcut ]" @shortkey="addLabel(label)">
v-shortkey.once=" replaceNull(label.shortcut) " @shortkey="addLabel(label)">
[[ label.text ]] [[ label.text ]]
</a> </a>
<span class="tag is-medium">[[ label.shortcut ]]</span>
<span class="tag is-medium"><kbd>[[ label.shortcut | simpleShortcut ]]</kbd></span>
</div> </div>
</div> </div>
</div> </div>

4
app/server/templates/annotation/sequence_labeling.html

@ -8,10 +8,10 @@
<div class="control" v-for="label in labels"> <div class="control" v-for="label in labels">
<div class="tags has-addons"> <div class="tags has-addons">
<a class="tag is-medium" v-bind:style="{ color: label.text_color, backgroundColor: label.background_color }" v-on:click="annotate(label.id)" <a class="tag is-medium" v-bind:style="{ color: label.text_color, backgroundColor: label.background_color }" v-on:click="annotate(label.id)"
v-shortkey.once="[ label.shortcut ]" @shortkey="annotate(label.id)">
v-shortkey.once=" replaceNull(label.shortcut) " @shortkey="annotate(label.id)">
[[ label.text ]] [[ label.text ]]
</a> </a>
<span class="tag is-medium">[[ label.shortcut ]]</span>
<span class="tag is-medium"><kbd>[[ label.shortcut | simpleShortcut ]]</kbd></span>
</div> </div>
</div> </div>
</div> </div>

1
app/server/templates/base.html

@ -14,6 +14,7 @@
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-extensions@4.0.1/bulma-divider/dist/css/bulma-divider.min.css" crossorigin="anonymous"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-extensions@4.0.1/bulma-divider/dist/css/bulma-divider.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma-extensions@4.0.1/bulma-checkradio/dist/css/bulma-checkradio.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="{% static 'css/forum.css' %}"> <link rel="stylesheet" href="{% static 'css/forum.css' %}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.3.3/css/swiper.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.3.3/css/swiper.min.css">
<!-- favicon settings --> <!-- favicon settings -->

Loading…
Cancel
Save