/
FieldSelectTranslator.vue
147 lines (125 loc) · 4.19 KB
/
FieldSelectTranslator.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<template>
<c-translator-button
v-if="canManageResourceTranslations && resourceTranslationsEnabled"
button-variant="light"
v-bind="$props"
:title="$t('tooltip')"
:size="size"
:resource="resource"
:fetcher="fetcher"
:updater="updater"
:key-prettyfier="keyPrettifyer"
class="ml-auto mr-1 py-1 px-3"
/>
</template>
<script>
import { compose } from '@cortezaproject/corteza-js'
import { mapGetters } from 'vuex'
import CTranslatorButton from 'corteza-webapp-compose/src/components/Translator/CTranslatorButton'
import moduleFieldSelectResTr from 'corteza-webapp-compose/src/lib/resource-translations/module-field-select'
const keyPrefix = 'meta.options.'
const keySuffix = '.text'
function optionValueFromKey (key) {
return key.substring(keyPrefix.length, key.length - keySuffix.length)
}
export default {
components: {
CTranslatorButton,
},
i18nOptions: {
namespaces: 'resource-translator',
keyPrefix: 'resources.module.field',
},
props: {
field: {
type: compose.ModuleField,
required: true,
},
module: {
type: compose.Module,
required: true,
},
size: {
type: String,
default: 'lg',
},
disabled: {
type: Boolean,
default: () => false,
},
highlightKey: {
type: String,
default: '',
},
},
computed: {
...mapGetters({
can: 'rbac/can',
}),
canManageResourceTranslations () {
return this.can('compose/', 'resource-translations.manage')
},
resource () {
const { fieldID } = this.field
const { moduleID, namespaceID } = this.module
return `compose:module-field/${namespaceID}/${moduleID}/${fieldID}`
},
fetcher () {
const { moduleID, namespaceID } = this.module
return () => {
return this.$ComposeAPI
.moduleListTranslations({ namespaceID, moduleID })
// Fields do not have their own translation endpoints,
// we'll just filter what we need here.
.then(set => {
set = set
// Extract translations for this field
.filter(({ resource }) => this.resource === resource)
// Ignore all option translations
.filter(({ key }) => key.startsWith(keyPrefix) && key.endsWith(keySuffix))
// after translations are fetched, make sure we copy all (updates) values from
// the caller so translator editor can operate with recent values
set
.filter(({ lang }) => this.currentLanguage === lang)
.forEach(rt => {
// find the corresponding option
const op = this.field.options.options
.find(op => typeof op === 'object' && rt.key === `${keyPrefix}${op.value}${keySuffix}`)
if (op) {
// and update the message
rt.message = op.text
}
})
// @todo instead of this ^ pass set of translations to the object (ModuleField* class)
// The logic there needs to be implemented; the idea is to decode
// values from the resource object to the set of translations)
return set
})
}
},
keyPrettifyer () {
return optionValueFromKey
},
updater () {
const { moduleID, namespaceID } = this.module
return translations => {
return this.$ComposeAPI
.moduleUpdateTranslations({ namespaceID, moduleID, translations })
// re-fetch translations, sanitized and stripped
.then(() => {
// When translations are successfully saved,
// scan changes and apply them back to the passed object
// not the most elegant solution but is saves us from
// handling the resource on multiple places
//
// @todo move this to ModuleFieldSelect classes
// the logic there needs to be implemented; the idea is to encode
// values from the set of translations back to the resource object
moduleFieldSelectResTr(this.field, translations, this.currentLanguage, this.resource)
this.fetcher()
})
}
},
},
}
</script>