合并企业版代码(未测试,先提交到测试分支)
This commit is contained in:
45
quality/static/src/scss/tablet_view.scss
Normal file
45
quality/static/src/scss/tablet_view.scss
Normal file
@@ -0,0 +1,45 @@
|
||||
// Add a picture
|
||||
.workorder_picture, .quality_picture {
|
||||
margin: 5px 0;
|
||||
|
||||
.o_legacy_field_widget.o_field_image {
|
||||
position: relative;
|
||||
margin-bottom: $o-horizontal-padding !important;
|
||||
|
||||
img {
|
||||
height: 100px;
|
||||
}
|
||||
.o_form_image_controls {
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
cursor: zoom-in;
|
||||
|
||||
.o_clear_file_button {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background-color: #00A09D;
|
||||
cursor: pointer;
|
||||
padding: 4px 8px;
|
||||
margin: 0;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.o_form_binary_progress {
|
||||
position: absolute;
|
||||
bottom: -18px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.o_hidden_input_file {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#picture_button {
|
||||
margin-top: 0;
|
||||
@include o-position-absolute($top: 33%, $left: 106%);
|
||||
}
|
||||
}
|
||||
29
quality/static/src/tablet_image_field/tablet_image_field.js
Normal file
29
quality/static/src/tablet_image_field/tablet_image_field.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
import { ImageField } from '@web/views/fields/image/image_field';
|
||||
|
||||
const { Component } = owl;
|
||||
|
||||
class ImagePreviewDialog extends Component {}
|
||||
ImagePreviewDialog.components = { Dialog };
|
||||
ImagePreviewDialog.template = "quality.ImagePreviewDialog";
|
||||
|
||||
export class TabletImageField extends ImageField {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.dialog = useService("dialog");
|
||||
}
|
||||
|
||||
openModal() {
|
||||
this.dialog.add(ImagePreviewDialog, {
|
||||
src: this.getUrl(this.props.name),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
TabletImageField.template = "quality.TabletImageField";
|
||||
|
||||
registry.category("fields").add("tablet_image", TabletImageField);
|
||||
@@ -0,0 +1,24 @@
|
||||
.workorder_picture, .quality_picture {
|
||||
margin: 5px 0;
|
||||
|
||||
.o_field_tablet_image {
|
||||
img {
|
||||
height: 80px;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
button {
|
||||
@include o-hover-opacity(0.6, 0.9);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background-color: #00A09D !important;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
#picture_button {
|
||||
margin-top: 0;
|
||||
@include o-position-absolute($top: 33%, $left: 106%);
|
||||
}
|
||||
}
|
||||
26
quality/static/src/tablet_image_field/tablet_image_field.xml
Normal file
26
quality/static/src/tablet_image_field/tablet_image_field.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="quality.TabletImageField" t-inherit="web.ImageField" t-inherit-mode="primary" owl="1">
|
||||
<xpath expr="//button[hasclass('o_select_file_button')]" position="replace">
|
||||
<div class="position-absolute start-100 bottom-100 ms-2" id="picture_button">
|
||||
<button class="btn btn-primary o_select_file_button" barcode_trigger="measure">Take a Picture</button>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//img" position="attributes">
|
||||
<attribute name="t-on-click">openModal</attribute>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t t-name="quality.ImagePreviewDialog" owl="1">
|
||||
<Dialog title="'Preview'" size="'lg'">
|
||||
<div class="o_viewer_img_wrapper">
|
||||
<div class="o_viewer_zoomer">
|
||||
<img alt="Viewer" class="o_viewer_img" t-att-src="props.src"/>
|
||||
</div>
|
||||
</div>
|
||||
<t t-set-slot="footer">
|
||||
<button class="btn btn-primary" t-on-click.stop="props.close">Close</button>
|
||||
</t>
|
||||
</Dialog>
|
||||
</t>
|
||||
</templates>
|
||||
74
quality/static/tests/tablet_image_field_tests.js
Normal file
74
quality/static/tests/tablet_image_field_tests.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/** @odoo-module **/
|
||||
import { click, getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
let serverData;
|
||||
let target;
|
||||
const MY_IMAGE =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==";
|
||||
|
||||
QUnit.module("Quality", (hooks) => {
|
||||
hooks.beforeEach(() => {
|
||||
target = getFixture();
|
||||
serverData = {
|
||||
models: {
|
||||
partner: {
|
||||
fields: {
|
||||
document: { string: "Binary", type: "binary" },
|
||||
},
|
||||
records: [
|
||||
{
|
||||
id: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
setupViewRegistries();
|
||||
});
|
||||
|
||||
QUnit.module("TabletImageField");
|
||||
|
||||
QUnit.test("tablet image field: open a preview when clicked", async function (assert) {
|
||||
serverData.models.partner.records[0].document = MY_IMAGE;
|
||||
|
||||
await makeView({
|
||||
type: "form",
|
||||
serverData,
|
||||
resModel: "partner",
|
||||
resId: 1,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="document" widget="tablet_image" options="{'size': [90, 90]}" />
|
||||
</form>`,
|
||||
});
|
||||
|
||||
assert.containsOnce(
|
||||
target,
|
||||
".o_field_tablet_image",
|
||||
"field is present in the view"
|
||||
);
|
||||
assert.strictEqual(
|
||||
target.querySelector("#picture_button button").textContent,
|
||||
"Take a Picture",
|
||||
"button to open the modal displays the right text"
|
||||
);
|
||||
|
||||
await click(target, ".o_field_tablet_image img");
|
||||
assert.containsOnce(target, ".o_dialog", "a dialog is present");
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_viewer_img_wrapper img").dataset.src,
|
||||
`data:image/png;base64,${MY_IMAGE}`,
|
||||
"the dialog contains the right image"
|
||||
);
|
||||
|
||||
await click(target, ".modal-footer button");
|
||||
await click(target, ".o_field_tablet_image button:not(#picture_button button)");
|
||||
assert.containsNone(target, ".o_dialog", "no dialog should be present");
|
||||
assert.strictEqual(
|
||||
target.querySelector(".o_field_tablet_image img").dataset.src,
|
||||
"/web/static/img/placeholder.png",
|
||||
"the dialog contains the right image"
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user