Skip to content

Commit d455acb

Browse files
authored
Merge pull request OCA#25 from camptocamp/ui-imp-fix
Misc UI fixes/imp
2 parents f0f53a8 + 0348c6a commit d455acb

File tree

13 files changed

+261
-142
lines changed

13 files changed

+261
-142
lines changed

shopfloor_mobile/static/wms/src/components/batch_picking_detail.js

+16-7
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,22 @@ Vue.component("batch-picking-detail", {
1111
},
1212
picking_detail_fields() {
1313
return [
14+
{path: "name", klass: "loud", action_val_path: "name"},
1415
{path: "move_line_count", label: "Lines"},
1516
{path: "weight", label: "Weight"},
1617
];
1718
},
19+
picking_list_options() {
20+
return {
21+
group_title_default: "Pickings list",
22+
group_color: this.utils.colors.color_for("screen_step_todo"),
23+
list_item_options: {
24+
key_title: "name",
25+
bold_title: true,
26+
fields: this.picking_detail_fields(),
27+
},
28+
};
29+
},
1830
},
1931
template: `
2032
<div class="detail batch-picking-detail with-bottom-actions" v-if="!_.isEmpty(record)">
@@ -40,13 +52,10 @@ Vue.component("batch-picking-detail", {
4052
</div>
4153
4254
<div class="pickings">
43-
<separator-title>Pickings list</separator-title>
44-
<detail-picking
45-
v-for="picking in record.pickings"
46-
:key="picking.id"
47-
:record="picking"
48-
:options="{fields: picking_detail_fields()}"
49-
/>
55+
<list
56+
:records="record.pickings"
57+
:options="picking_list_options()"
58+
/>
5059
</div>
5160
5261
</div>

shopfloor_mobile/static/wms/src/components/list.js

+37-26
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,14 @@ Vue.component("list", {
3636
listable() {
3737
if (!this.grouped_records.length) {
3838
// Simulate grouping (allows to keep template the same)
39-
return [{key: "no-group", title: "", records: this.records}];
39+
return [
40+
{
41+
key: "no-group",
42+
title: this.opts.group_title_default,
43+
44+
records: this.records,
45+
},
46+
];
4047
}
4148
return this.grouped_records;
4249
},
@@ -52,6 +59,7 @@ Vue.component("list", {
5259
list_item_actions: [],
5360
list_item_on_click: null,
5461
list_item_options: {},
62+
group_title_default: "",
5563
});
5664
return opts;
5765
},
@@ -81,15 +89,14 @@ Vue.component("list", {
8189
},
8290
template: `
8391
<div :class="klass">
84-
<v-card>
92+
<v-card class="list-group" :color="opts.group_color" v-for="(group, gindex) in listable" :key="make_component_key([$options._componentTag, 'group', gindex])">
93+
<v-card-title v-if="group.title">{{ group.title }}</v-card-title>
8594
<v-list v-if="has_records">
86-
<div class="list-group" v-for="group in listable" :key="make_component_key(['group', group.key])">
87-
<v-card-title v-if="group.title">{{ group.title }}</v-card-title>
88-
<div class="list-items-wrapper">
89-
<v-list-item
90-
v-for="(rec, index) in group.records" :key="make_component_key(['group', group.key, index])"
91-
@click="opts.list_item_on_click ? opts.list_item_on_click(rec) : undefined"
92-
:class="list_item_options.list_item_klass_maker ? list_item_options.list_item_klass_maker(rec) : ''">
95+
<div class="list-item-wrapper" v-for="(rec, index) in group.records">
96+
<v-list-item :key="make_component_key(['group-rec', gindex, index, rec.id])"
97+
:class="list_item_options.list_item_klass_maker ? list_item_options.list_item_klass_maker(rec) : ''"
98+
@click="opts.list_item_on_click ? opts.list_item_on_click(rec) : undefined">
99+
<v-list-item-content>
93100
<component
94101
:is="opts.list_item_component"
95102
:options="list_item_options"
@@ -98,25 +105,29 @@ Vue.component("list", {
98105
:count="group.records.length"
99106
:key="make_component_key([opts.list_item_component, 'list', index, rec.id])"
100107
/>
101-
<v-list-item-action v-if="opts.list_item_actions.length">
102-
<component
103-
v-for="action in opts.list_item_actions"
104-
:is="action.comp_name"
105-
v-if="action.enabled(rec, action)"
106-
:options="_.merge({}, list_item_options, action.options)"
107-
:record="action.get_record(rec, action)"
108-
:index="index"
109-
:count="group.records.length"
110-
:key="make_component_key([action.comp_name, 'list', index, action.get_record(rec, action).id])"
111-
/>
112-
</v-list-item-action>
113-
</v-list-item>
114-
</div>
108+
</v-list-item-content>
109+
<v-list-item-action v-if="opts.list_item_actions.length">
110+
<component
111+
v-for="action in opts.list_item_actions"
112+
:is="action.comp_name"
113+
v-if="action.enabled(rec, action)"
114+
:options="_.merge({}, list_item_options, action.options)"
115+
:record="action.get_record(rec, action)"
116+
:index="index"
117+
:count="group.records.length"
118+
:key="make_component_key([action.comp_name, 'list', index, action.get_record(rec, action).id])"
119+
/>
120+
</v-list-item-action>
121+
</v-list-item>
115122
</div>
116123
</v-list>
117-
<div class="no-record pa-2" v-if="!has_records">
118-
<p class="text--secondary">No item to list.</p>
119-
</div>
124+
<v-list v-if="!has_records">
125+
<v-list-item>
126+
<v-list-item-content>
127+
<p class="text--secondary">No item to list.</p>
128+
</v-list-item-content>
129+
</v-list-item>
130+
</v-list>
120131
</v-card>
121132
</div>
122133
`,

shopfloor_mobile/static/wms/src/components/manual_select.js

+30-14
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ Vue.component("manual-select", {
164164
list_item_extra_component: "",
165165
selected_event: "select",
166166
group_color: "",
167+
group_title_default: "",
167168
});
168169
return opts;
169170
},
@@ -180,7 +181,13 @@ Vue.component("manual-select", {
180181
selectable() {
181182
if (!this.grouped_records.length) {
182183
// Simulate grouping (allows to keep template the same)
183-
return [{key: "no-group", title: "", records: this.records}];
184+
return [
185+
{
186+
key: "no-group",
187+
title: this.opts.group_title_default,
188+
records: this.records,
189+
},
190+
];
184191
}
185192
return this.grouped_records;
186193
},
@@ -224,7 +231,7 @@ Vue.component("manual-select", {
224231
:key="make_component_key([opts.list_item_component, index, rec.id])"
225232
/>
226233
</v-list-item-content>
227-
<v-list-item-action :class="{'d-flex align-stretch': opts.list_item_actions.length}">
234+
<v-list-item-action>
228235
<component
229236
v-for="(action, action_index) in opts.list_item_actions"
230237
:is="action.comp_name"
@@ -236,16 +243,18 @@ Vue.component("manual-select", {
236243
:key="make_component_key([action.comp_name, index, action_index, rec.id])"
237244
/>
238245
<div class="action action-select">
239-
<input
240-
:class="['sf-checkbox', is_selected(rec) ? selected_color_klass('darken-3') : '']"
241-
type="checkbox"
242-
:input-value="rec.id"
243-
:true-value="rec.id"
244-
:value="rec.id"
245-
:checked="is_selected(rec)"
246-
:key="make_component_key(['list-checkbox', index, rec.id])"
247-
@click="handleSelect(rec, $event)"
248-
/>
246+
<v-btn icon x-large rounded>
247+
<input
248+
:class="['sf-checkbox', is_selected(rec) ? selected_color_klass('darken-3') : '']"
249+
type="checkbox"
250+
:input-value="rec.id"
251+
:true-value="rec.id"
252+
:value="rec.id"
253+
:checked="is_selected(rec)"
254+
:key="make_component_key(['list-checkbox', index, rec.id])"
255+
@click="handleSelect(rec, $event)"
256+
/>
257+
</v-btn>
249258
</div>
250259
</v-list-item-action>
251260
</v-list-item>
@@ -262,8 +271,15 @@ Vue.component("manual-select", {
262271
</div>
263272
</v-list>
264273
</v-card>
265-
<v-card class="no-record pa-2" v-if="!has_records">
266-
<p class="text--secondary">No item to select.</p>
274+
<v-card :color="opts.group_color" class="no-record pa-2" v-if="!has_records">
275+
<!-- Use v-list to have the same look and feel of the record list -->
276+
<v-list>
277+
<v-list-item>
278+
<v-list-item-content>
279+
<p class="text--secondary">No item to select.</p>
280+
</v-list-item-content>
281+
</v-list-item>
282+
</v-list>
267283
</v-card>
268284
<v-row class="actions bottom-actions" v-if="has_records && opts.showActions">
269285
<v-col>

shopfloor_mobile/static/wms/src/components/misc.js

+33-10
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ Vue.component("last-operation", {
5151
Vue.component("get-work", {
5252
template: `
5353
<div class="get-work fullscreen-buttons fullscreen-buttons-50">
54-
<btn-action id="btn-get-work" color="success" @click="$emit('get_work')">
54+
<btn-action id="btn-get-work" @click="$emit('get_work')">
5555
Get work
5656
</btn-action>
57-
<v-btn id="btn-manual" color="default" @click="$emit('manual_selection')">
57+
<btn-action id="btn-manual" color="default" @click="$emit('manual_selection')">
5858
Manual selection
59-
</v-btn>
59+
</btn-action>
6060
</div>
6161
`,
6262
});
@@ -117,12 +117,6 @@ Vue.component("edit-action", {
117117
`,
118118
});
119119

120-
Vue.component("btn-back", {
121-
template: `
122-
<v-btn x-large color="default" v-on:click="$router.back()">{{ $t("btn.back.title") }}</v-btn>
123-
`,
124-
});
125-
126120
Vue.component("separator-title", {
127121
template: `
128122
<h3 class="separator-title"><slot></slot></h3>
@@ -218,10 +212,39 @@ Vue.component("btn-action", {
218212
type: String,
219213
default: "",
220214
},
215+
color: {
216+
type: String,
217+
default: "",
218+
},
219+
},
220+
computed: {
221+
btn_color() {
222+
let color = this.color;
223+
if (!color) {
224+
color = this.utils.colors.color_for(
225+
this.action ? "btn_action_" + this.action : "btn_action"
226+
);
227+
}
228+
return color;
229+
},
221230
},
222231
template: `
223-
<v-btn x-large v-bind="$attrs" v-on="$listeners" :color="utils.colors.color_for(action ? 'btn_action_' + action : 'btn_action')">
232+
<v-btn x-large v-bind="$attrs" v-on="$listeners" :color="btn_color">
224233
<slot></slot>
225234
</v-btn>
226235
`,
227236
});
237+
238+
Vue.component("btn-back", {
239+
methods: {
240+
on_back: function() {
241+
this.$root.trigger("go_back");
242+
this.$router.back();
243+
},
244+
},
245+
template: `
246+
<btn-action v-bind="$attrs" action="back" v-on:click="on_back">
247+
<v-icon>mdi-keyboard-backspace</v-icon>{{ $t("btn.back.title") }}
248+
</btn-action>
249+
`,
250+
});

shopfloor_mobile/static/wms/src/components/packaging-qty-picker.js

+42-26
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ export var PackagingQtyPickerMixin = {
1313
methods: {
1414
on_change_pkg_qty: function(event) {
1515
const input = event.target;
16-
let new_qty = parseInt(input.value, 10);
16+
let new_qty = parseInt(input.value || 0, 10);
1717
const data = $(input).data();
18-
const origvalue = data.origvalue || 0;
18+
const origvalue = parseInt(data.origvalue || 0, 10);
1919
// Check max qty reached
2020
const future_qty = this.value + data.pkg.qty * (new_qty - origvalue);
2121
if (new_qty && future_qty > this.original_value) {
@@ -75,6 +75,10 @@ export var PackagingQtyPickerMixin = {
7575
// const min_unit = _.last(pkg_by_qty);
7676
pkg_by_qty.forEach(function(pkg) {
7777
let qty_per_pkg = 0;
78+
if (!pkg.qty) {
79+
console.error("Packaging with no quantity: skipping", pkg);
80+
return {};
81+
}
7882
[qty_per_pkg, qty] = self._qty_by_pkg(pkg.qty, qty);
7983
if (qty_per_pkg) res[pkg.id] = qty_per_pkg;
8084
if (!qty) return;
@@ -108,36 +112,33 @@ export var PackagingQtyPickerMixin = {
108112
compute_qty: function(newVal, oldVal) {
109113
this.value = this._compute_qty();
110114
},
111-
},
112-
watch: {
113-
value: {
114-
handler: function(newVal, oldVal) {
115-
this.$root.trigger("qty_edit", this.value);
116-
},
115+
_init_editable() {
116+
const self = this;
117+
this.$watch(
118+
"qty_by_pkg",
119+
function() {
120+
self.compute_qty();
121+
},
122+
{deep: true}
123+
);
124+
this.qty_by_pkg = this.product_qty_by_packaging();
125+
this.orig_qty_by_pkg = this.qty_by_pkg;
126+
// hooking via `v-on:change` we don't get the full event but only the qty :/
127+
// And forget about using v-text-field because it loses the full event object
128+
$(".pkg-value", this.$el).change(this.on_change_pkg_qty);
129+
$(".pkg-value", this.$el).on("focus click", function() {
130+
$(this).select();
131+
});
132+
},
133+
_init_readonly() {
134+
this.qty_by_pkg = this.product_qty_by_packaging();
135+
this.compute_qty();
117136
},
118137
},
119138
created: function() {
120139
this.original_value = parseInt(this.opts.init_value, 10);
121140
this.value = parseInt(this.opts.init_value, 10);
122141
},
123-
mounted: function() {
124-
const self = this;
125-
this.$watch(
126-
"qty_by_pkg",
127-
function() {
128-
self.compute_qty();
129-
},
130-
{deep: true}
131-
);
132-
this.qty_by_pkg = this.product_qty_by_packaging();
133-
this.orig_qty_by_pkg = this.qty_by_pkg;
134-
// hooking via `v-on:change` we don't get the full event but only the qty :/
135-
// And forget about using v-text-field because it loses the full event object
136-
$(".pkg-value", this.$el).change(this.on_change_pkg_qty);
137-
$(".pkg-value", this.$el).on("focus click", function() {
138-
$(this).select();
139-
});
140-
},
141142
computed: {
142143
opts() {
143144
const opts = _.defaults({}, this.$props.options, {
@@ -180,6 +181,16 @@ export var PackagingQtyPickerMixin = {
180181

181182
export var PackagingQtyPicker = Vue.component("packaging-qty-picker", {
182183
mixins: [PackagingQtyPickerMixin],
184+
watch: {
185+
value: {
186+
handler: function(newVal, oldVal) {
187+
this.$root.trigger("qty_edit", this.value);
188+
},
189+
},
190+
},
191+
mounted: function() {
192+
this._init_editable();
193+
},
183194
template: `
184195
<div :class="[$options._componentTag, opts.mode ? 'mode-' + opts.mode: '']">
185196
<v-row class="unit-value">
@@ -211,12 +222,17 @@ export var PackagingQtyPicker = Vue.component("packaging-qty-picker", {
211222

212223
export var PackagingQtyPickerDisplay = Vue.component("packaging-qty-picker-display", {
213224
mixins: [PackagingQtyPickerMixin],
225+
mounted: function() {
226+
this._init_readonly();
227+
},
214228
template: `
215229
<div :class="[$options._componentTag, opts.mode ? 'mode-' + opts.mode: '', 'd-inline']">
216230
<span class="packaging" v-for="(pkg, index) in sorted_packaging">
217231
<span class="pkg-qty" v-text="qty_by_pkg[pkg.id] || 0" />
218232
<span class="pkg-name" v-text="pkg.name" /><span class="sep" v-if="index != Object.keys(sorted_packaging).length - 1">, </span>
219233
</span>
234+
<!-- TOOO: use product uom -->
235+
<span class="min-unit">({{ opts.init_value }} Units)</span>
220236
</div>
221237
`,
222238
});

0 commit comments

Comments
 (0)