Template MyTemplate does not exist Odoo 15 - button

Can someone help?
I wan to add a custom button in POS Odoo 15 CE. I followed this article: https://www.cybrosys.com/blog/how-to-add-buttons-in-pos-using-owl, but It's seem that something has changed from verssion 14 to 15.
This is my js file in my_project/static/src/js directory:
odoo.define('numenapp_buyer_name.alias_button', function(require) {
'use strict';
const PosComponent = require('point_of_sale.PosComponent');
const ProductScreen = require('point_of_sale.ProductScreen');
const { useListener } = require('web.custom_hooks');
const Registries = require('point_of_sale.Registries');
class AliasButton extends PosComponent {
constructor() {
super(...arguments);
useListener('click', this.onClick);
}
is_available() {
const order = this.env.pos.get_order();
return order;
}
onClick() {
const cli = this.get_client();
alert(cli.name);
}
}
AliasButton.template = 'AliasButton';
ProductScreen.addControlButton({
component: AliasButton,
condition: function() {
return this.env.pos;
},
position: ['before', 'OrderlineCustomerNoteButton'],
});
Registries.Component.add(AliasButton);
return AliasButton;
});
This is my xml file in my_project/static/src/xml directory:
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="AliasButton" owl="1">
<div class='control-button'>
Alias
</div>
</t>
</templates>
And this is my manifest.py file (a piece):
'data': [
# 'security/ir.model.access.csv',
'views/views.xml',
'views/templates.xml',
],
'demo': [
'demo/demo.xml',
],
'qweb': [
'static/src/xml/AliasButton.xml',
],
'assets': {
'point_of_sale.assets': [
'numenapp_buyer_name/static/src/js/**/*',
],
},

The is no qweb entry anymore.
From bundles documentation:
The bundles are defined in each module’s __manifest__.py, with a dedicated assets key that contains a dictionary web.assets_qweb: all static XML templates used in the backend environment and in the point of sale.
Link all qweb .xml in web.assets_qweb bundle like following:
'assets': {
'web.assets_qweb': [
'my_project/static/src/xml/AliasButton.xml',
],
},

Related

How to configure cypress-sql-server with no cypress.json? (updated)

I'm trying to setup cypress-sql-server, but I'm using version 10.8.0, which does not use cypress.json to configure the environment. All of the setup instructions I've found refer to using cypress.json to configure the plug-in. With the help of u/Fody, I'm closer, but I'm still running into an error:
tasksqlServer:execute, SELECT 'Bob'
CypressError
cy.task('sqlServer:execute') failed with the following error:
The 'task' event has not been registered in the setupNodeEvents method. You must register it before using cy.task()
Fix this in your setupNodeEvents method here:
D:\git\mcare.automation\client\cypress\cypress.config.jsLearn more
node_modules/cypress-sql-server/src/commands/db.js:7:1
5 | }
6 |
> 7 | cy.task('sqlServer:execute', query).then(response => {
| ^
8 | let result = [];
9 |
cypress.config.js
const { defineConfig } = require("cypress");
const sqlServer = require("cypress-sql-server");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// allows db data to be accessed in tests
config.db = {
"userName": "user",
"password": "pass",
"server": "myserver",
"options": {
"database": "mydb",
"encrypt": true,
"rowCollectionOnRequestCompletion": true
}
}
// code from /plugins/index.js
const tasks = sqlServer.loadDBPlugin(config.db);
on('task', tasks);
return config
// implement node event listeners here
},
},
});
testSQL.spec.js
describe('Testing SQL queries', () => {
it("It should return Bob", () => {
cy.sqlServer("SELECT 'Bob'").should('eq', 'Bob');
});
})
My versions:
\cypress> npx cypress --version
Cypress package version: 10.8.0
Cypress binary version: 10.8.0
Electron version: 19.0.8
Bundled Node version:
16.14.2
Suggestions? Is there any more info I can provide to help?
This is the install instruction currently given by cypress-sql-server for Cypress v9
Plugin file
The plug-in can be initialised in your cypress/plugins/index.js file as below.
const sqlServer = require('cypress-sql-server');
module.exports = (on, config) => {
tasks = sqlServer.loadDBPlugin(config.db);
on('task', tasks);
}
Translating that into Cypress v10+
const { defineConfig } = require('cypress')
const sqlServer = require('cypress-sql-server');
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// allows db data to be accessed in tests
config.db = {
"userName": "user",
"password": "pass",
"server": "myserver",
"options": {
"database": "mydb",
"encrypt": true,
"rowCollectionOnRequestCompletion": true
}
}
// code from /plugins/index.js
const tasks = sqlServer.loadDBPlugin(config.db);
on('task', tasks);
return config
},
},
})
Other variations work, such as putting the "db": {...} section below the "e2e: {...}" section, but not in the "env": {...} section.
Custom commands
Instructions for Cypress v9
Commands file
The extension provides multiple sets of commands. You can import the ones you need.
Example support/index.js file.
import sqlServer from 'cypress-sql-server';
sqlServer.loadDBCommands();
For Cypress v10+
Just move this code to support/e2e.js
cypress.json is a way to specify Cypress environment variables. Instead of using a cypress.json file, you can use any of the strategies in that link.
If you just wanted to include them in your cypress.config.js, it would look something like this:
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
baseUrl: 'http://localhost:1234',
env: {
db: {
// your db values here
}
}
}
})

How to set path for dynamic import in webpack 4

I have a NET Core application with the following webpack config optimization and output sections located in ClientApp folder which is placed in the root of the project
optimization: {
splitChunks: {
cacheGroups: {
translations: {
test: /[\\/]node_modules[\\/]webapps-translations/,
name(module, chunks, cacheGroupKey) {
const moduleFileName = module.identifier()
.split('\\').pop().toLowerCase().replace('.json', '');
return `${moduleFileName}`;
}
}
}
}
},
output: {
path: path.resolve(path.join('..', 'wwwroot', 'js')),
publicPath: path.join('..', 'js'),
filename: `[name]${jsMin}.js`
}
I have the following dynamic import statement
import(
/* webpackMode: "lazy" */
/* webpackPrefetch: true */
/* webpackPreload: true */
`webapps-translations/assets/${lang}.json`).then(m => {
let translations = m.default;
// TODO: use translations
});
Webpack generates the files in the desire location but the dynamic import request path is wrong. My page URL is http://localhost:5001/api/mypage but the generated import path is http://localhost:5001/api/jsde.js. The generated webpack URL should be http://localhost:5001/js/de.js
How can I configure the right path for dynamic import?

Configure eslint to read common types in src/types/types.d.ts vue3

My eslint .eslintrc.js, now properly in the src folder, is the following:
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true
},
extends: [
'plugin:vue/vue3-recommended',
'standard',
'prettier'
],
parserOptions: {
ecmaVersion: 2020,
parser: '#typescript-eslint/parser',
'ecmaFeatures': {
'jsx': true
}
},
plugins: [
'vue',
'#typescript-eslint'
],
rules: {
'import/no-unresolved': 'error'
},
settings: {
'import/parsers': {
'#typescript-eslint/parser': ['.ts', '.tsx']
},
'import/resolver': {
'typescript': {
'alwaysTryTypes': true,
}
}
}
}
I'm attempting to use eslint-import-resolver-typescript, but the documentation is a bit opaque.
I currently get errors on lines where a externally defined type is used (StepData in this example):
setup() {
const data = inject("StepData") as StepData;
return {
data,
};
},
The answer was the following. In types.d.ts (or other file if you want to have different collections of your custom types):
export interface MyType {
positioner: DOMRect;
content: DOMRect;
arrow: DOMRect;
window: DOMRect;
}
export interface SomeOtherType {
.. and so on
Then in the .vue files, import the types I need for the component:
import type { MyType, SomeOtherType } from "../types/types";
Before I was not using the export keyword and the types just worked without being imported. They have to be imported like this if you use export. It's kind of amazing how you are just expected to know this, the documentation for Typescript or Vue is sorely lacking in examples.

Apply different css files between 2 sub roots

I have an angular app, which consists of a website and system.
so I have made 2 sub roots under app root, websiteMaster, and systemMaster.
CSS files of the website don't have to be loaded when I'm logged in.
CSS files of the systems don't have to be loaded when I'm logged out.
so I need to load CSS files in websiteMaster only for website sub root components and to load CSS files in systemMaster only for system sub root components.
Is there a way to apply that using Angular 8?
Thanks in advance
You've to manually load/unload css files in a main/root(whatever you want to call it) component in one of your subroot module.
Let suppose websiteMaster module has following structure
Routes:
// Wrapping all routes in a parent component
const routes: Routes = [
{ path: '', component: WebsiteMasterRootComponent, children: [
{ path: 'any-path', component: AnyComponent },
{ path: 'any-other-path', component: AnyOtherComponent },
]
}];
WebsiteMasterRootComponent: which will load and unload css files related to this module
export class WebsiteMasterRootComponent implements OnInit, OnDestroy {
// css files required for current module
private styles = [
{ id: 'css-file-1', path: 'assets/css/css-file-1.css' },
{ id: 'css-file-2', path: 'assets/css/css-file-2.css' },
{ id: 'css-file-3', path: 'assets/css/css-file-3.css' },
];
constructor() {}
ngOnInit() {
this.styles.forEach(style => this.loadCss(style));
}
ngOnDestroy() {
// remove css files from DOM when component is getting destroying
this.styles.forEach(style => {
let element = document.getElementById(style.id);
element.parentNode.removeChild(element);
});
}
// append css file to DOM dynamically when current module is loaded
private loadCss(style: any) {
let head = document.getElementsByTagName('head')[0];
let link = document.createElement('link');
link.id = style.id;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = style.path;
head.appendChild(link);
}}

How to choose between rtl css file generated by rtl css and ltr css

We're building a website for a customer and the customer demands both an english and an arabic version of the website.
We're using infernojs#7 with webpack#4 and we're bundling css using webpack as well.
We're applying https://github.com/nicolashemonic/rtl-css-transform-webpack-plugin so that we get two versions of our output css file : RTL version and LTR version, our filenames are hashed for caching obviously.
Here is the Problem : how to choose at runtime between the rtl css file and ltr css file when we don't know their name(because of the hash) ?
I'm thinking of using react-helmet in root component to do something like
<link rel="stylesheet" href={this.state.lang==='ar' ? 'bunldename.rtl.css' : 'bundlename.css'}/>
<!-- we'll actually get lang from route but that's not the point-->
My only problem is getting the bundlename, I thought of using DefinePlugin but I couldn't get bundlename even in webpack.config.js.
Here is my webpack config:
const HtmlWebpackPlugin = require('html-webpack-plugin'),
RtlCssPlugin = require('rtl-css-transform-webpack-plugin'),
ExtractCssChunks = require('extract-css-chunks-webpack-plugin'),
HtmlWebpackExcludeAssetsPlugin = require('html-webpack-exclude-assets-plugin'),
path = require('path');
const commonPlugins = [
new ExtractCssChunks({
'filename': 'css/[name].[contenthash].css'
}),
new RtlCssPlugin({
filename: 'css/[name].[hash].rtl.css'
}),
new HtmlWebpackPlugin({
'title': 'mytitle',
'template': 'index.html',
excludeAssets: /\.css/u
}),
new HtmlWebpackExcludeAssetsPlugin()
];
const productionPlugins = [
...
];
module.exports = (_env,argv) => ({
'entry': './src/index.jsx',
'output': {
'path': path.resolve('../public'),
'filename': 'js/main.[contenthash].js'
},
'plugins': argv.mode === 'development' ? commonPlugins : [...commonPlugins,...productionPlugins],
'module': {
'rules': [
{
'test': /\.(js|jsx)$/u,
'use':
{
'loader': 'babel-loader',
'options': {
'presets': ['#babel/preset-env'],
'plugins': [['babel-plugin-inferno', { 'imports': true }]]
}
}
},
{
'test': /\.css$/u,
'use': [ExtractCssChunks.loader, 'css-loader']
}
]
},
'devServer': {
'host': '0.0.0.0',
'historyApiFallback': true,
'contentBase': './public',
'publicPath': 'http://localhost:8080/'
},
'resolve': {
'alias': {
'inferno': (argv.mode === 'development')
? 'inferno/dist/index.dev.esm.js'
: 'inferno/dist/index.esm.js',
'react': 'inferno-compat',
'react-dom': 'inferno-compat'
}
}
});

Resources