[ADD] report_carbone, jsonifier, export_json : carbone is an alternative to Py3o
297
report_carbone/static/description/assets/description.css
Normal file
@@ -0,0 +1,297 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
a {
|
||||
color: "#5e17eb";
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Inter", sans-serif;
|
||||
line-height: 1.7;
|
||||
color: #001e2b;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
border-radius: 0;
|
||||
margin-bottom: 40px;
|
||||
position: relative;
|
||||
}
|
||||
.header-title-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 40px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.header-icon {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.header-icon img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
color: #5e17eb;
|
||||
font-size: 3em;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.header .subtitle {
|
||||
font-size: 1.8em;
|
||||
opacity: 0.85;
|
||||
margin-bottom: 15px;
|
||||
font-weight: 250;
|
||||
color: #e6fffa;
|
||||
}
|
||||
.badge {
|
||||
display: inline-block;
|
||||
background: transparent;
|
||||
border: 1px solid rgba(245, 243, 237, 0.3);
|
||||
padding: 10px 24px;
|
||||
border-radius: 2px;
|
||||
margin: 10px 8px;
|
||||
font-size: 0.85em;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 80px;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.section h2 {
|
||||
color: #001e2b;
|
||||
font-size: 2.2em;
|
||||
margin-bottom: 30px;
|
||||
border-bottom: 1px solid #001e2b;
|
||||
padding-bottom: 15px;
|
||||
font-weight: 400;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
color: #001e2b;
|
||||
font-size: 1.4em;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 30px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
background: #ffffff;
|
||||
padding: 35px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
.feature-card h4 {
|
||||
color: #001e2b;
|
||||
font-size: 1.15em;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.feature-card .icon {
|
||||
font-size: 1.4em;
|
||||
margin-right: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.feature-card p {
|
||||
color: #5a5a5a;
|
||||
line-height: 1.6;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
.screenshot-placeholder {
|
||||
background: #ffffff;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
color: #8a8a8a;
|
||||
font-size: 1em;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.02em;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.screenshot-placeholder img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
.benefits-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.benefits-list li {
|
||||
padding: 20px 0;
|
||||
border-bottom: 1px solid #e8e6df;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.benefits-list li:before {
|
||||
content: "—";
|
||||
color: #5e17eb;
|
||||
font-weight: 400;
|
||||
font-size: 1.3em;
|
||||
margin-right: 20px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.tech-specs {
|
||||
background: #ffffff;
|
||||
padding: 30px;
|
||||
border-radius: 0;
|
||||
margin-top: 30px;
|
||||
border: 1px solid #e8e6df;
|
||||
}
|
||||
|
||||
.tech-specs table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.tech-specs td {
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px solid #e8e6df;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
.tech-specs td:first-child {
|
||||
font-weight: 500;
|
||||
color: #001e2b;
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.tech-specs td:last-child {
|
||||
color: #5a5a5a;
|
||||
}
|
||||
|
||||
.cta-section {
|
||||
background: #001e2b;
|
||||
color: #f5f3ed;
|
||||
padding: 70px 60px;
|
||||
border-radius: 0;
|
||||
text-align: center;
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background: transparent;
|
||||
color: #f5f3ed;
|
||||
border: 2px solid #f5f3ed;
|
||||
padding: 16px 45px;
|
||||
border-radius: 2px;
|
||||
text-decoration: none;
|
||||
font-weight: 400;
|
||||
font-size: 1em;
|
||||
margin-top: 25px;
|
||||
transition: all 0.3s ease;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
background: #f5f3ed;
|
||||
color: #001e2b;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.doc-ressource-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin-left: 40px;
|
||||
line-height: 2;
|
||||
}
|
||||
.doc-ressource-list li:before {
|
||||
content: "—";
|
||||
color: #5e17eb;
|
||||
font-weight: 400;
|
||||
font-size: 1.3em;
|
||||
margin-right: 20px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.highlight-box {
|
||||
background: #5e17eb;
|
||||
border-left: 3px solid #001e2b;
|
||||
padding: 25px 30px;
|
||||
margin: 30px 0;
|
||||
border-radius: 0;
|
||||
color: #001e2b;
|
||||
}
|
||||
|
||||
.highlight-box strong {
|
||||
color: #001e2b;
|
||||
}
|
||||
.green-horizontal {
|
||||
width: 70px;
|
||||
height: 1px;
|
||||
background-color: #5e17eb;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
right: 90px;
|
||||
}
|
||||
|
||||
.text-item .text-bottom {
|
||||
font-weight: 700;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
.text-item .text-item .text-bottom {
|
||||
font-size: 44px;
|
||||
}
|
||||
.title-item h3 {
|
||||
margin: 0;
|
||||
}
|
||||
.title-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.footer {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
color: #666;
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 892 KiB |
|
After Width: | Height: | Size: 799 KiB |
|
After Width: | Height: | Size: 2.6 MiB |
BIN
report_carbone/static/description/assets/gifs/pop-up-worflow.gif
Normal file
|
After Width: | Height: | Size: 376 KiB |
|
After Width: | Height: | Size: 736 KiB |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 140 KiB |
BIN
report_carbone/static/description/assets/logo/icon-use-case.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 57 KiB |
BIN
report_carbone/static/description/assets/logo/mangono-logo.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
report_carbone/static/description/assets/logo/mangono_logo.jpg
Normal file
|
After Width: | Height: | Size: 248 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 258 KiB |
|
After Width: | Height: | Size: 180 KiB |
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 255 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 142 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 166 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 229 48"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:space="preserve"
|
||||
xmlns:serif="http://www.serif.com/"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
|
||||
>
|
||||
<g id="original">
|
||||
<path
|
||||
d="M35.015,0l-32.18,0c-1.566,0 -2.835,1.269 -2.835,2.835l-0,42.132c-0,1.566 1.269,2.835 2.835,2.835c7.732,0 29.127,0 36.859,0c0.752,0 1.473,-0.299 2.004,-0.83c0.532,-0.532 0.831,-1.253 0.831,-2.005c-0,-9.176 -0,-37.478 -0,-37.478l-7.514,-7.489Z"
|
||||
style="fill:#a544c5;"
|
||||
/>
|
||||
<path
|
||||
d="M60.53,37.702c-3.43,0 -6.114,-0.671 -8.052,-2.013c-1.939,-1.342 -2.908,-3.309 -2.908,-5.901c-0,-2.336 0.759,-4.126 2.276,-5.37c1.517,-1.244 3.675,-1.999 6.476,-2.266l7.362,-0.742l0,-1.172c0,-1.559 -0.507,-2.693 -1.523,-3.402c-1.015,-0.709 -2.409,-1.063 -4.181,-1.063c-1.41,-0 -2.772,0.192 -4.087,0.576c-1.315,0.385 -2.485,0.827 -3.51,1.328c-0.332,-0.268 -0.625,-0.614 -0.879,-1.038c-0.255,-0.425 -0.382,-0.863 -0.382,-1.316c-0,-1.136 0.621,-1.981 1.863,-2.535c0.974,-0.465 2.108,-0.818 3.402,-1.058c1.294,-0.24 2.623,-0.36 3.987,-0.36c3.291,-0 5.91,0.716 7.855,2.148c1.946,1.432 2.919,3.682 2.919,6.749l-0,12.368c-0,0.817 -0.18,1.453 -0.54,1.909c-0.36,0.456 -0.855,0.87 -1.485,1.244c-0.927,0.519 -2.127,0.967 -3.6,1.346c-1.472,0.379 -3.137,0.568 -4.993,0.568Zm0,-4.359c1.237,-0 2.306,-0.125 3.209,-0.376c0.902,-0.251 1.556,-0.508 1.96,-0.771l0,-6.72l-5.8,0.585c-1.6,0.122 -2.807,0.474 -3.621,1.056c-0.814,0.582 -1.221,1.43 -1.221,2.544c0,1.139 0.452,2.037 1.356,2.695c0.904,0.658 2.276,0.987 4.117,0.987Z"
|
||||
style="fill:#a544c5;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M87.41,17.492l0,7.721l-5.575,0l-0,-7.878c-0,-0.872 0.184,-1.586 0.554,-2.142c0.37,-0.556 0.932,-1.079 1.688,-1.568c1.008,-0.64 2.317,-1.174 3.927,-1.6c1.609,-0.427 3.361,-0.641 5.255,-0.641c3.114,0 4.67,0.89 4.67,2.669c0,0.433 -0.063,0.834 -0.188,1.203c-0.126,0.37 -0.287,0.686 -0.483,0.947c-0.354,-0.07 -0.803,-0.136 -1.349,-0.197c-0.545,-0.061 -1.105,-0.091 -1.681,-0.091c-1.417,0 -2.71,0.151 -3.877,0.451c-1.168,0.301 -2.148,0.676 -2.941,1.126Zm-5.575,5.446l5.575,0.458l0,13.443c-0.236,0.081 -0.583,0.168 -1.04,0.261c-0.457,0.093 -0.957,0.14 -1.5,0.14c-1.019,0 -1.779,-0.192 -2.282,-0.577c-0.502,-0.384 -0.753,-1.046 -0.753,-1.984l-0,-11.741Z"
|
||||
style="fill:#a544c5;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M118.188,11.37c2.23,-0 4.242,0.48 6.036,1.441c1.794,0.961 3.209,2.411 4.245,4.348c1.037,1.938 1.555,4.378 1.555,7.321c-0,2.958 -0.541,5.413 -1.623,7.365c-1.082,1.953 -2.586,3.411 -4.512,4.374c-1.927,0.963 -4.173,1.445 -6.74,1.445c-1.899,0 -3.579,-0.232 -5.039,-0.695c-1.46,-0.464 -2.666,-0.983 -3.619,-1.557c-0.742,-0.504 -1.271,-1.008 -1.589,-1.511c-0.317,-0.503 -0.475,-1.146 -0.475,-1.927l-0,-17.338l5.56,0l0,17.115c0.491,0.339 1.181,0.658 2.072,0.957c0.891,0.299 1.912,0.449 3.061,0.449c2.175,-0 3.924,-0.708 5.247,-2.124c1.323,-1.415 1.984,-3.6 1.984,-6.553c0,-2.999 -0.66,-5.185 -1.981,-6.558c-1.321,-1.373 -3.026,-2.06 -5.115,-2.06c-1.314,0 -2.479,0.252 -3.495,0.755c-1.017,0.502 -1.863,1.073 -2.54,1.71l-0.572,-4.513c0.787,-0.551 1.809,-1.097 3.067,-1.636c1.258,-0.539 2.749,-0.808 4.473,-0.808Zm-6.186,4.485l-5.575,0l-0,-13.328c0.235,-0.081 0.588,-0.168 1.058,-0.261c0.47,-0.093 0.977,-0.14 1.52,-0.14c1.029,-0 1.786,0.19 2.27,0.569c0.485,0.38 0.727,1.044 0.727,1.992l0,11.168Z"
|
||||
style="fill:#a544c5;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M163.493,24.509c-0,2.674 -0.516,4.997 -1.549,6.969c-1.032,1.973 -2.488,3.497 -4.367,4.573c-1.88,1.075 -4.092,1.613 -6.635,1.613c-2.537,0 -4.752,-0.535 -6.646,-1.605c-1.894,-1.07 -3.358,-2.591 -4.392,-4.564c-1.034,-1.974 -1.551,-4.302 -1.551,-6.986c0,-2.694 0.526,-5.02 1.578,-6.978c1.052,-1.958 2.524,-3.474 4.418,-4.549c1.894,-1.075 4.094,-1.612 6.598,-1.612c2.506,-0 4.698,0.539 6.577,1.619c1.879,1.079 3.344,2.599 4.394,4.56c1.05,1.96 1.575,4.281 1.575,6.96Zm-12.554,-8.647c-2.108,0 -3.78,0.765 -5.018,2.295c-1.237,1.53 -1.856,3.647 -1.856,6.352c-0,2.751 0.604,4.882 1.813,6.394c1.21,1.512 2.898,2.269 5.064,2.269c2.146,-0 3.822,-0.765 5.029,-2.295c1.207,-1.53 1.81,-3.652 1.81,-6.368c0,-2.695 -0.606,-4.81 -1.817,-6.345c-1.211,-1.535 -2.886,-2.302 -5.025,-2.302Z"
|
||||
style="fill:#a544c5;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M195.564,20.647l0,5.257l-5.575,-0l-0,-5.03c-0,-1.731 -0.493,-3 -1.477,-3.804c-0.984,-0.805 -2.299,-1.208 -3.944,-1.208c-1.216,0 -2.305,0.152 -3.267,0.456c-0.961,0.304 -1.801,0.661 -2.519,1.07l0,8.516l-5.575,-0l-0,-8.704c-0,-0.802 0.165,-1.458 0.494,-1.97c0.33,-0.512 0.861,-1.002 1.593,-1.471c0.998,-0.619 2.302,-1.172 3.91,-1.659c1.608,-0.487 3.406,-0.73 5.393,-0.73c3.433,-0 6.119,0.772 8.059,2.318c1.939,1.545 2.908,3.865 2.908,6.959Zm-22.357,2.52l5.575,-0l0,13.672c-0.236,0.081 -0.583,0.168 -1.04,0.261c-0.457,0.093 -0.957,0.14 -1.5,0.14c-1.019,0 -1.779,-0.192 -2.282,-0.577c-0.502,-0.384 -0.753,-1.046 -0.753,-1.984l-0,-11.512Zm16.782,-0l5.575,-0l0,13.672c-0.236,0.081 -0.589,0.168 -1.059,0.261c-0.47,0.093 -0.963,0.14 -1.481,0.14c-1.044,0 -1.811,-0.192 -2.301,-0.577c-0.49,-0.384 -0.734,-1.046 -0.734,-1.984l-0,-11.512Z"
|
||||
style="fill:#a544c5;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M208.92,27.583l-0.242,-4.066l14.952,-2.128c-0.121,-1.597 -0.703,-2.946 -1.746,-4.047c-1.043,-1.102 -2.516,-1.652 -4.418,-1.652c-1.973,-0 -3.606,0.695 -4.899,2.084c-1.292,1.389 -1.948,3.377 -1.968,5.964l0.089,2.086c0.277,2.49 1.17,4.352 2.679,5.586c1.508,1.234 3.485,1.851 5.931,1.851c1.484,0 2.846,-0.233 4.087,-0.698c1.241,-0.465 2.229,-0.965 2.966,-1.501c0.438,0.277 0.794,0.626 1.068,1.045c0.274,0.42 0.412,0.882 0.412,1.385c-0,0.81 -0.395,1.531 -1.185,2.164c-0.789,0.632 -1.848,1.125 -3.176,1.478c-1.329,0.353 -2.83,0.53 -4.504,0.53c-2.73,0 -5.123,-0.502 -7.179,-1.506c-2.056,-1.004 -3.652,-2.504 -4.789,-4.5c-1.137,-1.995 -1.706,-4.451 -1.706,-7.367c0,-2.103 0.317,-3.958 0.949,-5.565c0.633,-1.607 1.503,-2.954 2.609,-4.039c1.107,-1.085 2.402,-1.91 3.885,-2.473c1.483,-0.563 3.068,-0.844 4.754,-0.844c2.254,-0 4.235,0.466 5.942,1.4c1.707,0.933 3.047,2.227 4.018,3.88c0.971,1.653 1.456,3.549 1.456,5.688c0,0.897 -0.221,1.555 -0.663,1.974c-0.443,0.42 -1.061,0.68 -1.856,0.78l-17.466,2.491Z"
|
||||
style="fill:#a544c5;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M23.852,15.915c-2.224,0 -4.089,0.743 -5.596,2.23c-1.506,1.487 -2.259,3.631 -2.259,6.432c0,2.776 0.727,4.898 2.18,6.364c1.453,1.467 3.34,2.201 5.66,2.201c1.366,-0 2.521,-0.184 3.466,-0.55c0.944,-0.367 1.776,-0.78 2.493,-1.241c0.469,0.29 0.839,0.63 1.111,1.017c0.271,0.387 0.407,0.86 0.407,1.418c0,1.109 -0.723,2.03 -2.169,2.763c-1.447,0.734 -3.32,1.1 -5.619,1.1c-2.577,0 -4.862,-0.48 -6.857,-1.442c-1.995,-0.961 -3.553,-2.413 -4.673,-4.355c-1.12,-1.943 -1.68,-4.367 -1.68,-7.275c-0,-2.931 0.59,-5.375 1.77,-7.33c1.18,-1.955 2.766,-3.423 4.756,-4.405c1.99,-0.982 4.167,-1.472 6.533,-1.472c2.28,-0 4.13,0.395 5.551,1.187c1.422,0.791 2.132,1.733 2.132,2.826c0,0.493 -0.133,0.936 -0.4,1.328c-0.268,0.392 -0.6,0.711 -0.999,0.957c-0.728,-0.461 -1.547,-0.868 -2.459,-1.222c-0.912,-0.354 -2.028,-0.531 -3.348,-0.531Z"
|
||||
style="fill:#fff;fill-rule:nonzero;"
|
||||
/>
|
||||
<path
|
||||
d="M35.015,6.638c-0,0.226 0.089,0.442 0.249,0.602c0.159,0.159 0.375,0.249 0.601,0.249c1.967,-0 6.664,-0 6.664,-0l-7.514,-7.489l-0,6.638Z"
|
||||
style="fill:#e8a4ff;fill-rule:nonzero;"
|
||||
/>
|
||||
</g>
|
||||
<script xmlns=""/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.6 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="11" stroke="#5e17eb" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 193 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
||||
<circle cx="9.5" cy="9.5" r="9.5" fill="#5e17eb"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 177 B |
BIN
report_carbone/static/description/banner.png
Normal file
|
After Width: | Height: | Size: 576 KiB |
BIN
report_carbone/static/description/icon.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
484
report_carbone/static/description/index.html
Normal file
@@ -0,0 +1,484 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Carbone Document Generator</title>
|
||||
<link rel="stylesheet" href="/report_carbone/static/description/assets/description.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" style="font-family: 'Inter', sans-serif; line-height: 1.7; color: #001E2B;background-color: #ffffff; max-width: 1200px; margin: 0 auto; padding: 20px;">
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<img src="assets/logo/Carbone BentoGrid.png" style="max-width: 100%;border-radius: 20px;"/>
|
||||
</div>
|
||||
|
||||
<h1 style="font-size: 2.5em;font-weight: 700;letter-spacing: -0.02em;margin-bottom:20px">Carbone Document Generator</h1>
|
||||
<!-- Description -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Description</h2>
|
||||
<!-- <img src="./assets/logo/icon-description.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
<p style="font-size: 1.1em; line-height: 1.8;">
|
||||
<strong>Carbone Document Generator</strong> is the ultimate solution for automating the creation of professional documents from your Odoo data and a Template file.
|
||||
Whether you need to generate invoices, contracts, reports, or any other type of document, Carbone makes it easy and efficient, without any coding.
|
||||
To get started: simply select your Odoo data, design a template in your preferred text editor (LibreOffice, Word, Excel, PowerPoint, or Google Docs), add Carbone tags (placeholders), and you’re ready to automate your documents!
|
||||
|
||||
</p>
|
||||
<div style="text-align: center;background-color: #5e17eb; padding: 25px 30px; margin: 30px 0; border-radius: 0; color: white;border-radius: 10px;">
|
||||
This integration is the official <b><a style="color:white" href="https://carbone.io" target="_blank">Carbone.io</a></b> connector for Odoo, developed and maintained by <b><a style="color:white" href="https://mangono.fr/">Mangono</a></b>, an Official Carbone Partner ⭐️
|
||||
</div>
|
||||
</div>
|
||||
<!-- Use cases -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Use Cases</h2>
|
||||
<!-- <img src="./assets/logo/icon-use-case.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
|
||||
|
||||
<ul style=" list-style-type: none">
|
||||
<li><b>Sales:</b> Generate quotes, contracts, and purchase orders.</li>
|
||||
<li><b>Logistics:</b> Create delivery notes, packing slips, and shipping labels.</li>
|
||||
<li><b>Human Resources:</b> Automate the creation of employment contracts, payslips, and onboarding documents.</li>
|
||||
<li><b>Finance:</b> Produce invoices, financial statements, and expense reports.</li>
|
||||
<li><b>Marketing:</b> Render personalized proposals, campaign reports, and promotional materials.</li>
|
||||
<li><b>Custom Models:</b> Build documents from any custom Odoo model to fit your specific business needs.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<!-- Fonctionnalités -->
|
||||
<div class="section" style="margin-bottom: 20px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Key Features</h2>
|
||||
<!-- <img src="./assets/logo/icon-key-features.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
<div class="features-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 30px; margin-top: 40px;">
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> Generate and Convert Documents Instantly</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Generate and convert documents from a customized Template and your Odoo data, including Leads, Contacts, Orders, and custom models.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span>Flexible Template Format Support</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Carbone supports an extensive range of input formats: PDF, DOCX, XLSX, PPTX, ODG, IDML, ODT, ODS, ODP, XML, HTML, and Markdown.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> Export to Any Format You Need</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Export your documents to 100+ formats, including PDF, ODT, DOCX, JPG, PNG, EPUB, ODS, XLSX, CSV, ODP, PPTX, XML, HTML, TXT, IDML, and many more.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> Design Templates in Your Preferred Editor</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Create your templates using the tools you already know and love, such as LibreOffice, Word, Excel, PowerPoint, Google Docs, Pages, and OnlyOffice. No need to learn new software or coding.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> Enterprise-Grade Features</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Enrich your documents with dynamic charts, tables, barcodes, images, colors, SVGs, hyperlinks, HTML from WYSIWYG editors, conditional rendering, and more.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;">
|
||||
<img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/>
|
||||
</span> Multi-Language Support</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Generate international reports with full support for multiple languages, numbers, dates, times, and currency formats.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> E-Signature Support</h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Enhance your documents with electronic signatures for secure and legally binding agreements.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> Merge PDFs </h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">Combine multiple documents into a single PDF document for streamlined document management.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature-card" style="border:1px solid #ebebeb;background-color: #ffffff; padding: 35px; border-radius: 16px; transition: transform 0.2s ease, box-shadow 0.2s ease;">
|
||||
<h4 style="color: #001E2B; font-size: 1.15em; margin-bottom: 12px; display: flex; align-items: center; font-weight: 500;"><span class="icon" style="font-size: 1.4em; margin-right: 12px; opacity: 0.8;"><img src="assets/svg/green-dot-empty.svg" alt="green-dot-empty"/></span> HTML to PDF Conversion </h4>
|
||||
<p style="color: #5a5a5a; line-height: 1.6; font-size: 0.95em;">If you're already using Gothenberg or Puppeteer, migrate to Carbone in seconds, and enjoy the powerful Carbone conversion, the fastest in the industry.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Screenshots Section -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Screenshots</h2>
|
||||
<!-- <img src="./assets/logo/icon-screenshots.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;flex-direction: column;padding-bottom: 10px;">
|
||||
<div style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Odoo Module Configuration</h3>
|
||||
</div>
|
||||
<p> After installing the module, you’ll need to add your Carbone API key (found in your <a style="color : #5e17eb" href="https://account.carbone.io/">Carbone account</a>). No subscription yet? No problem—use the free test API key to try it out first!</p>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/add_api_keys.png"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: left;flex-direction: column;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Creating Carbone Templates</h3>
|
||||
</div>
|
||||
<ul style=" list-style-type: none">
|
||||
<li><b>Step 1:</b> Open <a style="color : #5e17eb" href="https://studio.carbone.io/">Carbone Studio</a> (the web interface for managing templates).</li>
|
||||
<ul>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/open_carbone_studio.png"/>
|
||||
</div>
|
||||
<ul style=" list-style-type: none">
|
||||
<li><b>Step 2:</b> On the home page, click "Start from scratch" to begin designing your template.</li>
|
||||
<ul>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/landing_page_carbone.png"/>
|
||||
</div>
|
||||
|
||||
<ul style=" list-style-type: none">
|
||||
<li><b>Step 3:</b> Create your template using a text editor, and upload on Carbone Studio. The editor has three key sections to help you design your template:</li>
|
||||
<ul style=" list-style-type: none">
|
||||
<li>📄 Template Panel (on the top right panel): Where you upload and version your Template (e.g., invoices, contracts).</li>
|
||||
<li>📊 Data Model Editor (left panel): Here, you define the JSON data that fills your template (e.g., {d.firstName}).</li>
|
||||
<li>🔍 Document Preview (right panel): See a real-time PDF preview of your final document as you edit.</li>
|
||||
</ul>
|
||||
<ul><br>
|
||||
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/create_new_template_carbone.png"/>
|
||||
</div>
|
||||
|
||||
<b>Step 4:</b> Once your design is ready, save your changes, and get a Template ID.
|
||||
<ul style=" list-style-type: none">
|
||||
<li>1. Click "New document" to upload your template.</li>
|
||||
<li>2. Disable "Auto-reload" (to finalize changes).</li>
|
||||
<li>3. Click "Save": this generates a unique Template Version ID (you’ll need this for Odoo).</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/copie_template_carbone_id.png"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;padding-bottom: 10px;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Setting Up Document Generation in Odoo</h3>
|
||||
</div>
|
||||
|
||||
<ul style=" list-style-type: none">
|
||||
<li>In Odoo, go to Document Generation (main menu).</li>
|
||||
<li>Click "New" to create a document workflow.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/open_carbone_menu.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/new_button.png"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;padding-bottom: 10px;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Copy Your Template Version ID from Carbone into Odoo</h3>
|
||||
</div>
|
||||
|
||||
<ul style=" list-style-type: none">
|
||||
<li>1. Paste your Template Version ID from Carbone Studio (1).</li>
|
||||
<li>2. Select the Odoo data model (e.g., Invoices, Contacts).</li>
|
||||
<li>3. Customize translation and language settings (if needed).</li>
|
||||
<li>4. Click "Add to Print Menu" (2), now you’re ready to generate documents!</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/copie_carbone_template_id_add_menu.png"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;padding-bottom: 10px;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Real-time Configuration of your Document</h3>
|
||||
</div>
|
||||
|
||||
With Carbone’s Odoo integration, you can:
|
||||
<ul style="margin-left: 18px;">
|
||||
<li>Download your template and tweak it anytime using in your favorite text editor.</li>
|
||||
<li>See changes instantly with a live preview of the final document.</li>
|
||||
</ul>
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/gifs/live-reload-change-record.gif"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Document Generation</h3>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/gifs/generate-report-from-report.gif"/>
|
||||
</div>
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/gifs/generate-report-from-po.gif"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Track and Version Your Documents</h3>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/copie_unique_template_id.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/unique_template_id_on_odoo.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/gifs/different-report-with-one-template-id.gif"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Choose Your Own Data Models for Reports</h3>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/select_one_record.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/pop-up-export.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img src="assets/screenshots/pop-up-export-2.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/find-your-export.png"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0; ">Add and Manage Translations with Ease</h3>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/add_translate.png"/>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/add_source_and_translate.png"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin:0;">Translation for Multi-Language Reports</h3>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/gifs/report-translated.gif"/>
|
||||
</div>
|
||||
|
||||
<div class="title-item" style="display: flex; align-items: center;">
|
||||
<div class="green-horizontal" style="width: 70px;height: 1px; background-color: #5e17eb; position: relative; flex-shrink: 0;right: 90px;"></div>
|
||||
<h3 style="color: #001E2B; font-size: 1.4em; font-weight: 500; margin: 0;">Manage Access Rights Through Group-Based Permissions</h3>
|
||||
</div>
|
||||
|
||||
<div class="screenshot-placeholder" style="background-color: #ffffff; border-radius: 0; padding: 0; text-align: center; margin: 30px 0; color: #8a8a8a; font-size: 1em; font-weight: 400; letter-spacing: 0.02em; overflow: hidden; display: flex; flex-direction: column;">
|
||||
<img style="width: 100%; height: auto; object-fit: contain;display: block;" src="assets/screenshots/carbone_groups.png"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Avantages -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Why You’ll Love Carbone</h2>
|
||||
<!-- <img src="./assets/logo/icon-why-carbone2.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
|
||||
<ul class="benefits-list" style="list-style: '— '; padding: 0;" >
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Premium Support</strong><br>
|
||||
Get priority assistance through our official support ticketing system, backed by the Carbone engineering team.<br>
|
||||
We’re committed to providing the best premium support experience—you’ll be heard, championed, and empowered to succeed.
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Future-proof</strong><br>
|
||||
Every template you create is guaranteed to work with all future versions of the Carbone Engine. <br>
|
||||
You’ll never have to update or recreate your templates due to software changes.<br>
|
||||
New features are always optional and backward-compatible, so you can adopt them on your terms.<br>
|
||||
With Carbone, you can focus on your business, not maintenance.
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Built for Speed and Scalability</strong><br>
|
||||
Carbone delivers high-performance document generation, optimized at every level for speed, and efficiency.<br>
|
||||
Whether you’re generating a few documents or thousands, Carbone scales to meet your demands without compromising quality or performance.
|
||||
Its powerful rendering engine is designed to handle high-throughput processing, ensuring rapid processing and reliability, even with complex templates or high-volume batches.<br>
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Empowering you with Your Own Tools</strong><br>
|
||||
Not only can you create templates using your preferred text editor (LibreOffice, Word, Google Doc, and more),<br>
|
||||
but you can also sign your generated documents using leading e-signature providers like:<br>
|
||||
Docusign, Yousign, Documenso, DocuSeal, SignWell and more.
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Security & Privacy</strong><br>
|
||||
At Carbone, we carefully design products with the highest level of security to protect your privacy and give you control over your information.<br>
|
||||
Generated documents are processed in real time and returned directly to your Odoo application, and never stored on Carbone Servers.<br>
|
||||
Odoo data samples are not saved or logged on our servers. We prioritize your privacy and do not store any sensitive information.<br>
|
||||
Template files are stored securely on our servers, but they do not contain sensitive information unless explicitly added by you.
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Flexible Deployment: Cloud, Self-Hosted, or Private Cloud</strong><br>
|
||||
By default, the Carbone integration for Odoo uses the Carbone Cloud API, hosted and managed by us for seamless performance.<br>
|
||||
For organizations with <b>strict privacy or security requirements</b>, you can easily deploy Carbone On-Premise on your own infrastructure (GCP, Azure, AWS, or others).
|
||||
The transition from Cloud to On-Premise is instantaneous: simply update the API endpoint, and you’re up and running in minutes.
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Open Source</strong><br>
|
||||
The Carbone plugin for Odoo is open-source under the LGPL-3 license.<br>
|
||||
The Carbone Document Engine is open-core and available on <a href="https://github.com/carboneio/carbone" target="_blank">GitHub</a>, licensed under the <a href="https://github.com/carboneio/carbone/blob/master/LICENSE.md" target="_blank">Carbone Community License</a>.
|
||||
</div>
|
||||
</li>
|
||||
<li style="padding: 20px 0; border-bottom: 1px solid #e8e6df; display: flex; align-items: start;">
|
||||
<div>
|
||||
<strong>Trusted by Thousands of Happy Users</strong><br>
|
||||
Carbone is highly rated on major review platforms:<br> <b>|</b>
|
||||
G2: 4.8/5 (Top-rated document automation solution)<br> <b>|</b>
|
||||
Capterra: 4.8/5 (Loved for ease of use and reliability)<br> <b>|</b>
|
||||
Trustpilot: 4.7/5 (Praise for the best customer support in the industry)
|
||||
</div>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Installation -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Installation & Configuration</h2>
|
||||
<!-- <img src="./assets/logo/icon-installation.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
|
||||
<h3>1. Installation</h3>
|
||||
<p>Install the module from the Odoo Store or directly from your Odoo interface:</p>
|
||||
<ul style="margin-left: 40px; margin-top: 10px;">
|
||||
<li>Applications → Search for "Carbone Document Generator"</li>
|
||||
<li>Click on "Install"</li>
|
||||
</ul>
|
||||
|
||||
<h3>2. Configuration</h3>
|
||||
<p>Set up your Carbone.io API key:</p>
|
||||
<ul style="margin-left: 40px; margin-top: 10px;">
|
||||
<li>Settings → Carbone.io Integration → API Keys</li>
|
||||
<li>Enter your API key (Get yours at your <a style="color : #5e17eb" href="https://account.carbone.io">Carbone Account</a>)</li>
|
||||
</ul>
|
||||
|
||||
<h3>3. Usage</h3>
|
||||
<p>To automate documents in Odoo:</p>
|
||||
<ul style="margin-left: 40px; margin-top: 10px;">
|
||||
<li>Upload your templates to your Carbone account</li>
|
||||
<li>Create a new "report" in the dedicated menu</li>
|
||||
<li>Link them to Odoo models (invoices, quotes, etc.)</li>
|
||||
<li>Generate your documents in one click!</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Spécifications Techniques -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Technical Specifications</h2>
|
||||
<!-- <img src="./assets/logo/icon-technical-specs.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>-->
|
||||
</div>
|
||||
<div class="tech-specs" style="background-color: #ffffff; padding: 30px; border-radius: 20px; margin-top: 30px; border: 1px solid #e8e6df;">
|
||||
<table style="width: 100%; border-collapse: collapse;">
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">Version Odoo</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">18.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">Dépendances</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">base, web, base_setup, export_json</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">Catégorie</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">Productivity / Reporting / Automation / Nocode / Lowcode</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">Licence</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">LGPL-3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">API Carbone</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">Compatible v3, v4 and v5</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">Supported input formats</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">PDF, DOCX, XLSX, PPTX, ODG, IDML, ODT, ODS, ODP, XML, HTML, and Markdown.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; font-weight: 500; color: #001E2B; width: 240px;">Supported output formats</td>
|
||||
<td style="padding: 15px 0; border-bottom: 1px solid #e8e6df;font-size: 0.95em; color: #5a5a5a;">PDF, DOCX, ODT, BIB, DOC, DOC6, DOC95, DOCBOOK, DOCX7, FODT, HTML, LATEX, MEDIAWIKI, OOXML, OTT, PDB, PSW, RTF, SDW, SDW4, SDW3, STW, SXW, TEXT, TXT, UOT, VOR, VOR4, VOR3, XHTML, JPG, JPEG, PNG, EPUB, XLSX, ODS, CSV, DBF, DIF, FODS, OTS, PXL, SDC, SDC4, SDC3, SLK, STC, SXC, UOS, XLS, XLS5, XLS95, XLT, XLT5, XLT95, PPTX, ODP, BMP, EMF, EPS, FODP, GIF, MET, ODG, PBM, PCT, PGM, PPM, PWP, RAS, SDA, SDD, SDD3, SDD4, SXD, STI, SVG, SVM, SWF, SXI, TIFF, UOP, VOR5, OTP, POTM, POT, PPS, PPT, ETEXT, HTML10, TEXT10, ODD, OTG, STD, SXD3, SXD5, SXW, XPM, and IDML</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documentation -->
|
||||
<div class="section" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none;">
|
||||
<div class="text-item" style="margin-bottom: 40px; padding: 0; background: transparent; border-radius: 0; box-shadow: none; position: relative;">
|
||||
<h2 class="text-bottom" style="color: #001E2B; font-size: 2.2em; margin-bottom: 30px; border-bottom: 1px solid #001E2B; padding-bottom: 15px; font-weight: 700; letter-spacing: -0.01em; position: relative; z-index: 1;">Documentation & Ressource</h2>
|
||||
<img src="./assets/logo/icon-documentation.png" style="position: absolute;height: 100%;top: 0;right: -5px;"/>
|
||||
</div>
|
||||
<ul class="doc-ressource-list" style=" list-style:'— '; padding: 0;margin-left: 40px; margin-right: 20px; line-height: 2; color: #5e17eb;
|
||||
font-weight: 400; margin-top: 2px;">
|
||||
<li><a style="color : #5e17eb" href="https://carbone.io/examples/">Templates Examples</a></li>
|
||||
<li><a style="color : #5e17eb" href="https://carbone.io/documentation/design/overview/getting-started.html">Getting started</a></li>
|
||||
<li><a style="color : #5e17eb" href="https://carbone.io/documentation/design/overview/philosophy.html">Philosophy</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- CTA -->
|
||||
<div class="cta-section" style="background-color: #2C003B; color: #f5f3ed; padding: 70px 60px; border-radius: 30px; text-align: center; margin-top: 80px;">
|
||||
<h2 style="color: white; border: none; font-size: 2.2em; margin-bottom: 15px;">
|
||||
Ready to Upgrade Your Odoo Reports?
|
||||
</h2>
|
||||
<p style="font-size: 1.2em; margin-bottom: 10px;">
|
||||
Download the module for free and start generating professional documents in minutes!
|
||||
</p>
|
||||
<a href="#" class="cta-button" style="display: inline-block; background: transparent; color: #f5f3ed; border: 2px solid #f5f3ed; padding: 16px 45px; border-radius: 2px; text-decoration: none; font-weight: 400; font-size: 1em; margin-top: 25px; transition: all 0.3s ease; letter-spacing: 0.05em; text-transform: uppercase;">Download</a>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="footer" style="text-align: center; padding: 40px 20px; color: #666;">
|
||||
<p style="margin-top: 10px;">Questions? Contact us at <a style="color:#5e17eb" href="mailto:contact+odoo@carbone.io">Carbone</a></p>.
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,28 @@
|
||||
/** @odoo-module */
|
||||
import {ListController} from "@web/views/list/list_controller";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {listView} from "@web/views/list/list_view";
|
||||
import {_t} from "@web/core/l10n/translation";
|
||||
export class CarboneIrActionsReportController extends ListController {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
OnClickCreateReport() {
|
||||
this.actionService.doAction({
|
||||
type: "ir.actions.act_window",
|
||||
res_model: "carbone.create.report.wizard",
|
||||
name: _t("Create new Carbone report"),
|
||||
view_mode: "form",
|
||||
view_type: "form",
|
||||
views: [[false, "form"]],
|
||||
target: "new",
|
||||
res_id: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
CarboneIrActionsReportController.template = "carbone_report_button_on_tree_view.ListView.Buttons";
|
||||
export const CustomCarboneIrActionsReportController = {
|
||||
...listView,
|
||||
Controller: CarboneIrActionsReportController,
|
||||
};
|
||||
registry.category("views").add("carbone_report_button_in_tree", CustomCarboneIrActionsReportController);
|
||||
47
report_carbone/static/src/js/report/action_manager_report.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {download} from "@web/core/network/download";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {user} from "@web/core/user";
|
||||
|
||||
registry.category("ir.actions.report handlers").add("carbone_handler", async function (action, options, env) {
|
||||
if (action.report_type === "carbone") {
|
||||
const type = action.report_type;
|
||||
let url = `/report/${type}/${action.report_name}`;
|
||||
const actionContext = action.context || {};
|
||||
if (action.data && JSON.stringify(action.data) !== "{}") {
|
||||
// Build a query string with `action.data` (it's the place where reports
|
||||
// using a wizard to customize the output traditionally put their options)
|
||||
const action_options = encodeURIComponent(JSON.stringify(action.data));
|
||||
const context = encodeURIComponent(JSON.stringify(actionContext));
|
||||
url += `?options=${action_options}&context=${context}`;
|
||||
} else {
|
||||
if (actionContext.active_ids) {
|
||||
url += `/${actionContext.active_ids.join(",")}`;
|
||||
}
|
||||
const context = encodeURIComponent(JSON.stringify(user.context));
|
||||
url += `?context=${context}`;
|
||||
}
|
||||
env.services.ui.block();
|
||||
try {
|
||||
const context = actionContext || user.context;
|
||||
await download({
|
||||
url: "/report/download",
|
||||
data: {
|
||||
data: JSON.stringify([url, action.report_type]),
|
||||
context: JSON.stringify(context),
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
env.services.ui.unblock();
|
||||
}
|
||||
const onClose = options.onClose;
|
||||
if (action.close_on_report_download) {
|
||||
return env.services.action.doAction({type: "ir.actions.act_window_close"}, {onClose});
|
||||
} else if (onClose) {
|
||||
onClose();
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
return Promise.resolve(false);
|
||||
});
|
||||
36
report_carbone/static/src/js/report/copy_export_json.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
function copyJsonAction(env, action, notifyUser = true) {
|
||||
const notification = env.services.notification;
|
||||
|
||||
const jsonData = action.context.json_data;
|
||||
|
||||
if (!jsonData && notifyUser) {
|
||||
notification.add("No JSON given in context", {type: "warning"});
|
||||
return {type: "ir.actions.act_window_close"};
|
||||
}
|
||||
|
||||
const formattedJson = formatJsonData(jsonData);
|
||||
|
||||
copyJsonToTarget(formattedJson, notification, notifyUser);
|
||||
|
||||
return {type: "ir.actions.act_window_close"};
|
||||
}
|
||||
|
||||
registry.category("actions").add("copy_options_to_carbone", copyJsonAction);
|
||||
|
||||
export function formatJsonData(jsonData) {
|
||||
if (typeof jsonData === "string") {
|
||||
try {
|
||||
const parsed = JSON.parse(jsonData);
|
||||
return JSON.stringify(parsed, null, 4);
|
||||
} catch (e) {
|
||||
return jsonData;
|
||||
}
|
||||
} else if (typeof jsonData === "object") {
|
||||
return JSON.stringify(jsonData, null, 4);
|
||||
}
|
||||
return String(jsonData || "");
|
||||
}
|
||||
485
report_carbone/static/src/js/report/initiate_studio.js
Normal file
@@ -0,0 +1,485 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {loadJS} from "@web/core/assets";
|
||||
import {rpc} from "@web/core/network/rpc";
|
||||
import {user} from "@web/core/user";
|
||||
import {formatJsonData} from "@report_carbone/js/report/copy_export_json";
|
||||
import {FormController} from "@web/views/form/form_controller";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
|
||||
// Bon, voici mon analyse complète et la correction. Le problème est clair :
|
||||
//
|
||||
// 1. openTemplateId → Tf.openTemplate({id}, true) sans retourner la promise
|
||||
// 2. openTemplate est async : fetch versions → getSample → restoreSampleDataFromTemplate → setState → render → updatePreview
|
||||
// 3. restoreSampleDataFromTemplate fait kf.setState({data: oldData, ...}) — écrase nos données
|
||||
// 4. kf.setState déclenche le re-render de tous les subscribers → updatePreview → AbortError si un preview était déjà en cours
|
||||
// 5. Aucun événement externe n'est émis quand openTemplate termine (options:updated n'est émis que par les interactions UI)
|
||||
//
|
||||
// Le listener options:updated ne se déclenche jamais dans ce cas. Il faut une autre stratégie :
|
||||
|
||||
// ========== CONSTANTS ==========
|
||||
// /!\ You must leave a minimum of 450ms, because when creating a new report, you must allow
|
||||
// Carbone time to deploy the new template, otherwise it cannot be displayed directly.
|
||||
// Between two recording changes, a minimum of 250 ms is required.
|
||||
const DEBOUNCE_DELAY = 450;
|
||||
const DEFAULT_OPTIONS = ["{}", "{}", "en", "UTC", "USD", "", ""];
|
||||
const CARBONE_STUDIO_SELECTOR = "carbone-studio";
|
||||
|
||||
// ========== DOM UTILITY==========
|
||||
const LOADER_CLASS = "carbone-studio-loader";
|
||||
|
||||
class DOMUtils {
|
||||
static setDisplayNone(element) {
|
||||
if (!element) return;
|
||||
Object.assign(element.style, {
|
||||
display: "none",
|
||||
width: "0%",
|
||||
height: "0%",
|
||||
});
|
||||
}
|
||||
|
||||
static showLoader(studio) {
|
||||
DOMUtils.removeLoader(studio);
|
||||
const parent = studio.parentElement;
|
||||
if (!parent) return null;
|
||||
if (!parent.style.position || parent.style.position === "static") {
|
||||
parent.style.position = "relative";
|
||||
}
|
||||
const overlay = document.createElement("div");
|
||||
overlay.className = LOADER_CLASS;
|
||||
Object.assign(overlay.style, {
|
||||
position: "absolute",
|
||||
inset: "0",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
background: "rgba(255, 255, 255, 0.75)",
|
||||
zIndex: "1000",
|
||||
});
|
||||
overlay.innerHTML = `
|
||||
<div style="text-align:center">
|
||||
<div class="o_loading_indicator">
|
||||
<img src="/web/static/img/spin.svg" alt="" style="width:48px;height:48px" />
|
||||
</div>
|
||||
<div style="margin-top:8px;font-size:14px;color:#666">
|
||||
Loading Odoo data...
|
||||
</div>
|
||||
</div>`;
|
||||
parent.appendChild(overlay);
|
||||
return overlay;
|
||||
}
|
||||
|
||||
static removeLoader(studio) {
|
||||
const parent = studio?.parentElement;
|
||||
if (!parent) return;
|
||||
parent.querySelectorAll(`.${LOADER_CLASS}`).forEach((el) => el.remove());
|
||||
}
|
||||
|
||||
static waitForElement(selector, callback) {
|
||||
const element = document.querySelector(selector);
|
||||
if (element) {
|
||||
callback(element);
|
||||
return null;
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
const found = document.querySelector(selector);
|
||||
if (found) {
|
||||
observer.disconnect();
|
||||
callback(found);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {childList: true, subtree: true});
|
||||
return observer;
|
||||
}
|
||||
|
||||
static improveOdooRecordView() {
|
||||
const node = document.querySelector("div.o_group.row.align-items-start");
|
||||
if (!node) return;
|
||||
|
||||
node.childNodes.forEach((childNode) => {
|
||||
if (childNode.nodeName === "DIV") {
|
||||
childNode.classList.add("col-lg-12");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ========== CARBONE HANDLER==========
|
||||
class CarboneStudioManager {
|
||||
constructor() {
|
||||
this.observer = null;
|
||||
this.studioURL = null;
|
||||
this.carboneToken = null;
|
||||
this.startIrReportId = null;
|
||||
this.isInitialized = false;
|
||||
this.debounceTimer = null;
|
||||
this.optionsList = [...DEFAULT_OPTIONS];
|
||||
this.currentStudio = null;
|
||||
this.isTemplateLoading = false;
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
if (!this.isInitialized) {
|
||||
this.studioURL = await CarboneAPI.importCarboneJs();
|
||||
this.carboneToken = await CarboneAPI.getCarboneApiKey();
|
||||
this.isInitialized = true;
|
||||
}
|
||||
return {
|
||||
studioURL: this.studioURL,
|
||||
carboneToken: this.carboneToken,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely close the current template, suppressing AbortError rejections
|
||||
* that the Carbone web component fires internally (from aborted fetch
|
||||
* calls in updatePreview) but does not handle itself.
|
||||
*/
|
||||
safeCloseTemplate() {
|
||||
if (!this.currentStudio) return;
|
||||
const suppressAbort = (event) => {
|
||||
if (event.reason?.name === "AbortError") {
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
window.addEventListener("unhandledrejection", suppressAbort);
|
||||
try {
|
||||
this.currentStudio.closeTemplate();
|
||||
} catch (e) {
|
||||
if (e.name !== "AbortError") {
|
||||
console.error("Error closing template:", e);
|
||||
}
|
||||
}
|
||||
// Keep the listener long enough for the async rejection to fire
|
||||
setTimeout(() => window.removeEventListener("unhandledrejection", suppressAbort), 500);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
this.observer = null;
|
||||
}
|
||||
|
||||
if (this.isTemplateLoading && this.currentStudio) {
|
||||
this.safeCloseTemplate();
|
||||
this.isTemplateLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
resetOptions() {
|
||||
this.optionsList = [...DEFAULT_OPTIONS];
|
||||
}
|
||||
|
||||
async refreshStudio(irReportId = null, services) {
|
||||
if (this.debounceTimer) {
|
||||
clearTimeout(this.debounceTimer);
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
this.debounceTimer = setTimeout(async () => {
|
||||
try {
|
||||
this.cleanup();
|
||||
this.resetOptions();
|
||||
|
||||
const config = await this.initialize();
|
||||
const isCarboneManager = await CarboneAPI.isCarboneManagerUser();
|
||||
const isCarboneReport = this.getIsCarboneReport(services);
|
||||
|
||||
if (!isCarboneReport || !isCarboneManager) {
|
||||
this.handleHideStudio(config);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
if (irReportId) {
|
||||
this.startIrReportId = irReportId;
|
||||
const options = await CarboneAPI.getDefaultOptionParameter(irReportId);
|
||||
if (options) {
|
||||
this.optionsList = options;
|
||||
}
|
||||
}
|
||||
|
||||
this.observer = DOMUtils.waitForElement(CARBONE_STUDIO_SELECTOR, (studio) => {
|
||||
this.setupStudio(studio, config);
|
||||
});
|
||||
|
||||
resolve();
|
||||
} catch (error) {
|
||||
console.error("Error refreshing Carbone Studio:", error);
|
||||
this.isTemplateLoading = false;
|
||||
resolve();
|
||||
}
|
||||
}, DEBOUNCE_DELAY);
|
||||
});
|
||||
}
|
||||
|
||||
setupStudio(studio, config) {
|
||||
if (this.currentStudio && this.isTemplateLoading) {
|
||||
this.safeCloseTemplate();
|
||||
}
|
||||
|
||||
this.currentStudio = studio;
|
||||
Object.assign(studio.style, {
|
||||
display: "",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
});
|
||||
DOMUtils.improveOdooRecordView();
|
||||
this.isTemplateLoading = true;
|
||||
this.launchCarbone(studio, config.studioURL, config.carboneToken);
|
||||
this.addStudioListeners(studio);
|
||||
}
|
||||
|
||||
handleHideStudio(config) {
|
||||
DOMUtils.waitForElement(CARBONE_STUDIO_SELECTOR, (studio) => {
|
||||
if (!config.studioURL || !config.carboneToken) {
|
||||
DOMUtils.setDisplayNone(studio);
|
||||
}
|
||||
});
|
||||
}
|
||||
getIsCarboneReport(services) {
|
||||
try {
|
||||
const actionService = services.action;
|
||||
if (!actionService?.currentController?.action) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const currentController = actionService.currentController;
|
||||
this.startIrReportId = currentController.currentState?.resId;
|
||||
return currentController.action.context?.default_report_type === "carbone";
|
||||
} catch (error) {
|
||||
console.error("Error getting current ir.actions.report:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async launchCarbone(studio, studioURL, carboneToken) {
|
||||
if (!studio || !studioURL || !carboneToken) {
|
||||
DOMUtils.setDisplayNone(studio);
|
||||
return false;
|
||||
}
|
||||
|
||||
studio.setConfig({origin: studioURL, token: carboneToken, mode: "embedded-versioning"});
|
||||
|
||||
const options = this.buildStudioOptions();
|
||||
const template = this.buildTemplateConfig();
|
||||
|
||||
await this.safeOpenTemplate(studio, template, options);
|
||||
this.isTemplateLoading = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
buildStudioOptions() {
|
||||
if (!this.optionsList || this.optionsList.length < 5) {
|
||||
this.optionsList = [...DEFAULT_OPTIONS];
|
||||
}
|
||||
|
||||
return {
|
||||
data: JSON.parse(this.optionsList[0]),
|
||||
translations: JSON.parse(this.optionsList[1]),
|
||||
lang: this.optionsList[2],
|
||||
timezone: this.optionsList[3],
|
||||
currencySource: this.optionsList[4],
|
||||
currencyTarget: this.optionsList[4],
|
||||
};
|
||||
}
|
||||
|
||||
buildTemplateConfig() {
|
||||
const template = {templateId: this.optionsList[5]};
|
||||
const extensionName = this.optionsList[6];
|
||||
|
||||
if (extensionName !== false) {
|
||||
template.extension = extensionName;
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
safeOpenTemplate(studio, template, options) {
|
||||
// openTemplateId() internally calls Tf.openTemplate() which is async,
|
||||
// but openTemplateId does NOT return the promise (fire-and-forget).
|
||||
// openTemplate fetches the saved "sample" from the Carbone backend
|
||||
// and calls restoreSampleDataFromTemplate(), which overwrites
|
||||
// kf.state.data with OLD saved data via kf.setState().
|
||||
//
|
||||
// No external event is emitted when openTemplate finishes
|
||||
// (options:updated is only emitted by UI interactions).
|
||||
//
|
||||
// Strategy: suppress the AbortError caused by the competing
|
||||
// updatePreview calls, show a loader, then re-apply our Odoo data
|
||||
// after a delay long enough for openTemplate to finish loading.
|
||||
const suppressAbort = (event) => {
|
||||
if (event.reason?.name === "AbortError") {
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
window.addEventListener("unhandledrejection", suppressAbort);
|
||||
DOMUtils.showLoader(studio);
|
||||
|
||||
try {
|
||||
studio.openTemplateId(template["templateId"]);
|
||||
} catch (e) {
|
||||
console.error("Error opening template:", e);
|
||||
DOMUtils.removeLoader(studio);
|
||||
window.removeEventListener("unhandledrejection", suppressAbort);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Wait for openTemplate's async work (getVersions + getSample +
|
||||
// restoreSampleDataFromTemplate + setState/render) to complete,
|
||||
// then overwrite with the correct Odoo record data.
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
studio.setRenderOptions(options);
|
||||
DOMUtils.removeLoader(studio);
|
||||
setTimeout(() => window.removeEventListener("unhandledrejection", suppressAbort), 2000);
|
||||
resolve();
|
||||
}, 2050);
|
||||
});
|
||||
}
|
||||
|
||||
addStudioListeners(studio) {
|
||||
const events = {
|
||||
connected: "studio connected.",
|
||||
disconnected: "studio disconnected.",
|
||||
"options:updated": null,
|
||||
};
|
||||
|
||||
Object.entries(events).forEach(([event, message]) => {
|
||||
studio.addEventListener(event, (e) => {
|
||||
if (message) {
|
||||
console.log(message, e);
|
||||
} else {
|
||||
console.log(e.detail);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ========== API CARBONE ==========
|
||||
class CarboneAPI {
|
||||
static async isCarboneManagerUser() {
|
||||
if (!user) return false;
|
||||
return await user.hasGroup("report_carbone.group_report_carbone_manager");
|
||||
}
|
||||
|
||||
static async importCarboneJs() {
|
||||
try {
|
||||
const res = await rpc("/carbone_config/carbone_studio_params");
|
||||
await loadJS(res.js_url);
|
||||
return res.studio_url;
|
||||
} catch (e) {
|
||||
console.error(`Failed to launch Carbone Studio: ${e.message}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static async getCarboneApiKey() {
|
||||
try {
|
||||
const res = await rpc("/carbone_config/carbone_api_key", {});
|
||||
return res.token;
|
||||
} catch (e) {
|
||||
console.error("Failed to retrieve API key:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static async getDefaultOptionParameter(irReportId) {
|
||||
try {
|
||||
const res = await rpc("/web/dataset/call_kw", {
|
||||
model: "ir.actions.report",
|
||||
method: "action_setup_carbone_studio_options",
|
||||
args: [[irReportId]],
|
||||
kwargs: {},
|
||||
});
|
||||
|
||||
return [
|
||||
formatJsonData(res.context.json_data),
|
||||
formatJsonData(res.context.json_translate_data),
|
||||
res.context.lang,
|
||||
res.context.timezone,
|
||||
res.context.currency,
|
||||
res.context.template,
|
||||
res.context.extension,
|
||||
];
|
||||
} catch (e) {
|
||||
console.error("Failed to retrieve options from backend:", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== PATCH FORM CONTROLLER ==========
|
||||
patch(FormController.prototype, {
|
||||
// Allows you to systematically refresh the studio, either by scrolling through records using the arrows or
|
||||
// by switching back and forth between the list view.
|
||||
onWillLoadRoot(nextConfiguration) {
|
||||
super.onWillLoadRoot(...arguments);
|
||||
// Skip refresh during save — onRecordSaved will handle it after save completes
|
||||
if (!this._carboneIsSaving) {
|
||||
this.handleCarboneStudio(nextConfiguration.resId);
|
||||
}
|
||||
},
|
||||
|
||||
async onPagerUpdate(params) {
|
||||
await super.onPagerUpdate(...arguments);
|
||||
this.handleCarboneStudio(this.model.root.resId);
|
||||
},
|
||||
|
||||
async save(params) {
|
||||
this._carboneIsSaving = true;
|
||||
const result = await super.save(...arguments);
|
||||
this._carboneIsSaving = false;
|
||||
return result;
|
||||
},
|
||||
|
||||
async onRecordSaved(record, changes) {
|
||||
await super.onRecordSaved(...arguments);
|
||||
this.handleCarboneStudio(this.model.root.resId);
|
||||
},
|
||||
|
||||
handleCarboneStudio(resId) {
|
||||
const dynamicService = this.env.services.dynamic_element_service;
|
||||
const isCarbone = this.props.context.default_report_type === "carbone";
|
||||
|
||||
if (!isCarbone) {
|
||||
this.waitForStudioThenRemove();
|
||||
return;
|
||||
}
|
||||
|
||||
dynamicService?.refreshCarboneStudio(resId);
|
||||
},
|
||||
|
||||
waitForStudioThenRemove() {
|
||||
DOMUtils.waitForElement(CARBONE_STUDIO_SELECTOR, (studio) => {
|
||||
DOMUtils.setDisplayNone(studio);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// ========== SERVICE DYNAMIC ELEMENT ==========
|
||||
export const dynamicElementService = {
|
||||
dependencies: ["action"],
|
||||
start(env, services) {
|
||||
const manager = new CarboneStudioManager();
|
||||
|
||||
async function refreshCarboneStudio(irReportId = null) {
|
||||
return await manager.refreshStudio(irReportId, services);
|
||||
}
|
||||
|
||||
async function actionRefreshCarboneStudio() {
|
||||
await refreshCarboneStudio(manager.startIrReportId);
|
||||
}
|
||||
|
||||
registry.category("actions").add("action_refresh_carbone_studio", actionRefreshCarboneStudio);
|
||||
|
||||
return {refreshCarboneStudio};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("services").add("dynamic_element_service", dynamicElementService);
|
||||
47
report_carbone/static/src/scss/carbone.scss
Normal file
@@ -0,0 +1,47 @@
|
||||
carbone-studio {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.o_settings_carbone_container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.o_field_row {
|
||||
display: flex;
|
||||
white-space: normal;
|
||||
margin-bottom: 0.25rem;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.o_form_label_fixed {
|
||||
min-width: 200px;
|
||||
text-align: left;
|
||||
font-weight: 400 !important;
|
||||
flex: 1;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.o_field_aligned {
|
||||
flex: 1;
|
||||
padding-top: 0.125rem;
|
||||
}
|
||||
|
||||
.o_tooltip_icon {
|
||||
font-size: 0.8rem;
|
||||
margin-left: 0.5rem;
|
||||
flex-shrink: 0;
|
||||
opacity: 0.7;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.o_tooltip_icon:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
.carbone-link-website {
|
||||
text-align: left;
|
||||
}
|
||||
10
report_carbone/static/src/xml/list_template.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="carbone_report_button_on_tree_view.ListView.Buttons" t-inherit="web.ListView">
|
||||
<xpath expr="//Layout/t[@t-set-slot='control-panel-create-button']" position="inside">
|
||||
<button type="button" class="btn btn-primary" style="margin-right: 10px;" t-on-click="OnClickCreateReport">
|
||||
New document
|
||||
</button>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||