alchemy-form 0.2.3 → 0.2.4
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.
- package/CHANGELOG.md +6 -0
- package/assets/stylesheets/form/elements/_field_translatable.scss +41 -1
- package/element/al_field_schema.js +26 -34
- package/element/al_field_translatable.js +62 -3
- package/element/al_field_translatable_entry.js +19 -1
- package/element/al_form.js +5 -1
- package/package.json +1 -1
- package/view/form/elements/alchemy_field_translatable.hwk +17 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## 0.2.4 (2023-02-26)
|
|
2
|
+
|
|
3
|
+
* Don't look for a field when the path is not specified
|
|
4
|
+
* Make `al-field-schema` elements use `Field#getSubSchema()` method
|
|
5
|
+
* Add an icon to the translatable-field entry buttons to see if it has a translation or not
|
|
6
|
+
|
|
1
7
|
## 0.2.3 (2023-02-11)
|
|
2
8
|
|
|
3
9
|
* Use `Scene#pushToHistory()` instead of directly calling `pushState`
|
|
@@ -3,6 +3,46 @@ al-field-translatable {
|
|
|
3
3
|
position: relative;
|
|
4
4
|
|
|
5
5
|
.prefix-buttons {
|
|
6
|
-
|
|
6
|
+
button {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-flow: row;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.has-empty-content {
|
|
12
|
+
font-size: 0.7rem;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.has-content {
|
|
16
|
+
font-size: 0.9rem;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.has-empty-content,
|
|
20
|
+
.has-content {
|
|
21
|
+
margin-left: 0.5rem;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
[data-has-content="true"] {
|
|
25
|
+
.has-empty-content {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[data-has-content="false"] {
|
|
31
|
+
.has-content {
|
|
32
|
+
display: none;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[icon-name] {
|
|
37
|
+
color: #333;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
[icon-name="ban"] {
|
|
41
|
+
color: tomato;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.has-content {
|
|
45
|
+
color: green;
|
|
46
|
+
}
|
|
7
47
|
}
|
|
8
48
|
}
|
|
@@ -21,47 +21,39 @@ FieldSchema.setTemplateFile('form/elements/alchemy_field_schema');
|
|
|
21
21
|
*
|
|
22
22
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
23
23
|
* @since 0.1.0
|
|
24
|
-
* @version 0.
|
|
24
|
+
* @version 0.2.4
|
|
25
25
|
*/
|
|
26
26
|
FieldSchema.setProperty(function schema() {
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const field_element = this.alchemy_field;
|
|
29
|
+
const field = field_element?.config;
|
|
30
|
+
|
|
31
|
+
if (field?.options) {
|
|
32
|
+
|
|
33
|
+
let schema = field.options.schema;
|
|
30
34
|
|
|
31
35
|
if (typeof schema == 'string') {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (value) {
|
|
48
|
-
if (value.schema) {
|
|
49
|
-
schema = value.schema;
|
|
50
|
-
} else if (value.value) {
|
|
51
|
-
// Enumified values can be wrapped on the server-side
|
|
52
|
-
value = value.value;
|
|
53
|
-
|
|
54
|
-
if (value.schema) {
|
|
55
|
-
schema = value.schema;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!schema) {
|
|
61
|
-
schema = value;
|
|
62
|
-
}
|
|
36
|
+
|
|
37
|
+
let parent_schema_value;
|
|
38
|
+
|
|
39
|
+
let parent_schema = field_element.queryParents('al-field[field-type="schema"]');
|
|
40
|
+
|
|
41
|
+
if (parent_schema) {
|
|
42
|
+
parent_schema_value = parent_schema.value;
|
|
43
|
+
} else {
|
|
44
|
+
|
|
45
|
+
const form = field_element.alchemy_form;
|
|
46
|
+
|
|
47
|
+
let record_value = form.value;
|
|
48
|
+
|
|
49
|
+
if (form.model) {
|
|
50
|
+
record_value = record_value[form.model];
|
|
63
51
|
}
|
|
52
|
+
|
|
53
|
+
parent_schema_value = record_value;
|
|
64
54
|
}
|
|
55
|
+
|
|
56
|
+
return field.getSubschema(parent_schema_value, schema)
|
|
65
57
|
}
|
|
66
58
|
|
|
67
59
|
return schema;
|
|
@@ -75,7 +75,44 @@ FieldTranslatable.setMethod(function showPrefix(prefix) {
|
|
|
75
75
|
element.hidden = true;
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check the translation contents
|
|
82
|
+
*
|
|
83
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
84
|
+
* @since 0.2.4
|
|
85
|
+
* @version 0.2.4
|
|
86
|
+
*/
|
|
87
|
+
FieldTranslatable.setMethod(function checkTranslationContents() {
|
|
88
|
+
|
|
89
|
+
let field = this.field_context?.config;
|
|
90
|
+
|
|
91
|
+
let has_content,
|
|
92
|
+
buttons = this.querySelectorAll('button[data-has-content][data-prefix]'),
|
|
93
|
+
button,
|
|
94
|
+
prefix,
|
|
95
|
+
values = this.value,
|
|
96
|
+
value,
|
|
97
|
+
i;
|
|
98
|
+
|
|
99
|
+
for (i = 0; i < buttons.length; i++) {
|
|
100
|
+
button = buttons[i];
|
|
101
|
+
prefix = button.dataset.prefix;
|
|
102
|
+
value = values?.[prefix];
|
|
103
|
+
|
|
104
|
+
if (field) {
|
|
105
|
+
has_content = field.valueHasContent(value);
|
|
106
|
+
} else {
|
|
107
|
+
has_content = value != null && value !== '';
|
|
108
|
+
}
|
|
78
109
|
|
|
110
|
+
if (has_content) {
|
|
111
|
+
button.dataset.hasContent = 'true';
|
|
112
|
+
} else {
|
|
113
|
+
button.dataset.hasContent = 'false';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
79
116
|
});
|
|
80
117
|
|
|
81
118
|
/**
|
|
@@ -83,15 +120,37 @@ FieldTranslatable.setMethod(function showPrefix(prefix) {
|
|
|
83
120
|
*
|
|
84
121
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
85
122
|
* @since 0.1.0
|
|
86
|
-
* @version 0.
|
|
123
|
+
* @version 0.2.4
|
|
87
124
|
*/
|
|
88
125
|
FieldTranslatable.setMethod(function introduced() {
|
|
89
126
|
|
|
90
|
-
const that = this
|
|
127
|
+
const that = this,
|
|
128
|
+
field = this.field_context;
|
|
129
|
+
|
|
130
|
+
let doTranslationCheck = Function.throttle(() => {
|
|
131
|
+
|
|
132
|
+
if (field?.purpose == 'view') {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
that.checkTranslationContents();
|
|
137
|
+
}, 500, true, true);
|
|
91
138
|
|
|
92
139
|
this.onEventSelector('click', '.prefix-buttons button[data-prefix]', function onClick(e) {
|
|
140
|
+
|
|
93
141
|
e.preventDefault();
|
|
94
|
-
|
|
142
|
+
|
|
143
|
+
let button = this.closest('[data-prefix]');
|
|
144
|
+
|
|
145
|
+
if (!button) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
that.showPrefix(button.dataset.prefix);
|
|
150
|
+
doTranslationCheck();
|
|
95
151
|
});
|
|
96
152
|
|
|
153
|
+
this.addEventListener('change', doTranslationCheck);
|
|
154
|
+
this.addEventListener('keyup', doTranslationCheck);
|
|
155
|
+
this.addEventListener('click', doTranslationCheck);
|
|
97
156
|
});
|
|
@@ -25,6 +25,22 @@ FieldTranslatableEntry.setTemplateFile('form/elements/alchemy_field_translatable
|
|
|
25
25
|
*/
|
|
26
26
|
FieldTranslatableEntry.setAttribute('prefix');
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Does this translation entry have a valid value?
|
|
30
|
+
*
|
|
31
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
32
|
+
* @since 0.2.4
|
|
33
|
+
* @version 0.2.4
|
|
34
|
+
*/
|
|
35
|
+
FieldTranslatableEntry.setProperty(function has_content() {
|
|
36
|
+
|
|
37
|
+
let field_translatable_el = this.field_context,
|
|
38
|
+
field_el = field_translatable_el.field_context,
|
|
39
|
+
field = field_el.config;
|
|
40
|
+
|
|
41
|
+
field.valueHasContent(this.value);
|
|
42
|
+
});
|
|
43
|
+
|
|
28
44
|
/**
|
|
29
45
|
* Get the original value
|
|
30
46
|
*
|
|
@@ -34,7 +50,9 @@ FieldTranslatableEntry.setAttribute('prefix');
|
|
|
34
50
|
*/
|
|
35
51
|
FieldTranslatableEntry.setProperty(function original_value() {
|
|
36
52
|
|
|
37
|
-
let
|
|
53
|
+
let field_translatable_el = this.field_context;
|
|
54
|
+
|
|
55
|
+
let context_value = field_translatable_el.original_value;
|
|
38
56
|
|
|
39
57
|
if (context_value) {
|
|
40
58
|
return context_value[this.prefix];
|
package/element/al_form.js
CHANGED
|
@@ -289,7 +289,7 @@ Form.setMethod(async function showViolations(err) {
|
|
|
289
289
|
*
|
|
290
290
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
291
291
|
* @since 0.1.0
|
|
292
|
-
* @version 0.2.
|
|
292
|
+
* @version 0.2.4
|
|
293
293
|
*
|
|
294
294
|
* @param {String} path
|
|
295
295
|
*
|
|
@@ -297,6 +297,10 @@ Form.setMethod(async function showViolations(err) {
|
|
|
297
297
|
*/
|
|
298
298
|
Form.setMethod(function findFieldByPath(path) {
|
|
299
299
|
|
|
300
|
+
if (!path) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
|
|
300
304
|
let current = this,
|
|
301
305
|
result,
|
|
302
306
|
pieces = path.split('.'),
|
package/package.json
CHANGED
|
@@ -8,9 +8,24 @@
|
|
|
8
8
|
<div class="prefix-buttons">
|
|
9
9
|
<% index = 0 %>
|
|
10
10
|
<% for (prefix in prefixes) { %>
|
|
11
|
-
|
|
11
|
+
<% value = null %>
|
|
12
|
+
<% if (values) value = values[prefix] %>
|
|
13
|
+
|
|
14
|
+
<button
|
|
15
|
+
data-prefix={% prefix %}
|
|
16
|
+
data-has-content=<% alchemy_field.config.valueHasContent(value) ? 'true' : 'false' %>
|
|
17
|
+
>
|
|
12
18
|
<% if (index == 0) $0.classList.add('active') %>
|
|
13
|
-
|
|
19
|
+
|
|
20
|
+
<span class="prefix-name">{{ prefix }}</span>
|
|
21
|
+
|
|
22
|
+
<al-icon-stack class="has-empty-content">
|
|
23
|
+
<al-icon icon-name="language"></al-icon>
|
|
24
|
+
<al-icon icon-name="ban" size=2></al-icon>
|
|
25
|
+
</al-icon-stack>
|
|
26
|
+
|
|
27
|
+
<al-icon class="has-content" icon-name="language"></al-icon>
|
|
28
|
+
|
|
14
29
|
</button>
|
|
15
30
|
|
|
16
31
|
<% index++ %>
|