mirror of https://github.com/doccano/doccano.git
Hironsan
5 years ago
52 changed files with 13149 additions and 0 deletions
Split View
Diff Options
-
16frontend/.babelrc
-
17frontend/.eslintrc.js
-
88frontend/.gitignore
-
22frontend/README.md
-
7frontend/assets/README.md
-
2frontend/assets/style/app.styl
-
1frontend/assets/style/variables.styl
-
90frontend/components/EntityItem.vue
-
113frontend/components/EntityItemContainer.vue
-
79frontend/components/Logo.vue
-
68frontend/components/Modal.vue
-
7frontend/components/README.md
-
21frontend/components/VuetifyLogo.vue
-
85frontend/components/project/SideBarLeft.vue
-
208frontend/components/project/SideBarRight/SideBarLabeling.vue
-
17frontend/jest.config.js
-
38frontend/layouts/BaseLayout.vue
-
7frontend/layouts/README.md
-
61frontend/layouts/annotation.vue
-
50frontend/layouts/default.vue
-
44frontend/layouts/error.vue
-
37frontend/layouts/project.vue
-
10frontend/layouts/projectList.vue
-
8frontend/middleware/README.md
-
90frontend/nuxt.config.js
-
47frontend/package.json
-
6frontend/pages/README.md
-
116frontend/pages/index.vue
-
23frontend/pages/inspire.vue
-
205frontend/pages/projects/_id/annotation/index.vue
-
142frontend/pages/projects/_id/dataset/index.vue
-
9frontend/pages/projects/_id/download/index.vue
-
50frontend/pages/projects/_id/guideline/index.vue
-
116frontend/pages/projects/_id/index.vue
-
253frontend/pages/projects/_id/labels/index.vue
-
9frontend/pages/projects/_id/statistics/index.vue
-
120frontend/pages/projects/_id/upload/index.vue
-
218frontend/pages/projects/_id/users/index.vue
-
334frontend/pages/projects/index.vue
-
7frontend/plugins/README.md
-
15frontend/plugins/filters.js
-
8frontend/plugins/utils.js
-
11frontend/static/README.md
-
BINfrontend/static/favicon.ico
-
BINfrontend/static/images/hero.jpeg
-
BINfrontend/static/images/vuetify.png
-
BINfrontend/static/v.png
-
10frontend/store/README.md
-
9frontend/store/sidebar.js
-
55frontend/test/Modal.spec.js
-
18frontend/test/filters.spec.js
-
10182frontend/yarn.lock
@ -0,0 +1,16 @@ |
|||
{ |
|||
"env": { |
|||
"test": { |
|||
"presets": [ |
|||
[ |
|||
"@babel/preset-env", |
|||
{ |
|||
"targets": { |
|||
"node": "current" |
|||
} |
|||
} |
|||
] |
|||
] |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
module.exports = { |
|||
root: true, |
|||
env: { |
|||
browser: true, |
|||
node: true |
|||
}, |
|||
parserOptions: { |
|||
parser: 'babel-eslint' |
|||
}, |
|||
extends: [ |
|||
'@nuxtjs', |
|||
'plugin:nuxt/recommended' |
|||
], |
|||
// add your custom rules here
|
|||
rules: { |
|||
} |
|||
} |
@ -0,0 +1,88 @@ |
|||
# Created by .ignore support plugin (hsz.mobi) |
|||
### Node template |
|||
# Logs |
|||
logs |
|||
*.log |
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
|
|||
# Runtime data |
|||
pids |
|||
*.pid |
|||
*.seed |
|||
*.pid.lock |
|||
|
|||
# Directory for instrumented libs generated by jscoverage/JSCover |
|||
lib-cov |
|||
|
|||
# Coverage directory used by tools like istanbul |
|||
coverage |
|||
|
|||
# nyc test coverage |
|||
.nyc_output |
|||
|
|||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) |
|||
.grunt |
|||
|
|||
# Bower dependency directory (https://bower.io/) |
|||
bower_components |
|||
|
|||
# node-waf configuration |
|||
.lock-wscript |
|||
|
|||
# Compiled binary addons (https://nodejs.org/api/addons.html) |
|||
build/Release |
|||
|
|||
# Dependency directories |
|||
node_modules/ |
|||
jspm_packages/ |
|||
|
|||
# TypeScript v1 declaration files |
|||
typings/ |
|||
|
|||
# Optional npm cache directory |
|||
.npm |
|||
|
|||
# Optional eslint cache |
|||
.eslintcache |
|||
|
|||
# Optional REPL history |
|||
.node_repl_history |
|||
|
|||
# Output of 'npm pack' |
|||
*.tgz |
|||
|
|||
# Yarn Integrity file |
|||
.yarn-integrity |
|||
|
|||
# dotenv environment variables file |
|||
.env |
|||
|
|||
# parcel-bundler cache (https://parceljs.org/) |
|||
.cache |
|||
|
|||
# next.js build output |
|||
.next |
|||
|
|||
# nuxt.js build output |
|||
.nuxt |
|||
|
|||
# Nuxt generate |
|||
dist |
|||
|
|||
# vuepress build output |
|||
.vuepress/dist |
|||
|
|||
# Serverless directories |
|||
.serverless |
|||
|
|||
# IDE / Editor |
|||
.idea |
|||
.editorconfig |
|||
|
|||
# Service worker |
|||
sw.* |
|||
|
|||
# Mac OSX |
|||
.DS_Store |
@ -0,0 +1,22 @@ |
|||
# doccano-client |
|||
|
|||
> doccano client |
|||
|
|||
## Build Setup |
|||
|
|||
``` bash |
|||
# install dependencies |
|||
$ yarn install |
|||
|
|||
# serve with hot reload at localhost:3000 |
|||
$ yarn dev |
|||
|
|||
# build for production and launch server |
|||
$ yarn build |
|||
$ yarn start |
|||
|
|||
# generate static project |
|||
$ yarn generate |
|||
``` |
|||
|
|||
For detailed explanation on how things work, checkout [Nuxt.js docs](https://nuxtjs.org). |
@ -0,0 +1,7 @@ |
|||
# ASSETS |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). |
@ -0,0 +1,2 @@ |
|||
// Import Vuetify styling |
|||
@require '~vuetify/src/stylus/app.styl' |
@ -0,0 +1 @@ |
|||
@require '~vuetify/src/stylus/settings/_variables.styl' |
@ -0,0 +1,90 @@ |
|||
<template> |
|||
<span v-if="label" class="highlight bottom" :style="{ borderColor: color }"> |
|||
<span class="highlight__content">{{ content }}</span><span class="highlight__label" :data-label="label" :style="{backgroundColor: color}" @click="open" /> |
|||
</span> |
|||
<span v-else>{{ content }}</span> |
|||
</template> |
|||
|
|||
<script> |
|||
import { idealColor } from '~/plugins/utils.js' |
|||
|
|||
export default { |
|||
props: { |
|||
content: { |
|||
type: String, |
|||
default: '', |
|||
required: true |
|||
}, |
|||
label: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
color: { |
|||
type: String, |
|||
default: '#64FFDA' |
|||
} |
|||
}, |
|||
computed: { |
|||
textColor() { |
|||
return idealColor(this.color) |
|||
} |
|||
}, |
|||
methods: { |
|||
open() { |
|||
alert('hello') |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.highlight.blue { |
|||
background: #edf4fa !important; |
|||
} |
|||
.highlight.bottom { |
|||
display: block; |
|||
white-space: normal; |
|||
} |
|||
.highlight:first-child { |
|||
margin-left: 0; |
|||
} |
|||
.highlight { |
|||
border: 2px solid; |
|||
color: #232323; |
|||
margin: 4px 6px 4px 3px; |
|||
vertical-align: middle; |
|||
box-shadow: 2px 4px 20px rgba(0,0,0,.1); |
|||
position: relative; |
|||
cursor: default; |
|||
min-width: 26px; |
|||
line-height: 22px; |
|||
display: flex; |
|||
} |
|||
.highlight__content { |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
align-items: center; |
|||
padding: 2px 2px 0px 6px; |
|||
} |
|||
.highlight.bottom .highlight__content:after { |
|||
content: " "; |
|||
padding-right: 3px; |
|||
} |
|||
.highlight__label { |
|||
line-height: 14px; |
|||
padding-top: 1px; |
|||
align-items: center; |
|||
justify-content: center; |
|||
display: flex; |
|||
padding: 0 8px; |
|||
text-align: center; |
|||
-webkit-user-select: none; |
|||
-moz-user-select: none; |
|||
-ms-user-select: none; |
|||
user-select: none; |
|||
color: white; |
|||
} |
|||
.highlight__label::after { |
|||
content: attr(data-label); |
|||
} |
|||
</style> |
@ -0,0 +1,113 @@ |
|||
<template> |
|||
<div class="highlight-container highlight-container--bottom-labels" @mouseup="open"> |
|||
<entity-item v-for="(chunk, i) in chunks" :key="i" :content="chunk.text" :label="chunk.label" :color="chunk.color" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import EntityItem from '~/components/EntityItem' |
|||
|
|||
export default { |
|||
components: { |
|||
EntityItem |
|||
}, |
|||
props: { |
|||
content: { |
|||
type: String, |
|||
default: '', |
|||
required: true |
|||
}, |
|||
labels: { |
|||
type: Array, |
|||
default: () => ([]), |
|||
required: true |
|||
}, |
|||
entities: { |
|||
type: Array, |
|||
default: () => ([]), |
|||
required: true |
|||
} |
|||
}, |
|||
computed: { |
|||
sortedEntities() { |
|||
return this.entities.slice().sort((a, b) => a.start_offset - b.start_offset) |
|||
}, |
|||
|
|||
chunks() { |
|||
const chunks = [] |
|||
const entities = this.sortedEntities |
|||
let startOffset = 0 |
|||
for (const entity of entities) { |
|||
// add non-entities to chunks. |
|||
chunks.push({ |
|||
label: null, |
|||
color: null, |
|||
text: this.content.slice(startOffset, entity.start_offset) |
|||
}) |
|||
startOffset = entity.end_offset |
|||
|
|||
// add entities to chunks. |
|||
const label = this.labelObject[entity.label] |
|||
chunks.push({ |
|||
label: label.name, |
|||
color: label.color, |
|||
text: this.content.slice(entity.start_offset, entity.end_offset) |
|||
}) |
|||
} |
|||
// add the rest of text. |
|||
chunks.push({ |
|||
label: null, |
|||
color: null, |
|||
text: this.content.slice(startOffset, this.content.length) |
|||
}) |
|||
return chunks |
|||
}, |
|||
|
|||
labelObject() { |
|||
const obj = {} |
|||
for (const label of this.labels) { |
|||
obj[label.id] = label |
|||
} |
|||
return obj |
|||
} |
|||
}, |
|||
methods: { |
|||
open() { |
|||
let selection |
|||
// Modern browsers. |
|||
if (window.getSelection) { |
|||
selection = window.getSelection() |
|||
} else if (document.selection) { |
|||
selection = document.selection |
|||
} |
|||
// If something is selected. |
|||
if (selection.rangeCount > 0) { |
|||
const range = selection.getRangeAt(0) |
|||
const preSelectionRange = range.cloneRange() |
|||
preSelectionRange.selectNodeContents(this.$el) |
|||
preSelectionRange.setEnd(range.startContainer, range.startOffset) |
|||
const start = [...preSelectionRange.toString()].length |
|||
const end = start + [...range.toString()].length |
|||
alert(start + ' ' + end) |
|||
return end |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.highlight-container.highlight-container--bottom-labels { |
|||
align-items: flex-start; |
|||
} |
|||
.highlight-container { |
|||
line-height: 42px!important; |
|||
display: flex; |
|||
flex-wrap: wrap; |
|||
white-space: pre-wrap; |
|||
cursor: default; |
|||
} |
|||
.highlight-container.highlight-container--bottom-labels .highlight.bottom { |
|||
margin-top: 6px; |
|||
} |
|||
</style> |
@ -0,0 +1,79 @@ |
|||
<template> |
|||
<div class="VueToNuxtLogo"> |
|||
<div class="Triangle Triangle--two" /> |
|||
<div class="Triangle Triangle--one" /> |
|||
<div class="Triangle Triangle--three" /> |
|||
<div class="Triangle Triangle--four" /> |
|||
</div> |
|||
</template> |
|||
|
|||
<style> |
|||
.VueToNuxtLogo { |
|||
display: inline-block; |
|||
animation: turn 2s linear forwards 1s; |
|||
transform: rotateX(180deg); |
|||
position: relative; |
|||
overflow: hidden; |
|||
height: 180px; |
|||
width: 245px; |
|||
} |
|||
|
|||
.Triangle { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
width: 0; |
|||
height: 0; |
|||
} |
|||
|
|||
.Triangle--one { |
|||
border-left: 105px solid transparent; |
|||
border-right: 105px solid transparent; |
|||
border-bottom: 180px solid #41b883; |
|||
} |
|||
|
|||
.Triangle--two { |
|||
top: 30px; |
|||
left: 35px; |
|||
animation: goright 0.5s linear forwards 3.5s; |
|||
border-left: 87.5px solid transparent; |
|||
border-right: 87.5px solid transparent; |
|||
border-bottom: 150px solid #3b8070; |
|||
} |
|||
|
|||
.Triangle--three { |
|||
top: 60px; |
|||
left: 35px; |
|||
animation: goright 0.5s linear forwards 3.5s; |
|||
border-left: 70px solid transparent; |
|||
border-right: 70px solid transparent; |
|||
border-bottom: 120px solid #35495e; |
|||
} |
|||
|
|||
.Triangle--four { |
|||
top: 120px; |
|||
left: 70px; |
|||
animation: godown 0.5s linear forwards 3s; |
|||
border-left: 35px solid transparent; |
|||
border-right: 35px solid transparent; |
|||
border-bottom: 60px solid #fff; |
|||
} |
|||
|
|||
@keyframes turn { |
|||
100% { |
|||
transform: rotateX(0deg); |
|||
} |
|||
} |
|||
|
|||
@keyframes godown { |
|||
100% { |
|||
top: 180px; |
|||
} |
|||
} |
|||
|
|||
@keyframes goright { |
|||
100% { |
|||
left: 70px; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,68 @@ |
|||
<template> |
|||
<v-dialog |
|||
v-model="dialog" |
|||
width="800px" |
|||
> |
|||
<v-card> |
|||
<v-card-title class="grey lighten-2"> |
|||
{{ title }} |
|||
</v-card-title> |
|||
<v-container grid-list-sm> |
|||
<v-layout |
|||
wrap |
|||
> |
|||
<v-flex xs12> |
|||
<slot /> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
<v-card-actions> |
|||
<v-spacer /> |
|||
<v-btn |
|||
class="text-capitalize" |
|||
text |
|||
color="primary" |
|||
@click="dialog = false" |
|||
> |
|||
Cancel |
|||
</v-btn> |
|||
<v-btn |
|||
class="text-none" |
|||
text |
|||
@click="dialog = false" |
|||
> |
|||
{{ button }} |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-dialog> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
title: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
button: { |
|||
type: String, |
|||
default: 'Yes' |
|||
} |
|||
}, |
|||
data: () => ({ |
|||
dialog: false |
|||
}), |
|||
methods: { |
|||
open() { |
|||
this.dialog = true |
|||
}, |
|||
agree() { |
|||
this.dialog = false |
|||
}, |
|||
cancel() { |
|||
this.dialog = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,7 @@ |
|||
# COMPONENTS |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
The components directory contains your Vue.js Components. |
|||
|
|||
_Nuxt.js doesn't supercharge these components._ |
@ -0,0 +1,21 @@ |
|||
<template> |
|||
<img |
|||
class="VuetifyLogo" |
|||
alt="Vuetify Logo" |
|||
src="data:image/png;base64,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" |
|||
> |
|||
</template> |
|||
|
|||
<style> |
|||
.VuetifyLogo { |
|||
width: 180px; |
|||
transform: rotateY(560deg); |
|||
animation: turn 3.5s ease-out forwards 1s; |
|||
} |
|||
|
|||
@keyframes turn { |
|||
100% { |
|||
transform: rotateY(0deg); |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,85 @@ |
|||
<template> |
|||
<v-list |
|||
dense |
|||
class="" |
|||
> |
|||
<v-list-item> |
|||
<v-btn rounded color="white"> |
|||
<v-icon left> |
|||
mdi-plus |
|||
</v-icon> Start Labeling |
|||
</v-btn> |
|||
</v-list-item> |
|||
<template v-for="(item, i) in items"> |
|||
<v-layout |
|||
v-if="item.heading" |
|||
:key="i" |
|||
align-center |
|||
> |
|||
<v-flex xs6> |
|||
<v-subheader v-if="item.heading"> |
|||
{{ item.heading }} |
|||
</v-subheader> |
|||
</v-flex> |
|||
<v-flex |
|||
xs6 |
|||
class="text-right" |
|||
> |
|||
<v-btn |
|||
small |
|||
text |
|||
> |
|||
edit |
|||
</v-btn> |
|||
</v-flex> |
|||
</v-layout> |
|||
<v-divider |
|||
v-else-if="item.divider" |
|||
:key="i" |
|||
dark |
|||
class="my-4" |
|||
/> |
|||
<v-list-item |
|||
v-else |
|||
:key="i" |
|||
@click="$router.push('/projects/' + $route.params.id + '/' + item.link)" |
|||
> |
|||
<v-list-item-action> |
|||
<v-icon> |
|||
{{ item.icon }} |
|||
</v-icon> |
|||
</v-list-item-action> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
{{ item.text }} |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</template> |
|||
</v-list> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data: () => ({ |
|||
items: [ |
|||
// { icon: 'lightbulb_outline', text: 'Start Labeling' }, |
|||
{ divider: true }, |
|||
{ icon: 'mdi-database', text: 'Dataset', link: 'dataset' }, |
|||
{ icon: 'person', text: 'User', link: 'users' }, |
|||
{ icon: 'label', text: 'Label', link: 'labels' }, |
|||
{ divider: true }, |
|||
// { heading: 'Labels' }, |
|||
// { icon: 'add', text: 'Create new label', link: 'labels' }, |
|||
// { divider: true }, |
|||
{ icon: 'backup', text: 'Import', link: 'upload' }, |
|||
{ icon: 'archive', text: 'Export', link: 'download' }, |
|||
{ divider: true }, |
|||
{ icon: 'settings', text: 'Guideline', link: 'guideline' }, |
|||
{ icon: 'chat_bubble', text: 'Statistics', link: 'statistics' }, |
|||
{ icon: 'help', text: 'Help', link: 'help' } |
|||
// { icon: 'keyboard', text: 'Keyboard shortcuts' } |
|||
] |
|||
}) |
|||
} |
|||
</script> |
@ -0,0 +1,208 @@ |
|||
<template> |
|||
<v-navigation-drawer |
|||
:value="drawer" |
|||
app |
|||
clipped |
|||
right |
|||
> |
|||
<v-list dense> |
|||
<v-list-group |
|||
sub-group |
|||
value="true" |
|||
> |
|||
<template v-slot:activator> |
|||
<v-list-item> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
Progress |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</template> |
|||
<v-list-item class="pl-4"> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
<v-progress-linear |
|||
:value="progress" |
|||
height="25" |
|||
rounded |
|||
> |
|||
<strong>{{ Math.ceil(progress) }}%</strong> |
|||
</v-progress-linear> |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list-group> |
|||
|
|||
<v-list-group |
|||
sub-group |
|||
value="true" |
|||
> |
|||
<template v-slot:activator> |
|||
<v-list-item> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
Labels |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</template> |
|||
<v-list-item |
|||
v-for="(label, i) in labels" |
|||
:key="i" |
|||
class="pl-4" |
|||
> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
<v-chip |
|||
:color="label.color" |
|||
text-color="white" |
|||
> |
|||
<v-avatar left> |
|||
<span class="white--text">{{ label.shortcut }}</span> |
|||
</v-avatar> |
|||
{{ label.name }} |
|||
</v-chip> |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list-group> |
|||
|
|||
<v-list-item @click="showMetadata = true"> |
|||
<v-list-item-action> |
|||
<v-icon>mdi-file-document-box</v-icon> |
|||
</v-list-item-action> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
Show metadata |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
|
|||
<v-list-item @click="showGuideline = true"> |
|||
<v-list-item-action> |
|||
<v-icon>mdi-text-subject</v-icon> |
|||
</v-list-item-action> |
|||
<v-list-item-content> |
|||
<v-list-item-title> |
|||
Show guideline |
|||
</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list> |
|||
<v-dialog |
|||
v-model="showMetadata" |
|||
width="800" |
|||
> |
|||
<v-card> |
|||
<v-card-title |
|||
class="headline grey lighten-2" |
|||
primary-title |
|||
> |
|||
Metadata |
|||
</v-card-title> |
|||
|
|||
<v-card-text> |
|||
<v-sheet> |
|||
<pre>{{ prettyJson }}</pre> |
|||
</v-sheet> |
|||
</v-card-text> |
|||
|
|||
<v-divider /> |
|||
|
|||
<v-card-actions> |
|||
<v-spacer /> |
|||
<v-btn |
|||
color="primary" |
|||
text |
|||
@click="showMetadata = false" |
|||
> |
|||
Close |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-dialog> |
|||
<v-dialog |
|||
v-model="showGuideline" |
|||
width="800" |
|||
> |
|||
<v-card> |
|||
<v-card-title |
|||
class="headline grey lighten-2" |
|||
primary-title |
|||
> |
|||
Annotation Guideline |
|||
</v-card-title> |
|||
|
|||
<v-card-text> |
|||
<viewer |
|||
:value="guidelineText" |
|||
/> |
|||
</v-card-text> |
|||
|
|||
<v-divider /> |
|||
|
|||
<v-card-actions> |
|||
<v-spacer /> |
|||
<v-btn |
|||
color="primary" |
|||
text |
|||
@click="showGuideline = false" |
|||
> |
|||
Close |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-dialog> |
|||
</v-navigation-drawer> |
|||
</template> |
|||
|
|||
<script> |
|||
import 'tui-editor/dist/tui-editor-contents.css' |
|||
import 'highlight.js/styles/github.css' |
|||
import { Viewer } from '@toast-ui/vue-editor' |
|||
|
|||
export default { |
|||
components: { |
|||
Viewer |
|||
}, |
|||
|
|||
props: { |
|||
labels: { |
|||
type: Array, |
|||
default: () => ([]), |
|||
required: true |
|||
}, |
|||
progress: { |
|||
type: Number, |
|||
default: 0, |
|||
required: true |
|||
}, |
|||
metadata: { |
|||
type: String, |
|||
default: '{}', |
|||
required: true |
|||
}, |
|||
guidelineText: { |
|||
type: String, |
|||
default: '# This is Viewer.\n Hello World.' |
|||
} |
|||
}, |
|||
|
|||
data: () => ({ |
|||
showMetadata: false, |
|||
showGuideline: false |
|||
}), |
|||
|
|||
computed: { |
|||
drawer() { |
|||
return this.$store.state.sidebar.drawer |
|||
}, |
|||
prettyJson() { |
|||
const data = JSON.parse(this.metadata) |
|||
const pretty = JSON.stringify(data, null, 4) |
|||
return pretty |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,17 @@ |
|||
module.exports = { |
|||
moduleNameMapper: { |
|||
'^@/(.*)$': '<rootDir>/$1', |
|||
'^~/(.*)$': '<rootDir>/$1', |
|||
'^vue$': 'vue/dist/vue.common.js' |
|||
}, |
|||
moduleFileExtensions: ['js', 'vue', 'json'], |
|||
transform: { |
|||
'^.+\\.js$': 'babel-jest', |
|||
'.*\\.(vue)$': 'vue-jest' |
|||
}, |
|||
collectCoverage: true, |
|||
collectCoverageFrom: [ |
|||
'<rootDir>/components/**/*.vue', |
|||
'<rootDir>/pages/**/*.vue' |
|||
] |
|||
} |
@ -0,0 +1,38 @@ |
|||
<template> |
|||
<v-app id="keep"> |
|||
<v-app-bar |
|||
app |
|||
clipped-left |
|||
clipped-right |
|||
color="" |
|||
> |
|||
<slot name="leftDrawerIcon" /> |
|||
<nuxt-link to="/" class="top"> |
|||
<span class="title ml-3 mr-5">doccano</span> |
|||
</nuxt-link> |
|||
<v-text-field |
|||
solo-inverted |
|||
flat |
|||
hide-details |
|||
label="Search" |
|||
prepend-inner-icon="search" |
|||
/> |
|||
<v-spacer /> |
|||
<slot name="rightDrawerIcon" /> |
|||
</v-app-bar> |
|||
|
|||
<slot name="leftDrawer" /> |
|||
<slot name="rightDrawer" /> |
|||
|
|||
<slot name="content" /> |
|||
</v-app> |
|||
</template> |
|||
|
|||
<script> |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.top{ |
|||
text-decoration: none; |
|||
} |
|||
</style> |
@ -0,0 +1,7 @@ |
|||
# LAYOUTS |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
This directory contains your Application Layouts. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts). |
@ -0,0 +1,61 @@ |
|||
<template> |
|||
<base-layout> |
|||
<template #leftDrawerIcon> |
|||
<v-app-bar-nav-icon @click="drawerLeft = !drawerLeft" /> |
|||
</template> |
|||
|
|||
<template #rightDrawerIcon> |
|||
<v-app-bar-nav-icon @click="toggle" /> |
|||
</template> |
|||
|
|||
<template #leftDrawer> |
|||
<v-navigation-drawer |
|||
v-model="drawerLeft" |
|||
app |
|||
clipped |
|||
color="" |
|||
> |
|||
<side-bar-left /> |
|||
</v-navigation-drawer> |
|||
</template> |
|||
|
|||
<!-- |
|||
<template #rightDrawer> |
|||
<v-navigation-drawer |
|||
v-model="drawerRight" |
|||
app |
|||
clipped |
|||
right |
|||
> |
|||
<slot name="sideBarRightContent" /> |
|||
</v-navigation-drawer> |
|||
</template> |
|||
--> |
|||
|
|||
<template #content> |
|||
<nuxt /> |
|||
</template> |
|||
</base-layout> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapMutations } from 'vuex' |
|||
import BaseLayout from '~/layouts/BaseLayout' |
|||
import SideBarLeft from '~/components/project/SideBarLeft' |
|||
|
|||
export default { |
|||
components: { |
|||
BaseLayout, |
|||
SideBarLeft |
|||
}, |
|||
data: () => ({ |
|||
drawerLeft: false, |
|||
drawerRight: false |
|||
}), |
|||
methods: { |
|||
...mapMutations({ |
|||
toggle: 'sidebar/toggle' |
|||
}) |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,50 @@ |
|||
<template> |
|||
<v-app> |
|||
<v-app-bar |
|||
color="indigo lighten-1" |
|||
dark |
|||
app |
|||
> |
|||
<v-toolbar-title v-text="title" /> |
|||
</v-app-bar> |
|||
<nuxt /> |
|||
<v-footer |
|||
color="primary lighten-1" |
|||
padless |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
wrap |
|||
> |
|||
<v-flex |
|||
primary |
|||
lighten-2 |
|||
py-4 |
|||
text-center |
|||
white--text |
|||
xs12 |
|||
> |
|||
{{ new Date().getFullYear() }} — <strong>Vuetify</strong> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-footer> |
|||
</v-app> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
title: 'doccano', |
|||
links: [ |
|||
'Home', |
|||
'About Us', |
|||
'Team', |
|||
'Services', |
|||
'Blog', |
|||
'Contact Us' |
|||
] |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,44 @@ |
|||
<template> |
|||
<v-app dark> |
|||
<h1 v-if="error.statusCode === 404"> |
|||
{{ pageNotFound }} |
|||
</h1> |
|||
<h1 v-else> |
|||
{{ otherError }} |
|||
</h1> |
|||
<NuxtLink to="/"> |
|||
Home page |
|||
</NuxtLink> |
|||
</v-app> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
layout: 'empty', |
|||
props: { |
|||
error: { |
|||
type: Object, |
|||
default: null |
|||
} |
|||
}, |
|||
head() { |
|||
const title = |
|||
this.error.statusCode === 404 ? this.pageNotFound : this.otherError |
|||
return { |
|||
title |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
pageNotFound: '404 Not Found', |
|||
otherError: 'An error occurred' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
h1 { |
|||
font-size: 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,37 @@ |
|||
<template> |
|||
<base-layout> |
|||
<template #leftDrawerIcon> |
|||
<v-app-bar-nav-icon @click="drawerLeft = !drawerLeft" /> |
|||
</template> |
|||
|
|||
<template #leftDrawer> |
|||
<v-navigation-drawer |
|||
v-model="drawerLeft" |
|||
app |
|||
clipped |
|||
color="" |
|||
> |
|||
<side-bar-left /> |
|||
</v-navigation-drawer> |
|||
</template> |
|||
|
|||
<template #content> |
|||
<nuxt /> |
|||
</template> |
|||
</base-layout> |
|||
</template> |
|||
|
|||
<script> |
|||
import BaseLayout from '~/layouts/BaseLayout' |
|||
import SideBarLeft from '~/components/project/SideBarLeft' |
|||
|
|||
export default { |
|||
components: { |
|||
BaseLayout, |
|||
SideBarLeft |
|||
}, |
|||
data: () => ({ |
|||
drawerLeft: false |
|||
}) |
|||
} |
|||
</script> |
@ -0,0 +1,10 @@ |
|||
<template> |
|||
<v-app> |
|||
<nuxt /> |
|||
</v-app> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
} |
|||
</script> |
@ -0,0 +1,8 @@ |
|||
# MIDDLEWARE |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
This directory contains your application middleware. |
|||
Middleware let you define custom functions that can be run before rendering either a page or a group of pages. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). |
@ -0,0 +1,90 @@ |
|||
import colors from 'vuetify/es5/util/colors' |
|||
|
|||
export default { |
|||
mode: 'spa', |
|||
/* |
|||
** Headers of the page |
|||
*/ |
|||
head: { |
|||
titleTemplate: '%s - ' + process.env.npm_package_name, |
|||
title: process.env.npm_package_name || '', |
|||
meta: [ |
|||
{ charset: 'utf-8' }, |
|||
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }, |
|||
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' } |
|||
], |
|||
script: [ |
|||
{ src: 'https://use.fontawesome.com/releases/v5.0.6/js/all.js' } |
|||
], |
|||
link: [ |
|||
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, |
|||
{ |
|||
rel: 'stylesheet', |
|||
href: |
|||
'https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' |
|||
} |
|||
] |
|||
}, |
|||
/* |
|||
** Customize the progress-bar color |
|||
*/ |
|||
loading: { color: '#fff' }, |
|||
/* |
|||
** Global CSS |
|||
*/ |
|||
css: [ |
|||
], |
|||
/* |
|||
** Plugins to load before mounting the App |
|||
*/ |
|||
plugins: [ |
|||
'~/plugins/filters.js' |
|||
], |
|||
/* |
|||
** Nuxt.js modules |
|||
*/ |
|||
modules: [ |
|||
'@nuxtjs/vuetify', |
|||
// Doc: https://axios.nuxtjs.org/usage
|
|||
'@nuxtjs/axios', |
|||
'@nuxtjs/eslint-module' |
|||
], |
|||
/* |
|||
** Axios module configuration |
|||
** See https://axios.nuxtjs.org/options
|
|||
*/ |
|||
axios: { |
|||
}, |
|||
/* |
|||
** vuetify module configuration |
|||
** https://github.com/nuxt-community/vuetify-module
|
|||
*/ |
|||
vuetify: { |
|||
theme: { |
|||
primary: colors.blue.darken2, |
|||
accent: colors.grey.darken3, |
|||
secondary: colors.amber.darken3, |
|||
info: colors.teal.lighten1, |
|||
warning: colors.amber.base, |
|||
error: colors.deepOrange.accent4, |
|||
success: colors.green.accent3 |
|||
} |
|||
}, |
|||
/* |
|||
** Build configuration |
|||
*/ |
|||
build: { |
|||
/* |
|||
** You can extend webpack config here |
|||
*/ |
|||
extend(config, ctx) { |
|||
config.module.rules.push({ |
|||
test: /\.(txt|csv|conll|jsonl)$/i, |
|||
loader: 'file-loader', |
|||
options: { |
|||
name: '[path][name].[ext]' |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,47 @@ |
|||
{ |
|||
"name": "doccano-client", |
|||
"version": "1.0.0", |
|||
"description": "doccano client", |
|||
"author": "Hironsan", |
|||
"private": true, |
|||
"scripts": { |
|||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .", |
|||
"precommit": "yarn lint", |
|||
"test": "jest", |
|||
"dev": "nuxt", |
|||
"build": "nuxt build", |
|||
"start": "nuxt start", |
|||
"generate": "nuxt generate" |
|||
}, |
|||
"dependencies": { |
|||
"@nuxtjs/axios": "^5.3.6", |
|||
"@nuxtjs/vuetify": "^1.0.2", |
|||
"@toast-ui/vue-editor": "^1.1.1", |
|||
"codemirror": "^5.48.2", |
|||
"nuxt": "^2.0.0", |
|||
"tui-editor": "^1.4.5", |
|||
"vuetify": "^2.0.2" |
|||
}, |
|||
"devDependencies": { |
|||
"@nuxtjs/eslint-config": "^0.0.1", |
|||
"@nuxtjs/eslint-module": "^0.0.1", |
|||
"@vue/test-utils": "^1.0.0-beta.27", |
|||
"babel-core": "7.0.0-bridge.0", |
|||
"babel-eslint": "^10.0.1", |
|||
"babel-jest": "^24.1.0", |
|||
"eslint": "^5.15.1", |
|||
"eslint-config-standard": ">=12.0.0", |
|||
"eslint-plugin-import": ">=2.16.0", |
|||
"eslint-plugin-jest": ">=22.3.0", |
|||
"eslint-plugin-node": ">=8.0.1", |
|||
"eslint-plugin-nuxt": ">=0.4.2", |
|||
"eslint-plugin-promise": ">=4.0.1", |
|||
"eslint-plugin-standard": ">=4.0.0", |
|||
"eslint-plugin-vue": "^5.2.2", |
|||
"jest": "^24.1.0", |
|||
"nodemon": "^1.18.9", |
|||
"stylus": "^0.54.5", |
|||
"stylus-loader": "^3.0.2", |
|||
"vue-jest": "^3.0.3" |
|||
} |
|||
} |
@ -0,0 +1,6 @@ |
|||
# PAGES |
|||
|
|||
This directory contains your Application Views and Routes. |
|||
The framework reads all the `*.vue` files inside this directory and creates the router of your application. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing). |
@ -0,0 +1,116 @@ |
|||
<template> |
|||
<v-content> |
|||
<section> |
|||
<v-parallax src="/images/hero.jpeg" height="600"> |
|||
<v-layout |
|||
column |
|||
align-center |
|||
justify-center |
|||
class="white--text" |
|||
> |
|||
<img src="/images/vuetify.png" alt="Vuetify.js" height="200"> |
|||
<h1 class="white--text mb-2 display-1 text-xs-center"> |
|||
Text Annotation for Human |
|||
</h1> |
|||
<div class="subheading mb-3 text-xs-center"> |
|||
Just create project, upload data and start annotation. You can build dataset in hours. |
|||
</div> |
|||
<v-btn |
|||
class="blue lighten-2 mt-5" |
|||
dark |
|||
large |
|||
href="/pre-made-themes" |
|||
> |
|||
Get Started |
|||
</v-btn> |
|||
</v-layout> |
|||
</v-parallax> |
|||
</section> |
|||
<section> |
|||
<v-layout |
|||
column |
|||
wrap |
|||
class="my-5" |
|||
align-center |
|||
> |
|||
<v-flex xs12 sm4 class="my-3"> |
|||
<div class="text-xs-center"> |
|||
<h2 class="headline"> |
|||
The best features |
|||
</h2> |
|||
</div> |
|||
</v-flex> |
|||
<v-flex xs12> |
|||
<v-container grid-list-xl> |
|||
<v-layout row wrap align-center> |
|||
<v-flex xs12 md4> |
|||
<v-card class="elevation-0 transparent"> |
|||
<v-card-text class="text-xs-center"> |
|||
<v-icon x-large class="blue--text text--lighten-2"> |
|||
color_lens |
|||
</v-icon> |
|||
</v-card-text> |
|||
<v-card-title primary-title class="layout justify-center"> |
|||
<div class="headline text-xs-center"> |
|||
Team Collaboration |
|||
</div> |
|||
</v-card-title> |
|||
<v-card-text class="subheading"> |
|||
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare. |
|||
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. |
|||
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti. |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
<v-flex xs12 md4> |
|||
<v-card class="elevation-0 transparent"> |
|||
<v-card-text class="text-xs-center"> |
|||
<v-icon x-large class="blue--text text--lighten-2"> |
|||
flash_on |
|||
</v-icon> |
|||
</v-card-text> |
|||
<v-card-title primary-title class="layout justify-center"> |
|||
<div class="headline"> |
|||
Multi Language |
|||
</div> |
|||
</v-card-title> |
|||
<v-card-text class="subheading"> |
|||
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare. |
|||
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. |
|||
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti. |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
<v-flex xs12 md4> |
|||
<v-card class="elevation-0 transparent"> |
|||
<v-card-text class="text-xs-center"> |
|||
<v-icon x-large class="blue--text text--lighten-2"> |
|||
build |
|||
</v-icon> |
|||
</v-card-text> |
|||
<v-card-title primary-title class="layout justify-center"> |
|||
<div class="headline text-xs-center"> |
|||
Completely Open Sourced |
|||
</div> |
|||
</v-card-title> |
|||
<v-card-text class="subheading"> |
|||
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare. |
|||
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. |
|||
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti. |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-flex> |
|||
</v-layout> |
|||
</section> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: { |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,23 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container> |
|||
<v-layout> |
|||
<v-flex text-xs-center> |
|||
<img |
|||
src="/v.png" |
|||
alt="Vuetify.js" |
|||
class="mb-5" |
|||
> |
|||
<blockquote class="blockquote"> |
|||
“First, solve the problem. Then, write the code.” |
|||
<footer> |
|||
<small> |
|||
<em>—John Johnson</em> |
|||
</small> |
|||
</footer> |
|||
</blockquote> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</template> |
@ -0,0 +1,205 @@ |
|||
<template> |
|||
<div> |
|||
<side-bar-labeling |
|||
:labels="labels" |
|||
:progress="progress" |
|||
:metadata="metadata" |
|||
/> |
|||
<v-content> |
|||
<v-container fluid fill-height> |
|||
<v-layout justify-center> |
|||
<v-flex> |
|||
<v-card> |
|||
<v-card-text class="title"> |
|||
<entity-item-container :content="text" :labels="labels" :entities="annotations" /> |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import EntityItemContainer from '~/components/EntityItemContainer' |
|||
import SideBarLabeling from '~/components/project/SideBarRight/SideBarLabeling' |
|||
|
|||
export default { |
|||
layout: 'annotation', |
|||
components: { |
|||
EntityItemContainer, |
|||
SideBarLabeling |
|||
}, |
|||
data: () => ({ |
|||
progress: 30, |
|||
metadata: '{"wikiPageId":2}', |
|||
search: '', |
|||
content: 'Sony', |
|||
text: |
|||
'Barack Hussein Obama II (born August 4, 1961) is an American attorney and politician who served as the 44th president of the United States from 2009 to 2017. A member of the Democratic Party, he was the first African American to be elected to the presidency. He previously served as a U.S. senator from Illinois from 2005 to 2008 and an Illinois state senator from 1997 to 2004.', |
|||
labelName: 'ORG', |
|||
labels: [ |
|||
{ |
|||
id: 1, |
|||
name: 'Location', |
|||
color: '#E91E63', |
|||
shortcut: 'l' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
name: 'Organization', |
|||
color: '#03A9F4', |
|||
shortcut: 'o' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
name: 'Person', |
|||
color: '#009688', |
|||
shortcut: 'p' |
|||
}, |
|||
{ |
|||
id: 4, |
|||
name: 'Date', |
|||
color: '#FF6F00', |
|||
shortcut: 'd' |
|||
}, |
|||
{ |
|||
id: 5, |
|||
name: 'Other', |
|||
color: '#333333', |
|||
shortcut: 't' |
|||
} |
|||
], |
|||
annotations: [ |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 3, |
|||
start_offset: 0, |
|||
end_offset: 23, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 3, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 30, |
|||
end_offset: 44, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 1, |
|||
start_offset: 125, |
|||
end_offset: 138, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 144, |
|||
end_offset: 148, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 152, |
|||
end_offset: 156, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 2, |
|||
start_offset: 174, |
|||
end_offset: 190, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 1, |
|||
start_offset: 285, |
|||
end_offset: 289, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 1, |
|||
start_offset: 303, |
|||
end_offset: 311, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 317, |
|||
end_offset: 321, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 325, |
|||
end_offset: 329, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 1, |
|||
start_offset: 337, |
|||
end_offset: 345, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 365, |
|||
end_offset: 369, |
|||
user: 1, |
|||
document: 1 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
prob: 0.0, |
|||
label: 4, |
|||
start_offset: 373, |
|||
end_offset: 377, |
|||
user: 1, |
|||
document: 1 |
|||
} |
|||
] |
|||
}), |
|||
|
|||
methods: { |
|||
save() {}, |
|||
cancel() {}, |
|||
open() {}, |
|||
close() {} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
</style> |
@ -0,0 +1,142 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
> |
|||
<v-flex> |
|||
<v-card> |
|||
<v-card-title> |
|||
<v-btn |
|||
class="mb-2 text-capitalize" |
|||
outlined |
|||
:disabled="selected.length === 0" |
|||
@click="openRemoveModal" |
|||
> |
|||
Remove |
|||
</v-btn> |
|||
<Modal |
|||
ref="removeDialogue" |
|||
:title="removeModal.title" |
|||
:button="removeModal.button" |
|||
> |
|||
Are you sure you want to remove these documents from this project? |
|||
<v-list dense> |
|||
<v-list-item v-for="(doc, i) in selected" :key="i"> |
|||
<v-list-item-content> |
|||
<v-list-item-title>{{ doc.text | truncate(50) }}</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list> |
|||
</Modal> |
|||
</v-card-title> |
|||
<v-data-table |
|||
v-model="selected" |
|||
:headers="headers" |
|||
:items="docs" |
|||
item-key="id" |
|||
:search="search" |
|||
show-select |
|||
> |
|||
<template v-slot:top> |
|||
<v-text-field |
|||
v-model="search" |
|||
prepend-inner-icon="search" |
|||
label="Search" |
|||
single-line |
|||
hide-details |
|||
filled |
|||
/> |
|||
</template> |
|||
<template v-slot:item.text="{ item }"> |
|||
<v-edit-dialog |
|||
:return-value.sync="item.text" |
|||
large |
|||
> |
|||
<span class="d-flex d-sm-none">{{ item.text | truncate(50) }}</span> |
|||
<span class="d-none d-sm-flex">{{ item.text | truncate(200) }}</span> |
|||
<!--{{ item.text | truncate(200) }}--> |
|||
<template v-slot:input> |
|||
<v-textarea |
|||
v-model="item.text" |
|||
label="Edit" |
|||
/> |
|||
</template> |
|||
</v-edit-dialog> |
|||
</template> |
|||
</v-data-table> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
import Modal from '~/components/Modal' |
|||
|
|||
export default { |
|||
layout: 'project', |
|||
components: { |
|||
Modal |
|||
}, |
|||
data: () => ({ |
|||
search: '', |
|||
selected: [], |
|||
removeModal: { |
|||
title: 'Remove Document', |
|||
button: 'Yes, remove' |
|||
}, |
|||
headers: [ |
|||
{ |
|||
text: 'Text', |
|||
align: 'left', |
|||
value: 'text' |
|||
} |
|||
], |
|||
docs: [ |
|||
{ |
|||
id: 1, |
|||
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
text: 'Text 1' |
|||
}, |
|||
{ |
|||
id: 3, |
|||
text: 'Text 2' |
|||
}, |
|||
{ |
|||
id: 4, |
|||
text: 'Text 3' |
|||
}, |
|||
{ |
|||
id: 5, |
|||
text: 'Text 4' |
|||
} |
|||
] |
|||
}), |
|||
|
|||
methods: { |
|||
save() { |
|||
// send server |
|||
}, |
|||
cancel() { |
|||
}, |
|||
open() { |
|||
}, |
|||
close() { |
|||
}, |
|||
openAddModal() { |
|||
this.$refs.childDialogue.open() |
|||
}, |
|||
openRemoveModal() { |
|||
this.$refs.removeDialogue.open() |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,9 @@ |
|||
<template> |
|||
<div /> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
layout: 'project' |
|||
} |
|||
</script> |
@ -0,0 +1,50 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
> |
|||
<v-flex fill-height> |
|||
<editor |
|||
v-model="editorText" |
|||
:options="editorOptions" |
|||
:visible="editorVisible" |
|||
preview-style="vertical" |
|||
height="inherit" |
|||
/> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
import 'tui-editor/dist/tui-editor.css' |
|||
import 'tui-editor/dist/tui-editor-contents.css' |
|||
import 'codemirror/lib/codemirror.css' |
|||
import { Editor } from '@toast-ui/vue-editor' |
|||
|
|||
export default { |
|||
layout: 'project', |
|||
components: { |
|||
Editor |
|||
}, |
|||
data() { |
|||
return { |
|||
editorText: 'Write annotation guideline.', |
|||
editorOptions: { |
|||
}, |
|||
editorVisible: true |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
.te-md-container .CodeMirror, .tui-editor-contents { |
|||
font-size: 20px; |
|||
} |
|||
</style> |
@ -0,0 +1,116 @@ |
|||
<template> |
|||
<v-content> |
|||
<section> |
|||
<v-parallax src="/images/hero.jpeg" height="600"> |
|||
<v-layout |
|||
column |
|||
align-center |
|||
justify-center |
|||
class="white--text" |
|||
> |
|||
<img src="/images/vuetify.png" alt="Vuetify.js" height="200"> |
|||
<h1 class="white--text mb-2 display-1 text-xs-center"> |
|||
Text Annotation for Human |
|||
</h1> |
|||
<div class="subheading mb-3 text-xs-center"> |
|||
Just create project, upload data and start annotation. You can build dataset in hours. |
|||
</div> |
|||
<v-btn |
|||
class="blue lighten-2 mt-5" |
|||
dark |
|||
large |
|||
href="/pre-made-themes" |
|||
> |
|||
Get Started |
|||
</v-btn> |
|||
</v-layout> |
|||
</v-parallax> |
|||
</section> |
|||
<section> |
|||
<v-layout |
|||
column |
|||
wrap |
|||
class="my-5" |
|||
align-center |
|||
> |
|||
<v-flex xs12 sm4 class="my-3"> |
|||
<div class="text-xs-center"> |
|||
<h2 class="headline"> |
|||
The best features |
|||
</h2> |
|||
</div> |
|||
</v-flex> |
|||
<v-flex xs12> |
|||
<v-container grid-list-xl> |
|||
<v-layout row wrap align-center> |
|||
<v-flex xs12 md4> |
|||
<v-card class="elevation-0 transparent"> |
|||
<v-card-text class="text-xs-center"> |
|||
<v-icon x-large class="blue--text text--lighten-2"> |
|||
color_lens |
|||
</v-icon> |
|||
</v-card-text> |
|||
<v-card-title primary-title class="layout justify-center"> |
|||
<div class="headline text-xs-center"> |
|||
Team Collaboration |
|||
</div> |
|||
</v-card-title> |
|||
<v-card-text class="subheading"> |
|||
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare. |
|||
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. |
|||
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti. |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
<v-flex xs12 md4> |
|||
<v-card class="elevation-0 transparent"> |
|||
<v-card-text class="text-xs-center"> |
|||
<v-icon x-large class="blue--text text--lighten-2"> |
|||
flash_on |
|||
</v-icon> |
|||
</v-card-text> |
|||
<v-card-title primary-title class="layout justify-center"> |
|||
<div class="headline"> |
|||
Multi Language |
|||
</div> |
|||
</v-card-title> |
|||
<v-card-text class="subheading"> |
|||
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare. |
|||
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. |
|||
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti. |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
<v-flex xs12 md4> |
|||
<v-card class="elevation-0 transparent"> |
|||
<v-card-text class="text-xs-center"> |
|||
<v-icon x-large class="blue--text text--lighten-2"> |
|||
build |
|||
</v-icon> |
|||
</v-card-text> |
|||
<v-card-title primary-title class="layout justify-center"> |
|||
<div class="headline text-xs-center"> |
|||
Completely Open Sourced |
|||
</div> |
|||
</v-card-title> |
|||
<v-card-text class="subheading"> |
|||
Cras facilisis mi vitae nunc lobortis pharetra. Nulla volutpat tincidunt ornare. |
|||
Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. |
|||
Nullam in aliquet odio. Aliquam eu est vitae tellus bibendum tincidunt. Suspendisse potenti. |
|||
</v-card-text> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-flex> |
|||
</v-layout> |
|||
</section> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: { |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,253 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
> |
|||
<v-flex> |
|||
<v-card> |
|||
<v-card-title> |
|||
<v-btn |
|||
class="mb-2 text-capitalize" |
|||
color="primary" |
|||
@click="openAddModal" |
|||
> |
|||
Add Label |
|||
</v-btn> |
|||
<Modal |
|||
ref="childDialogue" |
|||
:title="addModal.title" |
|||
:button="addModal.button" |
|||
> |
|||
<v-text-field |
|||
label="Label name" |
|||
prepend-icon="label" |
|||
/> |
|||
<v-select |
|||
:items="keys" |
|||
label="Key" |
|||
prepend-icon="mdi-keyboard" |
|||
/> |
|||
<v-color-picker |
|||
v-model="color" |
|||
show-swatches |
|||
hide-mode-switch |
|||
width="800" |
|||
:mode.sync="mode" |
|||
class="ma-2" |
|||
/> |
|||
</Modal> |
|||
<v-btn |
|||
class="mb-2 ml-2 text-capitalize" |
|||
outlined |
|||
:disabled="selected.length === 0" |
|||
@click="openRemoveModal" |
|||
> |
|||
Remove |
|||
</v-btn> |
|||
<Modal |
|||
ref="removeDialogue" |
|||
:title="removeModal.title" |
|||
:button="removeModal.button" |
|||
> |
|||
Are you sure you want to remove these labels from this project? |
|||
<v-list dense> |
|||
<v-list-item v-for="(label, i) in selected" :key="i"> |
|||
<v-list-item-content> |
|||
<v-list-item-title>{{ label.name }}</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list> |
|||
</Modal> |
|||
</v-card-title> |
|||
<v-data-table |
|||
v-model="selected" |
|||
:headers="headers" |
|||
:items="labels" |
|||
item-key="id" |
|||
:search="search" |
|||
show-select |
|||
> |
|||
<template v-slot:top> |
|||
<v-text-field |
|||
v-model="search" |
|||
prepend-inner-icon="search" |
|||
label="Search" |
|||
single-line |
|||
hide-details |
|||
filled |
|||
/> |
|||
</template> |
|||
<template v-slot:item.name="{ item }"> |
|||
<v-edit-dialog |
|||
:return-value.sync="item.name" |
|||
> |
|||
{{ item.name }} |
|||
<template v-slot:input> |
|||
<v-text-field |
|||
v-model="item.name" |
|||
label="Edit" |
|||
single-line |
|||
/> |
|||
</template> |
|||
</v-edit-dialog> |
|||
</template> |
|||
<template v-slot:item.shortcut="{ item }"> |
|||
<v-edit-dialog |
|||
:return-value.sync="item.shortcut" |
|||
large |
|||
persistent |
|||
@save="save" |
|||
> |
|||
<div>{{ item.shortcut }}</div> |
|||
<template v-slot:input> |
|||
<div class="mt-4 title"> |
|||
Update key |
|||
</div> |
|||
</template> |
|||
<template v-slot:input> |
|||
<v-select |
|||
v-model="item.shortcut" |
|||
:items="keys" |
|||
label="Key" |
|||
/> |
|||
</template> |
|||
</v-edit-dialog> |
|||
</template> |
|||
<template v-slot:item.color="{ item }"> |
|||
<v-edit-dialog |
|||
:return-value.sync="item.color" |
|||
large |
|||
persistent |
|||
@save="save" |
|||
> |
|||
<v-chip :color="item.color" dark> |
|||
{{ item.color }} |
|||
</v-chip> |
|||
<template v-slot:input> |
|||
<div class="mt-4 title"> |
|||
Update color |
|||
</div> |
|||
</template> |
|||
<template v-slot:input> |
|||
<v-color-picker |
|||
v-model="item.color" |
|||
show-swatches |
|||
hide-mode-switch |
|||
width="800" |
|||
:mode.sync="mode" |
|||
class="ma-2" |
|||
/> |
|||
</template> |
|||
</v-edit-dialog> |
|||
</template> |
|||
</v-data-table> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
import Modal from '~/components/Modal' |
|||
|
|||
export default { |
|||
layout: 'project', |
|||
components: { |
|||
Modal |
|||
}, |
|||
data: () => ({ |
|||
dialog: false, |
|||
search: '', |
|||
isLoading: false, |
|||
selected: [], |
|||
selectedUser: null, |
|||
keys: 'abcdefghijklmnopqrstuvwxyz'.split(''), |
|||
mode: 'hexa', |
|||
color: '#FF00FF', |
|||
addModal: { |
|||
title: 'Add Label', |
|||
button: 'Add Label' |
|||
}, |
|||
removeModal: { |
|||
title: 'Remove Label', |
|||
button: 'Yes, remove' |
|||
}, |
|||
headers: [ |
|||
{ |
|||
text: 'Name', |
|||
align: 'left', |
|||
value: 'name' |
|||
}, |
|||
{ |
|||
text: 'Shortkey', |
|||
value: 'shortcut' |
|||
}, |
|||
{ |
|||
text: 'Color', |
|||
sortable: false, |
|||
value: 'color' |
|||
} |
|||
], |
|||
labels: [ |
|||
{ |
|||
id: 1, |
|||
name: 'Location', |
|||
color: '#E91E63', |
|||
shortcut: 'l', |
|||
fat: 6.0 |
|||
}, |
|||
{ |
|||
id: 2, |
|||
name: 'Organization', |
|||
color: '#03A9F4', |
|||
shortcut: 'o', |
|||
fat: 9.0 |
|||
}, |
|||
{ |
|||
id: 3, |
|||
name: 'Person', |
|||
color: '#009688', |
|||
shortcut: 'p', |
|||
fat: 16.0 |
|||
}, |
|||
{ |
|||
id: 4, |
|||
name: 'Money', |
|||
color: '#FF6F00', |
|||
shortcut: 'm', |
|||
fat: 3.7 |
|||
}, |
|||
{ |
|||
id: 5, |
|||
name: 'Other', |
|||
color: '#333333', |
|||
shortcut: 't', |
|||
fat: 16.0 |
|||
} |
|||
] |
|||
}), |
|||
|
|||
methods: { |
|||
save() { |
|||
// send server |
|||
}, |
|||
cancel() { |
|||
}, |
|||
open() { |
|||
}, |
|||
close() { |
|||
}, |
|||
openAddModal() { |
|||
this.$refs.childDialogue.open() |
|||
}, |
|||
openRemoveModal() { |
|||
this.$refs.removeDialogue.open() |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,9 @@ |
|||
<template> |
|||
<div /> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
layout: 'project' |
|||
} |
|||
</script> |
@ -0,0 +1,120 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout> |
|||
<v-flex> |
|||
<v-form |
|||
ref="form" |
|||
lazy-validation |
|||
> |
|||
<v-card> |
|||
<v-card flat> |
|||
<v-card-title> |
|||
Objective |
|||
</v-card-title> |
|||
<v-card-text> |
|||
<v-radio-group v-model="selectedTask"> |
|||
<v-radio |
|||
v-for="(task, i) in tasks" |
|||
:key="i" |
|||
:label="task" |
|||
:value="task" |
|||
/> |
|||
</v-radio-group> |
|||
</v-card-text> |
|||
</v-card> |
|||
|
|||
<v-card flat max-width="800"> |
|||
<v-card-title> |
|||
Import text items |
|||
</v-card-title> |
|||
<v-card-text> |
|||
<v-radio-group v-model="selectedFormat"> |
|||
<v-radio |
|||
v-for="(format, i) in formats" |
|||
:key="i" |
|||
:label="format.text" |
|||
:value="format" |
|||
/> |
|||
</v-radio-group> |
|||
<v-sheet color="black white--text" class="pa-3"> |
|||
{{ selectedFormat }} |
|||
</v-sheet> |
|||
</v-card-text> |
|||
</v-card> |
|||
|
|||
<v-card flat max-width="500"> |
|||
<v-card-title> |
|||
Select file |
|||
</v-card-title> |
|||
<v-card-text> |
|||
<v-file-input :accept="acceptType" label="File input" /> |
|||
</v-card-text> |
|||
</v-card> |
|||
|
|||
<v-card-actions> |
|||
<v-btn> |
|||
Import Dataset |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-form> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
layout: 'project', |
|||
data() { |
|||
return { |
|||
selectedTask: null, |
|||
selectedFormat: null, |
|||
tasks: [ |
|||
'Text Classification', |
|||
'Sequence Labeling', |
|||
'Seq2seq' |
|||
], |
|||
formats: [ |
|||
{ |
|||
type: 'csv', |
|||
text: 'Upload a CSV file from your computer', |
|||
accept: '.csv' |
|||
}, |
|||
{ |
|||
type: 'plain', |
|||
text: 'Upload text items from your computer', |
|||
accept: '.txt' |
|||
}, |
|||
{ |
|||
type: 'json', |
|||
text: 'Upload a JSON file from your computer', |
|||
accept: '.json,.jsonl' |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
computed: { |
|||
acceptType() { |
|||
if (this.selectedFormat) { |
|||
return this.selectedFormat.accept |
|||
} else { |
|||
return '.txt,.csv,.json,.jsonl' |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
body pre { |
|||
color: white; |
|||
} |
|||
</style> |
@ -0,0 +1,218 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout |
|||
justify-center |
|||
> |
|||
<v-flex> |
|||
<v-card> |
|||
<v-card-title> |
|||
<v-btn |
|||
class="mb-2 text-capitalize" |
|||
color="primary" |
|||
@click="openAddModal" |
|||
> |
|||
Add User |
|||
</v-btn> |
|||
<Modal |
|||
ref="childDialogue" |
|||
:title="addModal.title" |
|||
:button="addModal.button" |
|||
> |
|||
<v-autocomplete |
|||
v-model="selectedUser" |
|||
:items="items" |
|||
:loading="isLoading" |
|||
:search-input.sync="username" |
|||
color="white" |
|||
hide-no-data |
|||
hide-selected |
|||
item-text="username" |
|||
label="User Search APIs" |
|||
placeholder="Start typing to Search" |
|||
prepend-icon="mdi-account" |
|||
return-object |
|||
/> |
|||
<v-select |
|||
:items="roles" |
|||
label="Role" |
|||
prepend-icon="mdi-account-card-details-outline" |
|||
/> |
|||
</Modal> |
|||
<v-btn |
|||
class="mb-2 ml-2 text-capitalize" |
|||
outlined |
|||
:disabled="selected.length === 0" |
|||
@click="openRemoveModal" |
|||
> |
|||
Remove |
|||
</v-btn> |
|||
<Modal |
|||
ref="removeDialogue" |
|||
:title="removeModal.title" |
|||
:button="removeModal.button" |
|||
> |
|||
Are you sure you want to remove these users from this project? |
|||
<v-list dense> |
|||
<v-list-item v-for="(user, i) in selected" :key="i"> |
|||
<v-list-item-content> |
|||
<v-list-item-title>{{ user.name }}</v-list-item-title> |
|||
</v-list-item-content> |
|||
</v-list-item> |
|||
</v-list> |
|||
</Modal> |
|||
</v-card-title> |
|||
<v-data-table |
|||
v-model="selected" |
|||
:headers="headers" |
|||
:items="users" |
|||
item-key="name" |
|||
:search="search" |
|||
show-select |
|||
> |
|||
<template v-slot:top> |
|||
<v-text-field |
|||
v-model="search" |
|||
prepend-inner-icon="search" |
|||
label="Search" |
|||
single-line |
|||
hide-details |
|||
filled |
|||
/> |
|||
</template> |
|||
<template v-slot:item.role="props"> |
|||
<v-edit-dialog |
|||
:return-value.sync="props.item.role" |
|||
large |
|||
persistent |
|||
@save="save" |
|||
> |
|||
<div>{{ props.item.role }}</div> |
|||
<template v-slot:input> |
|||
<div class="mt-4 title"> |
|||
Update Role |
|||
</div> |
|||
</template> |
|||
<template v-slot:input> |
|||
<v-select |
|||
v-model="props.item.role" |
|||
:items="roles" |
|||
label="Role" |
|||
/> |
|||
</template> |
|||
</v-edit-dialog> |
|||
</template> |
|||
</v-data-table> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
import Modal from '~/components/Modal' |
|||
|
|||
export default { |
|||
layout: 'project', |
|||
components: { |
|||
Modal |
|||
}, |
|||
data: () => ({ |
|||
search: '', |
|||
username: '', |
|||
isLoading: false, |
|||
selected: [], |
|||
selectedUser: null, |
|||
roles: ['Admin', 'Member'], |
|||
addModal: { |
|||
title: 'Add User', |
|||
button: 'Add User' |
|||
}, |
|||
removeModal: { |
|||
title: 'Remove User', |
|||
button: 'Yes, remove' |
|||
}, |
|||
headers: [ |
|||
{ |
|||
text: 'Name', |
|||
align: 'left', |
|||
sortable: false, |
|||
value: 'name' |
|||
}, |
|||
{ text: 'Role', value: 'role' } |
|||
], |
|||
users: [ |
|||
{ |
|||
name: 'Hiroki Nakayama', |
|||
role: 'Admin' |
|||
}, |
|||
{ |
|||
name: 'Takahiro Kubo', |
|||
role: 'Member' |
|||
}, |
|||
{ |
|||
name: 'Junya Kamura', |
|||
role: 'Member' |
|||
}, |
|||
{ |
|||
name: 'Yasufumi Taniguchi', |
|||
role: 'Member' |
|||
}, |
|||
{ |
|||
name: 'Ryo Sho', |
|||
role: 'Member' |
|||
} |
|||
], |
|||
items: [ |
|||
{ |
|||
id: 1, |
|||
username: 'Donald Trump', |
|||
Description: 'Daily cat facts' |
|||
}, |
|||
{ |
|||
id: 2, |
|||
username: 'Barack Obama', |
|||
Description: 'Pictures of cats from Tumblr' |
|||
} |
|||
] |
|||
}), |
|||
|
|||
watch: { |
|||
username(val) { |
|||
// Items have already been requested |
|||
if (this.isLoading) return |
|||
|
|||
this.isLoading = true |
|||
|
|||
// Lazily load input items |
|||
// GET /users endpoint |
|||
// fetch('https://api.publicapis.org/entries') |
|||
// .then(res => res.json()) |
|||
// .then((res) => { |
|||
// this.items.push({ username: 'Bush', id: this.items.length + 1 }) |
|||
// }) |
|||
// .catch((err) => { |
|||
// alert(err) |
|||
// }) |
|||
// .finally(() => (this.isLoading = false)) |
|||
} |
|||
}, |
|||
|
|||
methods: { |
|||
save() { |
|||
// send server |
|||
}, |
|||
openAddModal() { |
|||
this.$refs.childDialogue.open() |
|||
}, |
|||
openRemoveModal() { |
|||
this.$refs.removeDialogue.open() |
|||
} |
|||
} |
|||
|
|||
} |
|||
</script> |
@ -0,0 +1,334 @@ |
|||
<template> |
|||
<v-content> |
|||
<v-app-bar |
|||
:clipped-left="$vuetify.breakpoint.lgAndUp" |
|||
app |
|||
color="blue darken-3" |
|||
dark |
|||
dense |
|||
> |
|||
<v-toolbar-title |
|||
style="width: 300px" |
|||
class="ml-0 pl-4" |
|||
> |
|||
<v-app-bar-nav-icon @click.stop="drawer = !drawer" /> |
|||
<span class="hidden-sm-and-down">doccano</span> |
|||
</v-toolbar-title> |
|||
<v-text-field |
|||
flat |
|||
solo-inverted |
|||
hide-details |
|||
prepend-inner-icon="search" |
|||
label="Search" |
|||
class="hidden-sm-and-down" |
|||
/> |
|||
<v-spacer /> |
|||
<v-btn icon> |
|||
<v-icon>apps</v-icon> |
|||
</v-btn> |
|||
<v-btn icon> |
|||
<v-icon>notifications</v-icon> |
|||
</v-btn> |
|||
<v-btn |
|||
icon |
|||
large |
|||
> |
|||
<v-avatar |
|||
size="32px" |
|||
item |
|||
> |
|||
<v-img |
|||
src="https://cdn.vuetifyjs.com/images/logos/logo.svg" |
|||
alt="Vuetify" |
|||
/> |
|||
</v-avatar> |
|||
</v-btn> |
|||
</v-app-bar> |
|||
<v-container |
|||
fluid |
|||
fill-height |
|||
> |
|||
<v-layout |
|||
align-center |
|||
justify-center |
|||
> |
|||
<v-flex> |
|||
<v-card> |
|||
<v-card-title> |
|||
Projects |
|||
<v-spacer /> |
|||
<v-text-field |
|||
v-model="search" |
|||
append-icon="search" |
|||
label="Search" |
|||
single-line |
|||
hide-details |
|||
/> |
|||
</v-card-title> |
|||
<v-data-table |
|||
:headers="headers" |
|||
:items="desserts" |
|||
:search="search" |
|||
> |
|||
<template v-slot:item.calories="{ item }"> |
|||
<v-chip :color="getColor(item.calories)" dark> |
|||
{{ item.calories }} |
|||
</v-chip> |
|||
</template> |
|||
</v-data-table> |
|||
</v-card> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
<v-btn |
|||
bottom |
|||
color="pink" |
|||
dark |
|||
fab |
|||
fixed |
|||
right |
|||
@click="dialog = !dialog" |
|||
> |
|||
<v-icon>add</v-icon> |
|||
</v-btn> |
|||
<v-dialog |
|||
v-model="dialog" |
|||
width="800px" |
|||
> |
|||
<v-card> |
|||
<v-card-title class="grey darken-2"> |
|||
Create contact |
|||
</v-card-title> |
|||
<v-container grid-list-sm> |
|||
<v-layout |
|||
wrap |
|||
> |
|||
<v-flex |
|||
xs12 |
|||
align-center |
|||
justify-space-between |
|||
> |
|||
<v-layout align-center> |
|||
<v-avatar |
|||
size="40px" |
|||
class="mr-4" |
|||
> |
|||
<img |
|||
src="//ssl.gstatic.com/s2/oz/images/sge/grey_silhouette.png" |
|||
alt="" |
|||
> |
|||
</v-avatar> |
|||
<v-text-field |
|||
placeholder="Name" |
|||
/> |
|||
</v-layout> |
|||
</v-flex> |
|||
<v-flex xs6> |
|||
<v-text-field |
|||
prepend-icon="business" |
|||
placeholder="Company" |
|||
/> |
|||
</v-flex> |
|||
<v-flex xs6> |
|||
<v-text-field |
|||
placeholder="Job title" |
|||
/> |
|||
</v-flex> |
|||
<v-flex xs12> |
|||
<v-text-field |
|||
prepend-icon="mail" |
|||
placeholder="Email" |
|||
/> |
|||
</v-flex> |
|||
<v-flex xs12> |
|||
<v-text-field |
|||
type="tel" |
|||
prepend-icon="phone" |
|||
placeholder="(000) 000 - 0000" |
|||
/> |
|||
</v-flex> |
|||
<v-flex xs12> |
|||
<v-text-field |
|||
prepend-icon="notes" |
|||
placeholder="Notes" |
|||
/> |
|||
</v-flex> |
|||
</v-layout> |
|||
</v-container> |
|||
<v-card-actions> |
|||
<v-btn |
|||
text |
|||
color="primary" |
|||
> |
|||
More |
|||
</v-btn> |
|||
<v-spacer /> |
|||
<v-btn |
|||
text |
|||
color="primary" |
|||
@click="dialog = false" |
|||
> |
|||
Cancel |
|||
</v-btn> |
|||
<v-btn |
|||
text |
|||
@click="dialog = false" |
|||
> |
|||
Save |
|||
</v-btn> |
|||
</v-card-actions> |
|||
</v-card> |
|||
</v-dialog> |
|||
</v-content> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
layout: 'projectList', |
|||
props: { |
|||
source: { |
|||
type: String, |
|||
default: 'cat' |
|||
} |
|||
}, |
|||
data: () => ({ |
|||
dialog: false, |
|||
drawer: null, |
|||
items: [ |
|||
{ icon: 'contacts', text: 'Contacts' }, |
|||
{ icon: 'history', text: 'Frequently contacted' }, |
|||
{ icon: 'content_copy', text: 'Duplicates' }, |
|||
{ |
|||
icon: 'keyboard_arrow_up', |
|||
'icon-alt': 'keyboard_arrow_down', |
|||
text: 'Labels', |
|||
model: true, |
|||
children: [ |
|||
{ icon: 'add', text: 'Create label' } |
|||
] |
|||
}, |
|||
{ |
|||
icon: 'keyboard_arrow_up', |
|||
'icon-alt': 'keyboard_arrow_down', |
|||
text: 'More', |
|||
model: false, |
|||
children: [ |
|||
{ text: 'Import' }, |
|||
{ text: 'Export' }, |
|||
{ text: 'Print' }, |
|||
{ text: 'Undo changes' }, |
|||
{ text: 'Other contacts' } |
|||
] |
|||
}, |
|||
{ icon: 'settings', text: 'Settings' }, |
|||
{ icon: 'chat_bubble', text: 'Send feedback' }, |
|||
{ icon: 'help', text: 'Help' }, |
|||
{ icon: 'phonelink', text: 'App downloads' }, |
|||
{ icon: 'keyboard', text: 'Go to the old version' } |
|||
], |
|||
search: '', |
|||
headers: [ |
|||
{ |
|||
text: 'Name', |
|||
align: 'left', |
|||
sortable: false, |
|||
value: 'name' |
|||
}, |
|||
{ text: 'calories', value: 'calories' }, |
|||
{ text: 'Description', value: 'fat' } |
|||
// { text: 'Carbs (g)', value: 'carbs' }, |
|||
// { text: 'Protein (g)', value: 'protein' }, |
|||
// { text: 'Iron (%)', value: 'iron' } |
|||
], |
|||
desserts: [ |
|||
{ |
|||
name: 'Frozen Yogurt', |
|||
calories: 159, |
|||
fat: 6.0, |
|||
carbs: 24, |
|||
protein: 4.0, |
|||
iron: '1%' |
|||
}, |
|||
{ |
|||
name: 'Ice cream sandwich', |
|||
calories: 237, |
|||
fat: 9.0, |
|||
carbs: 37, |
|||
protein: 4.3, |
|||
iron: '1%' |
|||
}, |
|||
{ |
|||
name: 'Eclair', |
|||
calories: 262, |
|||
fat: 16.0, |
|||
carbs: 23, |
|||
protein: 6.0, |
|||
iron: '7%' |
|||
}, |
|||
{ |
|||
name: 'Cupcake', |
|||
calories: 305, |
|||
fat: 3.7, |
|||
carbs: 67, |
|||
protein: 4.3, |
|||
iron: '8%' |
|||
}, |
|||
{ |
|||
name: 'Gingerbread', |
|||
calories: 356, |
|||
fat: 16.0, |
|||
carbs: 49, |
|||
protein: 3.9, |
|||
iron: '16%' |
|||
}, |
|||
{ |
|||
name: 'Jelly bean', |
|||
calories: 375, |
|||
fat: 0.0, |
|||
carbs: 94, |
|||
protein: 0.0, |
|||
iron: '0%' |
|||
}, |
|||
{ |
|||
name: 'Lollipop', |
|||
calories: 392, |
|||
fat: 0.2, |
|||
carbs: 98, |
|||
protein: 0, |
|||
iron: '2%' |
|||
}, |
|||
{ |
|||
name: 'Honeycomb', |
|||
calories: 408, |
|||
fat: 3.2, |
|||
carbs: 87, |
|||
protein: 6.5, |
|||
iron: '45%' |
|||
}, |
|||
{ |
|||
name: 'Donut', |
|||
calories: 452, |
|||
fat: 25.0, |
|||
carbs: 51, |
|||
protein: 4.9, |
|||
iron: '22%' |
|||
}, |
|||
{ |
|||
name: 'KitKat', |
|||
calories: 518, |
|||
fat: 26.0, |
|||
carbs: 65, |
|||
protein: 7, |
|||
iron: '6%' |
|||
} |
|||
] |
|||
}), |
|||
methods: { |
|||
getColor(calories) { |
|||
if (calories > 400) return 'red' |
|||
else if (calories > 200) return 'orange' |
|||
else return 'green' |
|||
} |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,7 @@ |
|||
# PLUGINS |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). |
@ -0,0 +1,15 @@ |
|||
import Vue from 'vue' |
|||
|
|||
export const truncate = function (text, length, clamp) { |
|||
text = text || '' |
|||
clamp = clamp || '...' |
|||
length = length || 30 |
|||
|
|||
if (text.length <= length) { |
|||
return text |
|||
} |
|||
|
|||
return text.substring(0, length) + clamp |
|||
} |
|||
|
|||
Vue.filter('truncate', truncate) |
@ -0,0 +1,8 @@ |
|||
export const idealColor = function (hexString) { |
|||
// W3c offers a formula for calculating ideal color:
|
|||
// https://www.w3.org/TR/AERT/#color-contrast
|
|||
const r = parseInt(hexString.substr(1, 2), 16) |
|||
const g = parseInt(hexString.substr(3, 2), 16) |
|||
const b = parseInt(hexString.substr(5, 2), 16) |
|||
return ((((r * 299) + (g * 587) + (b * 114)) / 1000) < 128) ? '#ffffff' : '#000000' |
|||
} |
@ -0,0 +1,11 @@ |
|||
# STATIC |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
This directory contains your static files. |
|||
Each file inside this directory is mapped to `/`. |
|||
Thus you'd want to delete this README.md before deploying to production. |
|||
|
|||
Example: `/static/robots.txt` is mapped as `/robots.txt`. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). |
@ -0,0 +1,10 @@ |
|||
# STORE |
|||
|
|||
**This directory is not required, you can delete it if you don't want to use it.** |
|||
|
|||
This directory contains your Vuex Store files. |
|||
Vuex Store option is implemented in the Nuxt.js framework. |
|||
|
|||
Creating a file in this directory automatically activates the option in the framework. |
|||
|
|||
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). |
@ -0,0 +1,9 @@ |
|||
export const state = () => ({ |
|||
drawer: false |
|||
}) |
|||
|
|||
export const mutations = { |
|||
toggle(state) { |
|||
state.drawer = !state.drawer |
|||
} |
|||
} |
@ -0,0 +1,55 @@ |
|||
import { shallowMount } from '@vue/test-utils' |
|||
import Vue from 'vue' |
|||
import Vuetify from 'vuetify' |
|||
import Modal from '@/components/Modal.vue' |
|||
|
|||
Vue.use(Vuetify) |
|||
|
|||
describe('Modal', () => { |
|||
test('can receive props', () => { |
|||
const propsData = { |
|||
title: 'test title', |
|||
button: 'test text' |
|||
} |
|||
const wrapper = shallowMount(Modal, { propsData }) |
|||
expect(wrapper.props()).toEqual(propsData) |
|||
}) |
|||
|
|||
test('can insert content into slot', () => { |
|||
const wrapper = shallowMount(Modal, { |
|||
slots: { |
|||
default: '<div data-test="slotContent">slot content</div>' |
|||
} |
|||
}) |
|||
const slotContent = wrapper.find('[data-test="slotContent"]') |
|||
expect(slotContent.exists()).toBe(true) |
|||
expect(slotContent.text()).toBe('slot content') |
|||
}) |
|||
|
|||
test('is closed by default', () => { |
|||
const wrapper = shallowMount(Modal) |
|||
expect(wrapper.vm.dialog).toBe(false) |
|||
}) |
|||
|
|||
test('can open dialog', () => { |
|||
const wrapper = shallowMount(Modal) |
|||
wrapper.vm.open() |
|||
expect(wrapper.vm.dialog).toBe(true) |
|||
}) |
|||
|
|||
test('can close after agree', () => { |
|||
const wrapper = shallowMount(Modal) |
|||
wrapper.vm.open() |
|||
expect(wrapper.vm.dialog).toBe(true) |
|||
wrapper.vm.agree() |
|||
expect(wrapper.vm.dialog).toBe(false) |
|||
}) |
|||
|
|||
test('can close after cancel', () => { |
|||
const wrapper = shallowMount(Modal) |
|||
wrapper.vm.open() |
|||
expect(wrapper.vm.dialog).toBe(true) |
|||
wrapper.vm.cancel() |
|||
expect(wrapper.vm.dialog).toBe(false) |
|||
}) |
|||
}) |
@ -0,0 +1,18 @@ |
|||
import { truncate } from '@/plugins/filters.js' |
|||
|
|||
describe('Truncate', () => { |
|||
test('dont do nothing', () => { |
|||
const string = 'aiueo' |
|||
expect(truncate(string)).toEqual(string) |
|||
}) |
|||
|
|||
test('cut the string and add clamp if string length is larger than specified length', () => { |
|||
const string = 'aiueo' |
|||
expect(truncate(string, 3)).toEqual('aiu...') |
|||
}) |
|||
|
|||
test('dont cut anything if string length is smaller than specified length', () => { |
|||
const string = 'aiueo' |
|||
expect(truncate(string, 10)).toEqual(string) |
|||
}) |
|||
}) |
10182
frontend/yarn.lock
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save