lesli_babel 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/lesli_babel/application.css +4 -1308
- data/app/controllers/lesli_babel/labels_controller.rb +2 -2
- data/app/services/lesli_babel/label_service.rb +1 -1
- data/app/services/lesli_babel/translation_service.rb +2 -2
- data/app/views/lesli_babel/dashboards/show.html.erb +15 -11
- data/app/views/lesli_babel/labels/_form.html.erb +1 -1
- data/app/views/lesli_babel/labels/index.html.erb +6 -6
- data/lib/lesli_babel/engine.rb +2 -2
- data/lib/lesli_babel/version.rb +2 -2
- data/lib/tasks/lesli_babel_tasks.rake +1 -1
- metadata +3 -21
- data/lib/scss/application.scss +0 -46
- data/lib/scss/dashboards.scss +0 -56
- data/lib/scss/modules.scss +0 -34
- data/lib/scss/translations.scss +0 -59
- data/lib/vue/application.js +0 -69
- data/lib/vue/apps/dashboards/show.vue +0 -83
- data/lib/vue/apps/modules/show.vue +0 -106
- data/lib/vue/apps/relevants/index.vue +0 -47
- data/lib/vue/apps/translations/index.vue +0 -78
- data/lib/vue/components/actions.vue +0 -29
- data/lib/vue/components/form-label-editor.vue +0 -437
- data/lib/vue/components/form-string-new.vue +0 -130
- data/lib/vue/stores/module.js +0 -63
- data/lib/vue/stores/statistics.js +0 -42
- data/lib/vue/stores/string.js +0 -84
- data/lib/vue/stores/strings.js +0 -141
- data/lib/vue/stores/translations.js +0 -73
- data/lib/vue/stores/translations.json +0 -162
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/*
|
|
3
|
-
Copyright (c) 2022, all rights reserved.
|
|
4
|
-
|
|
5
|
-
All the information provided by this platform is protected by international laws related to
|
|
6
|
-
industrial property, intellectual property, copyright and relative international laws.
|
|
7
|
-
All intellectual or industrial property rights of the code, texts, trade mark, design,
|
|
8
|
-
pictures and any other information belongs to the owner of this platform.
|
|
9
|
-
|
|
10
|
-
Without the written permission of the owner, any replication, modification,
|
|
11
|
-
transmission, publication is strictly forbidden.
|
|
12
|
-
|
|
13
|
-
For more information read the license file including with this software.
|
|
14
|
-
|
|
15
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
16
|
-
// ·
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// · import vue tools
|
|
21
|
-
import { ref, reactive, onMounted, watch, computed, inject } from "vue"
|
|
22
|
-
import { useRouter, useRoute } from 'vue-router'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// · initialize/inject plugins
|
|
26
|
-
const router = useRouter()
|
|
27
|
-
const route = useRoute()
|
|
28
|
-
const msg = inject("msg")
|
|
29
|
-
const url = inject("url")
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// · import components
|
|
33
|
-
import componentLabelEditor from "LesliBabel/vue/components/form-label-editor.vue"
|
|
34
|
-
import componentActions from "LesliBabel/vue/components/actions.vue"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
</script>
|
|
38
|
-
<template>
|
|
39
|
-
<section class="application-component">
|
|
40
|
-
<lesli-header title="Relevant translations">
|
|
41
|
-
<component-actions></component-actions>
|
|
42
|
-
</lesli-header>
|
|
43
|
-
|
|
44
|
-
<component-label-editor module="relevants">
|
|
45
|
-
</component-label-editor>
|
|
46
|
-
</section>
|
|
47
|
-
</template>
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/*
|
|
3
|
-
Lesli
|
|
4
|
-
|
|
5
|
-
Copyright (c) 2023, Lesli Technologies, S. A.
|
|
6
|
-
|
|
7
|
-
This program is free software: you can redistribute it and/or modify
|
|
8
|
-
it under the terms of the GNU General Public License as published by
|
|
9
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
-
(at your option) any later version.
|
|
11
|
-
|
|
12
|
-
This program is distributed in the hope that it will be useful,
|
|
13
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
-
GNU General Public License for more details.
|
|
16
|
-
|
|
17
|
-
You should have received a copy of the GNU General Public License
|
|
18
|
-
along with this program. If not, see http://www.gnu.org/licenses/.
|
|
19
|
-
|
|
20
|
-
Lesli · Ruby on Rails SaaS Development Framework.
|
|
21
|
-
|
|
22
|
-
Made with ♥ by LesliTech
|
|
23
|
-
Building a better future, one line of code at a time.
|
|
24
|
-
|
|
25
|
-
@contact hello@lesli.tech
|
|
26
|
-
@website https://www.lesli.tech
|
|
27
|
-
@license GPLv3 http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
28
|
-
|
|
29
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
30
|
-
// ·
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
// · import vue tools
|
|
35
|
-
import { ref, reactive, onMounted, watch, computed, inject } from "vue"
|
|
36
|
-
import { useRouter, useRoute } from 'vue-router'
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// · initialize/inject plugins
|
|
40
|
-
const router = useRouter()
|
|
41
|
-
const route = useRoute()
|
|
42
|
-
const msg = inject("msg")
|
|
43
|
-
const url = inject("url")
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// · import components
|
|
47
|
-
import componentLabelEditor from "LesliBabel/vue/components/form-label-editor.vue"
|
|
48
|
-
import componentActions from "LesliBabel/vue/components/actions.vue"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// · import lesli stores
|
|
52
|
-
import { useStrings } from "LesliBabel/vue/stores/strings"
|
|
53
|
-
import { useTranslations } from "LesliBabel/vue/stores/translations"
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// · implement stores
|
|
57
|
-
const storeStrings = useStrings()
|
|
58
|
-
const storeTranslations = useTranslations()
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// ·
|
|
62
|
-
function search(string) {
|
|
63
|
-
router.push({ path: "translations", query: { search: string }})
|
|
64
|
-
}
|
|
65
|
-
</script>
|
|
66
|
-
<template>
|
|
67
|
-
<lesli-application-container>
|
|
68
|
-
<lesli-header title="Translations">
|
|
69
|
-
<component-actions></component-actions>
|
|
70
|
-
</lesli-header>
|
|
71
|
-
|
|
72
|
-
<lesli-toolbar :initial-value="storeStrings.search" @search="search">
|
|
73
|
-
</lesli-toolbar>
|
|
74
|
-
|
|
75
|
-
<component-label-editor>
|
|
76
|
-
</component-label-editor>
|
|
77
|
-
</lesli-application-container>
|
|
78
|
-
</template>
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
|
|
3
|
-
// · import lesli stores
|
|
4
|
-
import { useTranslations } from "LesliBabel/vue/stores/translations"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// · implement stores
|
|
8
|
-
const storeTranslations = useTranslations()
|
|
9
|
-
|
|
10
|
-
</script>
|
|
11
|
-
<template>
|
|
12
|
-
<lesli-button icon="rocket_launch" @click="storeTranslations.postDeploy()">
|
|
13
|
-
deploy
|
|
14
|
-
</lesli-button>
|
|
15
|
-
<!--
|
|
16
|
-
<lesli-button icon="download">
|
|
17
|
-
update
|
|
18
|
-
</lesli-button>
|
|
19
|
-
<lesli-button icon="sync" @click="storeTranslations.postSync()">
|
|
20
|
-
sync
|
|
21
|
-
</lesli-button>
|
|
22
|
-
<lesli-button icon="code">
|
|
23
|
-
javascript
|
|
24
|
-
</lesli-button>
|
|
25
|
-
<lesli-button icon="code">
|
|
26
|
-
flutter
|
|
27
|
-
</lesli-button>
|
|
28
|
-
-->
|
|
29
|
-
</template>
|
|
@@ -1,437 +0,0 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
/*
|
|
3
|
-
Copyright (c) 2022, all rights reserved.
|
|
4
|
-
|
|
5
|
-
All the information provided by this platform is protected by international laws related to
|
|
6
|
-
industrial property, intellectual property, copyright and relative international laws.
|
|
7
|
-
All intellectual or industrial property rights of the code, texts, trade mark, design,
|
|
8
|
-
pictures and any other information belongs to the owner of this platform.
|
|
9
|
-
|
|
10
|
-
Without the written permission of the owner, any replication, modification,
|
|
11
|
-
transmission, publication is strictly forbidden.
|
|
12
|
-
|
|
13
|
-
For more information read the license file including with this software.
|
|
14
|
-
|
|
15
|
-
// · ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~ ~·~
|
|
16
|
-
// ·
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// · import vue tools
|
|
21
|
-
import { ref, reactive, onMounted, watch, computed, onUnmounted } from "vue"
|
|
22
|
-
import { useRouter, useRoute } from 'vue-router'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// · import lesli stores
|
|
26
|
-
const route = useRoute()
|
|
27
|
-
import { useStrings } from "LesliBabel/vue/stores/strings"
|
|
28
|
-
import { useTranslations } from "LesliBabel/vue/stores/translations"
|
|
29
|
-
import { useServiceTranslator } from "Lesli/vue/shared/services/translator"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
// · implement stores
|
|
33
|
-
const storeStrings = useStrings()
|
|
34
|
-
const storeTranslations = useTranslations()
|
|
35
|
-
const storeServiceTranslator = useServiceTranslator()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// ·
|
|
39
|
-
const props = defineProps({
|
|
40
|
-
module: {
|
|
41
|
-
type: [Number, String],
|
|
42
|
-
require: false
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// · columns of the editor table
|
|
48
|
-
const columns = ref([])
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// · selected language to work with
|
|
52
|
-
const language = ref(null)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// ·
|
|
56
|
-
onMounted(() => {
|
|
57
|
-
|
|
58
|
-
// english by default if custom language not sent through url
|
|
59
|
-
language.value = route.query?.locale ?? 'en'
|
|
60
|
-
|
|
61
|
-
// get options for translations
|
|
62
|
-
storeTranslations.fetchOptions()
|
|
63
|
-
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// · get translations checking configuration provided through the store or query
|
|
68
|
-
function fetchTranslations() {
|
|
69
|
-
|
|
70
|
-
// always reset the config
|
|
71
|
-
storeStrings.search = ""
|
|
72
|
-
storeStrings.module = 0
|
|
73
|
-
storeStrings.ids = null
|
|
74
|
-
|
|
75
|
-
// work with relevant translations
|
|
76
|
-
if (props.module == "relevants") {
|
|
77
|
-
return storeStrings.fetchRelevant()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// check if labels ids are provided
|
|
81
|
-
if (route.query?.ids) {
|
|
82
|
-
storeStrings.ids = route.query?.ids
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// check if search params is provided through query
|
|
86
|
-
if (route.query?.search) {
|
|
87
|
-
storeStrings.search = route.query?.search
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// work with an specific module if provided
|
|
91
|
-
if (props.module) {
|
|
92
|
-
storeStrings.module = props.module
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return storeStrings.fetchStrings()
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// · load all the columns available for the editor
|
|
101
|
-
function resetColumns() {
|
|
102
|
-
|
|
103
|
-
// reset columns
|
|
104
|
-
columns.value = []
|
|
105
|
-
|
|
106
|
-
// load defaults columns for the editor table
|
|
107
|
-
columns.value.push({
|
|
108
|
-
label: 'Label to translate',
|
|
109
|
-
field: 'label'
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
// dynamic add the column related to the selected working language
|
|
113
|
-
columns.value.push({
|
|
114
|
-
label: storeTranslations?.options?.locales_available[language.value],
|
|
115
|
-
field: language.value,
|
|
116
|
-
width: '100%'
|
|
117
|
-
})
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// · build the title for the table custom headers
|
|
122
|
-
// · this is necessary to show the custom header cell for every language
|
|
123
|
-
// · (we show only one language at the time)
|
|
124
|
-
function languageHead(language) {
|
|
125
|
-
return 'head('+language+')'
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// suggest translation from english to desire language
|
|
130
|
-
// to make this work we need to have the label already translated to english
|
|
131
|
-
function suggestTranslation(label, locale) {
|
|
132
|
-
|
|
133
|
-
// we use the translator service (integrated with google translate)
|
|
134
|
-
// we always send the text in english due the label key is compound with the
|
|
135
|
-
// collection and bucket names
|
|
136
|
-
storeServiceTranslator.getTranslation(label["en"], "en", locale).then(result => {
|
|
137
|
-
|
|
138
|
-
// update the translation
|
|
139
|
-
label[locale] = result.translatedText
|
|
140
|
-
|
|
141
|
-
// custom property added just here to let the editor know that an automatic
|
|
142
|
-
// translation was added to the label
|
|
143
|
-
label[`translated_${locale}`] = true
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// remove a translation for a specific locale
|
|
149
|
-
// mostly used with suggested translations
|
|
150
|
-
function clearStringTranslation(record, locale) {
|
|
151
|
-
record[locale] = ''
|
|
152
|
-
record[`translated_${locale}`] = false
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
// build a string to use as direct link to the selected label
|
|
157
|
-
function getLabelLink(id) {
|
|
158
|
-
return `${window.location.host}/babel/translations?ids=${id}`
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
// switch a label as help needed
|
|
163
|
-
function askForHelp(record) {
|
|
164
|
-
record.status = 2
|
|
165
|
-
storeStrings.putString(record)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// switch a label as help needed
|
|
170
|
-
function askForTranslation(record) {
|
|
171
|
-
record.status = 3
|
|
172
|
-
storeStrings.putString(record)
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
// · get strings for the module selected, reset if module changed
|
|
177
|
-
watch(() => props.module, () => {
|
|
178
|
-
storeStrings.search = ""
|
|
179
|
-
storeStrings.module = props.module
|
|
180
|
-
fetchTranslations()
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
watch(() => route.query.search, string => {
|
|
185
|
-
storeStrings.search = string
|
|
186
|
-
fetchTranslations()
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
// · changing the working language, keep config if language changed
|
|
191
|
-
watch(() => language.value, (language) => {
|
|
192
|
-
storeStrings.language = language
|
|
193
|
-
fetchTranslations()
|
|
194
|
-
resetColumns()
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// · watch for the locales available to dynamically show language columns in the editor
|
|
199
|
-
watch(() => storeTranslations.options.locales_available, () => {
|
|
200
|
-
resetColumns()
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
// · go to the first input once translations loaded
|
|
205
|
-
watch(() => storeStrings.strings.records, () => {
|
|
206
|
-
setTimeout(() => { nextTranslation() }, 1000)
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// ·
|
|
211
|
-
function copyToClipboard(button, text) {
|
|
212
|
-
const el = document.createElement('textarea');
|
|
213
|
-
el.value = text; // text to copy
|
|
214
|
-
el.setAttribute('readonly', '');
|
|
215
|
-
el.style.position = 'absolute';
|
|
216
|
-
el.style.left = '-9999px';
|
|
217
|
-
document.body.appendChild(el);
|
|
218
|
-
el.select();
|
|
219
|
-
document.execCommand('copy');
|
|
220
|
-
document.body.removeChild(el);
|
|
221
|
-
button.target.classList.add('copied')
|
|
222
|
-
setTimeout(() => button.target.classList.remove('copied'), 1000)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// · Navigate to the next translation using arrow keys
|
|
227
|
-
function nextTranslation () {
|
|
228
|
-
return
|
|
229
|
-
var table = document.getElementById("babel-translations")
|
|
230
|
-
var inputs = table.getElementsByTagName("input")
|
|
231
|
-
|
|
232
|
-
for(var i = 0 ; i < inputs.length;i++) {
|
|
233
|
-
|
|
234
|
-
// add a listener for keydown
|
|
235
|
-
inputs[i].addEventListener('keydown', function(e){
|
|
236
|
-
|
|
237
|
-
// execute only for down/up/enter keys
|
|
238
|
-
if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13) {
|
|
239
|
-
|
|
240
|
-
// remove default behavior for arrow keys
|
|
241
|
-
e.preventDefault()
|
|
242
|
-
|
|
243
|
-
// get the index of the current index
|
|
244
|
-
var currentIndex = findElement(e.target)
|
|
245
|
-
|
|
246
|
-
// work only with valid index between 0 ~ n
|
|
247
|
-
if (currentIndex < 0 || currentIndex > inputs.length) {
|
|
248
|
-
return
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// downkey
|
|
252
|
-
if (e.keyCode == 38) {
|
|
253
|
-
if (inputs[currentIndex-1]) {
|
|
254
|
-
inputs[currentIndex-1].focus();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// upkey
|
|
259
|
-
if (e.keyCode == 40 || e.keyCode == 13) {
|
|
260
|
-
if (inputs[currentIndex+1]) {
|
|
261
|
-
inputs[currentIndex+1].focus();
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// get the current selected input
|
|
271
|
-
function findElement(element) {
|
|
272
|
-
var index = -1;
|
|
273
|
-
for(var i = 0; i < inputs.length; i++) {
|
|
274
|
-
if(inputs[i] == element) {
|
|
275
|
-
return i;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return index;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
</script>
|
|
284
|
-
<template>
|
|
285
|
-
<lesli-table
|
|
286
|
-
id="babel-translations"
|
|
287
|
-
:loading="storeStrings.strings.loading"
|
|
288
|
-
:records="storeStrings.strings.records"
|
|
289
|
-
:columns="columns"
|
|
290
|
-
@paginate="storeStrings.fetchStrings()"
|
|
291
|
-
@details="nextTranslation()">
|
|
292
|
-
|
|
293
|
-
<!-- Table custom header, renders a language selector -->
|
|
294
|
-
<template :[languageHead(language)]="{ column }">
|
|
295
|
-
<lesli-select
|
|
296
|
-
icon="public"
|
|
297
|
-
v-model="language"
|
|
298
|
-
:options="storeTranslations.locales">
|
|
299
|
-
</lesli-select>
|
|
300
|
-
</template>
|
|
301
|
-
|
|
302
|
-
<!-- Print the label string with a button to easely copy to clipboard -->
|
|
303
|
-
<template #label="{ record }">
|
|
304
|
-
<button
|
|
305
|
-
class="button is-white p-0"
|
|
306
|
-
@click.stop="copyToClipboard($event, record.label)"
|
|
307
|
-
@contextmenu.capture.prevent="copyToClipboard($event, record.path)">
|
|
308
|
-
<span class="icon has-text-grey">
|
|
309
|
-
<span class="material-icons">
|
|
310
|
-
content_copy
|
|
311
|
-
</span>
|
|
312
|
-
</span>
|
|
313
|
-
<span :class="{
|
|
314
|
-
'has-text-info': record.status == 2,
|
|
315
|
-
'has-text-warning': record.status == 3
|
|
316
|
-
}">
|
|
317
|
-
{{ record.label }}
|
|
318
|
-
</span>
|
|
319
|
-
</button>
|
|
320
|
-
</template>
|
|
321
|
-
|
|
322
|
-
<!-- Print a input to edit the translation for the current locale -->
|
|
323
|
-
<template #[language]="{ value, record }">
|
|
324
|
-
<div class="is-flex is-align-items-center">
|
|
325
|
-
<input
|
|
326
|
-
type="text"
|
|
327
|
-
class="input"
|
|
328
|
-
placeholder="Add translations..."
|
|
329
|
-
@input="storeStrings.updateString(record, language)"
|
|
330
|
-
v-model="record[language]"
|
|
331
|
-
/>
|
|
332
|
-
<span class="icon mx-1" v-if="record.need_help">
|
|
333
|
-
<span class="material-icons has-text-info">
|
|
334
|
-
help_outline
|
|
335
|
-
</span>
|
|
336
|
-
</span>
|
|
337
|
-
<span class="icon mx-1" v-if="record.need_translation">
|
|
338
|
-
<span class="material-icons has-text-warning-dark">
|
|
339
|
-
translate
|
|
340
|
-
</span>
|
|
341
|
-
</span>
|
|
342
|
-
</div>
|
|
343
|
-
</template>
|
|
344
|
-
|
|
345
|
-
<template #detail="{ record }">
|
|
346
|
-
<tr v-for="(locale_name, locale_code) in storeTranslations.options.locales_available">
|
|
347
|
-
<td></td>
|
|
348
|
-
<td class="has-text-right">{{ locale_name }}</td>
|
|
349
|
-
<td class="is-flex is-align-items-center">
|
|
350
|
-
<input
|
|
351
|
-
type="text"
|
|
352
|
-
class="input"
|
|
353
|
-
placeholder="Add translations..."
|
|
354
|
-
v-model="record[locale_code]"
|
|
355
|
-
@input="storeStrings.updateString(record, locale_code)"
|
|
356
|
-
/>
|
|
357
|
-
<lesli-button
|
|
358
|
-
icon-only small danger icon="clear"
|
|
359
|
-
v-if="record[`translated_${locale_code}`] == true"
|
|
360
|
-
@click="clearStringTranslation(record, locale_code)">
|
|
361
|
-
</lesli-button>
|
|
362
|
-
|
|
363
|
-
<lesli-button
|
|
364
|
-
icon-only small icon="save"
|
|
365
|
-
v-if="record[`translated_${locale_code}`] == true"
|
|
366
|
-
@click="storeStrings.putString(record)">
|
|
367
|
-
</lesli-button>
|
|
368
|
-
|
|
369
|
-
<lesli-button
|
|
370
|
-
icon-only small icon="translate"
|
|
371
|
-
v-if="!!record['en']"
|
|
372
|
-
@click="suggestTranslation(record, locale_code)">
|
|
373
|
-
</lesli-button>
|
|
374
|
-
</td>
|
|
375
|
-
</tr>
|
|
376
|
-
<tr>
|
|
377
|
-
<td></td>
|
|
378
|
-
<td class="has-text-right">Context</td>
|
|
379
|
-
<td>
|
|
380
|
-
<input
|
|
381
|
-
type="text"
|
|
382
|
-
class="input"
|
|
383
|
-
placeholder="Add translation context..."
|
|
384
|
-
v-model="record.context"
|
|
385
|
-
@input="storeStrings.updateString(record)"
|
|
386
|
-
/>
|
|
387
|
-
</td>
|
|
388
|
-
</tr>
|
|
389
|
-
<tr>
|
|
390
|
-
<td></td>
|
|
391
|
-
<td class="has-text-right">Full path</td>
|
|
392
|
-
<td>
|
|
393
|
-
<button
|
|
394
|
-
class="button is-primary is-inverted"
|
|
395
|
-
@click.stop="copyToClipboard($event, record.path)">
|
|
396
|
-
<span class="icon has-text-grey">
|
|
397
|
-
<span class="material-icons">
|
|
398
|
-
content_copy
|
|
399
|
-
</span>
|
|
400
|
-
</span>
|
|
401
|
-
<span>
|
|
402
|
-
{{ record.path }}
|
|
403
|
-
</span>
|
|
404
|
-
</button>
|
|
405
|
-
</td>
|
|
406
|
-
</tr>
|
|
407
|
-
<tr>
|
|
408
|
-
<td colspan="100%">
|
|
409
|
-
<div class="buttons is-justify-content-center">
|
|
410
|
-
<button
|
|
411
|
-
class="button is-primary is-small"
|
|
412
|
-
@click="copyToClipboard($event, getLabelLink(record.id))">
|
|
413
|
-
<span class="icon is-small">
|
|
414
|
-
<span class="material-icons">link</span>
|
|
415
|
-
</span>
|
|
416
|
-
<span>Copy link</span>
|
|
417
|
-
</button>
|
|
418
|
-
|
|
419
|
-
<lesli-button
|
|
420
|
-
small info solid icon="help_outline"
|
|
421
|
-
:disabled="record.status == 2"
|
|
422
|
-
@click="askForHelp(record)">
|
|
423
|
-
Need help
|
|
424
|
-
</lesli-button>
|
|
425
|
-
|
|
426
|
-
<lesli-button
|
|
427
|
-
small warning solid icon="translate"
|
|
428
|
-
:disabled="record.status == 3"
|
|
429
|
-
@click="askForTranslation(record)">
|
|
430
|
-
Need translation
|
|
431
|
-
</lesli-button>
|
|
432
|
-
</div>
|
|
433
|
-
</td>
|
|
434
|
-
</tr>
|
|
435
|
-
</template>
|
|
436
|
-
</lesli-table>
|
|
437
|
-
</template>
|