mirror of https://github.com/OCA/social.git
commit
929ec8f264
|
@ -0,0 +1,13 @@
|
|||
# Do NOT update manually; changes here will be overwritten by Copier
|
||||
_commit: v1.1.3
|
||||
_src_path: https://github.com/OCA/oca-addons-repo-template.git
|
||||
dependency_installation_mode: OCA
|
||||
generate_requirements_txt: true
|
||||
include_wkhtmltopdf: false
|
||||
odoo_version: 13.0
|
||||
rebel_module_groups: []
|
||||
repo_description: Addons concerning Odoo's social features and messaging in general.
|
||||
repo_name: Social addons for Odoo
|
||||
repo_slug: social
|
||||
travis_apt_packages: []
|
||||
travis_apt_sources: []
|
|
@ -7,11 +7,11 @@ indent_style = space
|
|||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[.eslintrc,*.{json,yml,yaml,rst,md}]
|
||||
[*.{json,yml,yaml,rst,md}]
|
||||
indent_size = 2
|
||||
|
||||
# Do not configure editor for libs and autogenerated content
|
||||
[*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst]
|
||||
[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}]
|
||||
charset = unset
|
||||
end_of_line = unset
|
||||
indent_size = unset
|
||||
|
|
291
.eslintrc
291
.eslintrc
|
@ -1,291 +0,0 @@
|
|||
{
|
||||
"globals": {
|
||||
"$": false,
|
||||
"_": false,
|
||||
"fuzzy": false,
|
||||
"jQuery": false,
|
||||
"moment": false,
|
||||
"odoo": false,
|
||||
"openerp": false,
|
||||
"self": false
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"rules": {
|
||||
"no-alert": "warn",
|
||||
"no-array-constructor": "warn",
|
||||
"no-bitwise": "off",
|
||||
"no-caller": "warn",
|
||||
"no-case-declarations": "warn",
|
||||
"no-catch-shadow": "warn",
|
||||
"no-class-assign": "warn",
|
||||
"no-cond-assign": "warn",
|
||||
"no-confusing-arrow": "warn",
|
||||
"no-console": "off",
|
||||
"no-const-assign": "warn",
|
||||
"no-constant-condition": "warn",
|
||||
"no-continue": "off",
|
||||
"no-control-regex": "warn",
|
||||
"no-debugger": "warn",
|
||||
"no-delete-var": "warn",
|
||||
"no-div-regex": "warn",
|
||||
"no-dupe-args": "warn",
|
||||
"no-dupe-class-members": "warn",
|
||||
"no-dupe-keys": "warn",
|
||||
"no-duplicate-case": "warn",
|
||||
"no-duplicate-imports": "warn",
|
||||
"no-else-return": "warn",
|
||||
"no-empty": "warn",
|
||||
"no-empty-character-class": "warn",
|
||||
"no-empty-function": "warn",
|
||||
"no-empty-pattern": "warn",
|
||||
"no-eq-null": "warn",
|
||||
"no-eval": "warn",
|
||||
"no-ex-assign": "warn",
|
||||
"no-extend-native": "warn",
|
||||
"no-extra-bind": "warn",
|
||||
"no-extra-boolean-cast": "warn",
|
||||
"no-extra-label": "warn",
|
||||
"no-extra-parens": "warn",
|
||||
"no-extra-semi": "warn",
|
||||
"no-fallthrough": "warn",
|
||||
"no-floating-decimal": "warn",
|
||||
"no-func-assign": "warn",
|
||||
"no-implicit-coercion": ["warn", {
|
||||
"allow": ["~"]
|
||||
}],
|
||||
"no-implicit-globals": "warn",
|
||||
"no-implied-eval": "warn",
|
||||
"no-inline-comments": "warn",
|
||||
"no-inner-declarations": "warn",
|
||||
"no-invalid-regexp": "warn",
|
||||
"no-invalid-this": "off",
|
||||
"no-irregular-whitespace": "warn",
|
||||
"no-iterator": "warn",
|
||||
"no-label-var": "warn",
|
||||
"no-labels": "warn",
|
||||
"no-lone-blocks": "warn",
|
||||
"no-lonely-if": "warn",
|
||||
"no-loop-func": "off",
|
||||
"no-magic-numbers": "off",
|
||||
"no-mixed-operators": "warn",
|
||||
"no-mixed-requires": "warn",
|
||||
"no-mixed-spaces-and-tabs": "warn",
|
||||
"no-multi-spaces": "warn",
|
||||
"no-multi-str": "warn",
|
||||
"no-multiple-empty-lines": "warn",
|
||||
"no-native-reassign": "warn",
|
||||
"no-negated-condition": "warn",
|
||||
"no-negated-in-lhs": "warn",
|
||||
"no-nested-ternary": "off",
|
||||
"no-new": "warn",
|
||||
"no-new-func": "warn",
|
||||
"no-new-object": "warn",
|
||||
"no-new-require": "warn",
|
||||
"no-new-symbol": "warn",
|
||||
"no-new-wrappers": "warn",
|
||||
"no-obj-calls": "warn",
|
||||
"no-octal": "warn",
|
||||
"no-octal-escape": "warn",
|
||||
"no-param-reassign": "warn",
|
||||
"no-path-concat": "warn",
|
||||
"no-plusplus": "off",
|
||||
"no-process-env": "warn",
|
||||
"no-process-exit": "warn",
|
||||
"no-proto": "warn",
|
||||
"no-prototype-builtins": "warn",
|
||||
"no-redeclare": "warn",
|
||||
"no-regex-spaces": "warn",
|
||||
"no-restricted-globals": "warn",
|
||||
"no-restricted-imports": "warn",
|
||||
"no-restricted-modules": "warn",
|
||||
"no-restricted-syntax": "warn",
|
||||
"no-return-assign": "warn",
|
||||
"no-script-url": "warn",
|
||||
"no-self-assign": "warn",
|
||||
"no-self-compare": "warn",
|
||||
"no-sequences": "warn",
|
||||
"no-shadow": "warn",
|
||||
"no-shadow-restricted-names": "warn",
|
||||
"no-whitespace-before-property": "warn",
|
||||
"no-spaced-func": "warn",
|
||||
"no-sparse-arrays": "warn",
|
||||
"no-sync": "warn",
|
||||
"no-tabs": "warn",
|
||||
"no-ternary": "off",
|
||||
"no-trailing-spaces": "warn",
|
||||
"no-this-before-super": "warn",
|
||||
"no-throw-literal": "warn",
|
||||
"no-undef": "warn",
|
||||
"no-undef-init": "warn",
|
||||
"no-undefined": "off",
|
||||
"no-unexpected-multiline": "warn",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unmodified-loop-condition": "warn",
|
||||
"no-unneeded-ternary": "warn",
|
||||
"no-unreachable": "warn",
|
||||
"no-unsafe-finally": "warn",
|
||||
"no-unused-expressions": "warn",
|
||||
"no-unused-labels": "warn",
|
||||
"no-unused-vars": "warn",
|
||||
"no-use-before-define": "warn",
|
||||
"no-useless-call": "warn",
|
||||
"no-useless-computed-key": "warn",
|
||||
"no-useless-concat": "warn",
|
||||
"no-useless-constructor": "warn",
|
||||
"no-useless-escape": "warn",
|
||||
"no-useless-rename": "warn",
|
||||
"no-void": "warn",
|
||||
"no-var": "off",
|
||||
"no-warning-comments": "off",
|
||||
"no-with": "warn",
|
||||
"array-bracket-spacing": "off",
|
||||
"array-callback-return": "warn",
|
||||
"arrow-body-style": "warn",
|
||||
"arrow-parens": "warn",
|
||||
"arrow-spacing": "off",
|
||||
"accessor-pairs": "warn",
|
||||
"block-scoped-var": "off",
|
||||
"block-spacing": ["warn", "always"],
|
||||
"brace-style": "warn",
|
||||
"callback-return": "warn",
|
||||
"camelcase": "off",
|
||||
"capitalized-comments": ["warn", "always", {
|
||||
"ignoreConsecutiveComments": true,
|
||||
"ignoreInlineComments": true
|
||||
}],
|
||||
"comma-dangle": ["warn", "always-multiline"],
|
||||
"comma-spacing": ["warn", {
|
||||
"before": false,
|
||||
"after": true
|
||||
}],
|
||||
"comma-style": "warn",
|
||||
"complexity": [
|
||||
"warn",
|
||||
15
|
||||
],
|
||||
"computed-property-spacing": "off",
|
||||
"consistent-return": "off",
|
||||
"consistent-this": "off",
|
||||
"constructor-super": "warn",
|
||||
"curly": "warn",
|
||||
"default-case": "off",
|
||||
"dot-location": ["warn", "property"],
|
||||
"dot-notation": "warn",
|
||||
"eol-last": "warn",
|
||||
"eqeqeq": "warn",
|
||||
"func-names": "off",
|
||||
"func-style": "off",
|
||||
"generator-star-spacing": "off",
|
||||
"global-require": "warn",
|
||||
"guard-for-in": "off",
|
||||
"handle-callback-err": "warn",
|
||||
"id-blacklist": "warn",
|
||||
"id-length": "off",
|
||||
"id-match": "warn",
|
||||
"indent": "warn",
|
||||
"init-declarations": "warn",
|
||||
"jsx-quotes": "warn",
|
||||
"key-spacing": "off",
|
||||
"keyword-spacing": "warn",
|
||||
"linebreak-style": [
|
||||
"warn",
|
||||
"unix"
|
||||
],
|
||||
"lines-around-comment": "warn",
|
||||
"max-depth": "warn",
|
||||
"max-len": ["warn", {
|
||||
"code": 88,
|
||||
"ignorePattern": "odoo\\.define\\(",
|
||||
"tabWidth": 4
|
||||
}],
|
||||
"max-lines": "off",
|
||||
"max-nested-callbacks": "warn",
|
||||
"max-params": "off",
|
||||
"max-statements": "off",
|
||||
"max-statements-per-line": "warn",
|
||||
"multiline-ternary": "off",
|
||||
"new-cap": "off",
|
||||
"new-parens": "warn",
|
||||
"newline-after-var": "off",
|
||||
"newline-before-return": "off",
|
||||
"newline-per-chained-call": "off",
|
||||
"object-curly-newline": ["warn", { "consistent": true }],
|
||||
"object-curly-spacing": ["warn", "never"],
|
||||
"object-property-newline": ["warn", {
|
||||
"allowAllPropertiesOnSameLine": true
|
||||
}],
|
||||
"object-shorthand": "off",
|
||||
"one-var": "off",
|
||||
"one-var-declaration-per-line": "off",
|
||||
"operator-assignment": "warn",
|
||||
"operator-linebreak": "warn",
|
||||
"padded-blocks": "off",
|
||||
"prefer-arrow-callback": "off",
|
||||
"prefer-const": "warn",
|
||||
"prefer-reflect": "off",
|
||||
"prefer-rest-params": "off",
|
||||
"prefer-spread": "off",
|
||||
"prefer-template": "off",
|
||||
"quote-props": "off",
|
||||
"quotes": "off",
|
||||
"radix": "warn",
|
||||
"require-yield": "warn",
|
||||
"rest-spread-spacing": "off",
|
||||
"semi": [
|
||||
"warn",
|
||||
"always"
|
||||
],
|
||||
"semi-spacing": "warn",
|
||||
"sort-imports": "warn",
|
||||
"sort-vars": "off",
|
||||
"space-before-blocks": "warn",
|
||||
"space-before-function-paren": "warn",
|
||||
"space-in-parens": "off",
|
||||
"space-infix-ops": "off",
|
||||
"space-unary-ops": "off",
|
||||
"spaced-comment": ["warn", "always"],
|
||||
"strict": ["warn", "function"],
|
||||
"template-curly-spacing": "off",
|
||||
"unicode-bom": "warn",
|
||||
"use-isnan": "warn",
|
||||
"valid-jsdoc": ["warn", {
|
||||
"prefer": {
|
||||
"arg": "param",
|
||||
"argument": "param",
|
||||
"augments": "extends",
|
||||
"constructor": "class",
|
||||
"exception": "throws",
|
||||
"func": "function",
|
||||
"method": "function",
|
||||
"prop": "property",
|
||||
"return": "returns",
|
||||
"virtual": "abstract",
|
||||
"yield": "yields"
|
||||
},
|
||||
"preferType": {
|
||||
"array": "Array",
|
||||
"bool": "Boolean",
|
||||
"boolean": "Boolean",
|
||||
"number": "Number",
|
||||
"object": "Object",
|
||||
"str": "String",
|
||||
"string": "String"
|
||||
},
|
||||
"requireParamDescription": false,
|
||||
"requireReturn": false,
|
||||
"requireReturnDescription": false,
|
||||
"requireReturnType": false
|
||||
}],
|
||||
"valid-typeof": "warn",
|
||||
"vars-on-top": "off",
|
||||
"wrap-iife": "warn",
|
||||
"wrap-regex": "warn",
|
||||
"yield-star-spacing": "off",
|
||||
"yoda": "warn"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2017
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
env:
|
||||
browser: true
|
||||
|
||||
# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449
|
||||
parserOptions:
|
||||
ecmaVersion: 2017
|
||||
|
||||
# Globals available in Odoo that shouldn't produce errorings
|
||||
globals:
|
||||
_: readonly
|
||||
$: readonly
|
||||
fuzzy: readonly
|
||||
jQuery: readonly
|
||||
moment: readonly
|
||||
odoo: readonly
|
||||
openerp: readonly
|
||||
Promise: readonly
|
||||
|
||||
# Styling is handled by Prettier, so we only need to enable AST rules;
|
||||
# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890
|
||||
rules:
|
||||
accessor-pairs: warn
|
||||
array-callback-return: warn
|
||||
callback-return: warn
|
||||
capitalized-comments:
|
||||
- warn
|
||||
- always
|
||||
- ignoreConsecutiveComments: true
|
||||
ignoreInlineComments: true
|
||||
complexity:
|
||||
- warn
|
||||
- 15
|
||||
constructor-super: warn
|
||||
dot-notation: warn
|
||||
eqeqeq: warn
|
||||
global-require: warn
|
||||
handle-callback-err: warn
|
||||
id-blacklist: warn
|
||||
id-match: warn
|
||||
init-declarations: error
|
||||
max-depth: warn
|
||||
max-nested-callbacks: warn
|
||||
max-statements-per-line: warn
|
||||
no-alert: warn
|
||||
no-array-constructor: warn
|
||||
no-caller: warn
|
||||
no-case-declarations: warn
|
||||
no-class-assign: warn
|
||||
no-cond-assign: error
|
||||
no-const-assign: error
|
||||
no-constant-condition: warn
|
||||
no-control-regex: warn
|
||||
no-debugger: error
|
||||
no-delete-var: warn
|
||||
no-div-regex: warn
|
||||
no-dupe-args: error
|
||||
no-dupe-class-members: error
|
||||
no-dupe-keys: error
|
||||
no-duplicate-case: error
|
||||
no-duplicate-imports: error
|
||||
no-else-return: warn
|
||||
no-empty-character-class: warn
|
||||
no-empty-function: error
|
||||
no-empty-pattern: error
|
||||
no-empty: warn
|
||||
no-eq-null: error
|
||||
no-eval: error
|
||||
no-ex-assign: error
|
||||
no-extend-native: warn
|
||||
no-extra-bind: warn
|
||||
no-extra-boolean-cast: warn
|
||||
no-extra-label: warn
|
||||
no-fallthrough: warn
|
||||
no-func-assign: error
|
||||
no-global-assign: error
|
||||
no-implicit-coercion:
|
||||
- warn
|
||||
- allow: ["~"]
|
||||
no-implicit-globals: warn
|
||||
no-implied-eval: warn
|
||||
no-inline-comments: warn
|
||||
no-inner-declarations: warn
|
||||
no-invalid-regexp: warn
|
||||
no-irregular-whitespace: warn
|
||||
no-iterator: warn
|
||||
no-label-var: warn
|
||||
no-labels: warn
|
||||
no-lone-blocks: warn
|
||||
no-lonely-if: error
|
||||
no-mixed-requires: error
|
||||
no-multi-str: warn
|
||||
no-native-reassign: error
|
||||
no-negated-condition: warn
|
||||
no-negated-in-lhs: error
|
||||
no-new-func: warn
|
||||
no-new-object: warn
|
||||
no-new-require: warn
|
||||
no-new-symbol: warn
|
||||
no-new-wrappers: warn
|
||||
no-new: warn
|
||||
no-obj-calls: warn
|
||||
no-octal-escape: warn
|
||||
no-octal: warn
|
||||
no-param-reassign: warn
|
||||
no-path-concat: warn
|
||||
no-process-env: warn
|
||||
no-process-exit: warn
|
||||
no-proto: warn
|
||||
no-prototype-builtins: warn
|
||||
no-redeclare: warn
|
||||
no-regex-spaces: warn
|
||||
no-restricted-globals: warn
|
||||
no-restricted-imports: warn
|
||||
no-restricted-modules: warn
|
||||
no-restricted-syntax: warn
|
||||
no-return-assign: error
|
||||
no-script-url: warn
|
||||
no-self-assign: warn
|
||||
no-self-compare: warn
|
||||
no-sequences: warn
|
||||
no-shadow-restricted-names: warn
|
||||
no-shadow: warn
|
||||
no-sparse-arrays: warn
|
||||
no-sync: warn
|
||||
no-this-before-super: warn
|
||||
no-throw-literal: warn
|
||||
no-undef-init: warn
|
||||
no-undef: error
|
||||
no-unmodified-loop-condition: warn
|
||||
no-unneeded-ternary: error
|
||||
no-unreachable: error
|
||||
no-unsafe-finally: error
|
||||
no-unused-expressions: error
|
||||
no-unused-labels: error
|
||||
no-unused-vars: error
|
||||
no-use-before-define: error
|
||||
no-useless-call: warn
|
||||
no-useless-computed-key: warn
|
||||
no-useless-concat: warn
|
||||
no-useless-constructor: warn
|
||||
no-useless-escape: warn
|
||||
no-useless-rename: warn
|
||||
no-void: warn
|
||||
no-with: warn
|
||||
operator-assignment: [error, always]
|
||||
prefer-const: warn
|
||||
radix: warn
|
||||
require-yield: warn
|
||||
sort-imports: warn
|
||||
spaced-comment: [error, always]
|
||||
strict: [error, function]
|
||||
use-isnan: error
|
||||
valid-jsdoc:
|
||||
- warn
|
||||
- prefer:
|
||||
arg: param
|
||||
argument: param
|
||||
augments: extends
|
||||
constructor: class
|
||||
exception: throws
|
||||
func: function
|
||||
method: function
|
||||
prop: property
|
||||
return: returns
|
||||
virtual: abstract
|
||||
yield: yields
|
||||
preferType:
|
||||
array: Array
|
||||
bool: Boolean
|
||||
boolean: Boolean
|
||||
number: Number
|
||||
object: Object
|
||||
str: String
|
||||
string: String
|
||||
requireParamDescription: false
|
||||
requireReturn: false
|
||||
requireReturnDescription: false
|
||||
requireReturnType: false
|
||||
valid-typeof: warn
|
||||
yoda: warn
|
|
@ -0,0 +1,13 @@
|
|||
name: pre-commit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: pre-commit/action@v2.0.0
|
|
@ -1,6 +1,8 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
/.venv
|
||||
/.pytest_cache
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
@ -8,12 +10,11 @@ __pycache__/
|
|||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
bin/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
|
@ -22,12 +23,7 @@ var/
|
|||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
*.eggs
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
@ -37,11 +33,9 @@ pip-delete-this-directory.txt
|
|||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
@ -49,11 +43,33 @@ coverage.xml
|
|||
# Pycharm
|
||||
.idea
|
||||
|
||||
# Eclipse
|
||||
.settings
|
||||
|
||||
# Visual Studio cache/options directory
|
||||
.vs/
|
||||
.vscode
|
||||
|
||||
# OSX Files
|
||||
.DS_Store
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Rope
|
||||
.ropeproject
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
# Backup files
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# OCA rules
|
||||
!static/lib/
|
||||
|
|
|
@ -9,4 +9,4 @@ line_length=88
|
|||
known_odoo=odoo
|
||||
known_odoo_addons=odoo.addons
|
||||
sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
|
||||
known_third_party=lxml,mock,psycopg2,requests,setuptools,werkzeug
|
||||
default_section=THIRDPARTY
|
||||
|
|
|
@ -1,69 +1,128 @@
|
|||
exclude: "^setup/|/static/lib/|/static/src/lib/"
|
||||
exclude: |
|
||||
(?x)
|
||||
# NOT INSTALLABLE ADDONS
|
||||
# END NOT INSTALLABLE ADDONS
|
||||
# Files and folders generated by bots, to avoid loops
|
||||
^setup/|/static/description/index\.html$|
|
||||
# We don't want to mess with tool-generated files
|
||||
.svg$|
|
||||
# Maybe reactivate this when all README files include prettier ignore tags?
|
||||
^README\.md$|
|
||||
# Library files can have extraneous formatting (even minimized)
|
||||
/static/(src/)?lib/|
|
||||
# Repos using Sphinx to generate docs don't need prettying
|
||||
^docs/_templates/.*\.html$|
|
||||
# You don't usually want a bot to modify your legal texts
|
||||
(LICENSE.*|COPYING.*)
|
||||
default_language_version:
|
||||
python: python3
|
||||
node: "14.13.0"
|
||||
repos:
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 19.3b0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
# exclude autogenerated files
|
||||
exclude: /README\.rst$|\.pot?$
|
||||
- id: end-of-file-fixer
|
||||
# exclude autogenerated files
|
||||
exclude: /README\.rst$|\.pot?$
|
||||
- id: debug-statements
|
||||
- id: flake8
|
||||
name: flake8 except __init__.py
|
||||
exclude: /__init__\.py$
|
||||
additional_dependencies: ["flake8-bugbear==19.8.0"]
|
||||
- id: flake8
|
||||
name: flake8 only __init__.py
|
||||
args: ["--extend-ignore=F401"] # ignore unused imports in __init__.py
|
||||
files: /__init__\.py$
|
||||
additional_dependencies: ["flake8-bugbear==19.8.0"]
|
||||
- id: fix-encoding-pragma
|
||||
args: ["--remove"]
|
||||
- id: check-case-conflict
|
||||
- id: check-docstring-first
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-merge-conflict
|
||||
- id: check-symlinks
|
||||
- id: check-xml
|
||||
- id: mixed-line-ending
|
||||
args: ["--fix=lf"]
|
||||
- repo: https://github.com/pre-commit/mirrors-pylint
|
||||
rev: v2.3.1
|
||||
hooks:
|
||||
- id: pylint
|
||||
name: pylint with optional checks
|
||||
args: ["--rcfile=.pylintrc", "--exit-zero"]
|
||||
verbose: true
|
||||
additional_dependencies: ["pylint-odoo==3.5.0"]
|
||||
- id: pylint
|
||||
name: pylint with mandatory checks
|
||||
args: ["--rcfile=.pylintrc-mandatory"]
|
||||
additional_dependencies: ["pylint-odoo==3.5.0"]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v1.24.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
- repo: https://github.com/asottile/seed-isort-config
|
||||
rev: v1.9.3
|
||||
hooks:
|
||||
- id: seed-isort-config
|
||||
- repo: https://github.com/pre-commit/mirrors-isort
|
||||
rev: v4.3.21
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort except __init__.py
|
||||
exclude: /__init__\.py$
|
||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||
rev: v6.5.1
|
||||
hooks:
|
||||
- id: eslint
|
||||
verbose: true
|
||||
- repo: local
|
||||
hooks:
|
||||
# These files are most likely copier diff rejection junks; if found,
|
||||
# review them manually, fix the problem (if needed) and remove them
|
||||
- id: forbidden-files
|
||||
name: forbidden files
|
||||
entry: found forbidden files; remove them
|
||||
language: fail
|
||||
files: "\\.rej$"
|
||||
- repo: https://github.com/oca/maintainer-tools
|
||||
rev: ab1d7f6
|
||||
hooks:
|
||||
# update the NOT INSTALLABLE ADDONS section above
|
||||
- id: oca-update-pre-commit-excluded-addons
|
||||
- id: oca-fix-manifest-website
|
||||
args: ["https://github.com/OCA/social"]
|
||||
- repo: https://github.com/myint/autoflake
|
||||
rev: v1.4
|
||||
hooks:
|
||||
- id: autoflake
|
||||
args: ["-i", "--ignore-init-module-imports"]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 19.10b0
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v1.19.1
|
||||
hooks:
|
||||
- id: prettier
|
||||
name: prettier (with plugin-xml)
|
||||
entry: prettier --write --list-different
|
||||
additional_dependencies:
|
||||
- "prettier@1.19.1"
|
||||
- "@prettier/plugin-xml@0.7.2"
|
||||
files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$
|
||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||
rev: v6.8.0
|
||||
hooks:
|
||||
- id: eslint
|
||||
verbose: true
|
||||
args:
|
||||
- --color
|
||||
- --fix
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.4.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
# exclude autogenerated files
|
||||
exclude: /README\.rst$|\.pot?$
|
||||
- id: end-of-file-fixer
|
||||
# exclude autogenerated files
|
||||
exclude: /README\.rst$|\.pot?$
|
||||
- id: debug-statements
|
||||
- id: fix-encoding-pragma
|
||||
args: ["--remove"]
|
||||
- id: check-case-conflict
|
||||
- id: check-docstring-first
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-merge-conflict
|
||||
# exclude files where underlines are not distinguishable from merge conflicts
|
||||
exclude: /README\.rst$|^docs/.*\.rst$
|
||||
- id: check-symlinks
|
||||
- id: check-xml
|
||||
- id: mixed-line-ending
|
||||
args: ["--fix=lf"]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v1.26.2
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: ["--keep-percent-format"]
|
||||
- repo: https://github.com/pre-commit/mirrors-isort
|
||||
rev: v4.3.21
|
||||
hooks:
|
||||
- id: isort
|
||||
name: isort except __init__.py
|
||||
exclude: /__init__\.py$
|
||||
- repo: https://github.com/acsone/setuptools-odoo
|
||||
rev: 2.5.2
|
||||
hooks:
|
||||
- id: setuptools-odoo-make-default
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.7.9
|
||||
hooks:
|
||||
- id: flake8
|
||||
name: flake8 except __init__.py
|
||||
exclude: /__init__\.py$
|
||||
additional_dependencies: ["flake8-bugbear==19.8.0"]
|
||||
- id: flake8
|
||||
name: flake8 only __init__.py
|
||||
args: ["--extend-ignore=F401"] # ignore unused imports in __init__.py
|
||||
files: /__init__\.py$
|
||||
additional_dependencies: ["flake8-bugbear==19.8.0"]
|
||||
- repo: https://github.com/pre-commit/mirrors-pylint
|
||||
rev: v2.5.3
|
||||
hooks:
|
||||
- id: pylint
|
||||
name: pylint with optional checks
|
||||
args:
|
||||
- --rcfile=.pylintrc
|
||||
- --exit-zero
|
||||
verbose: true
|
||||
additional_dependencies: &pylint_deps
|
||||
- pylint-odoo==3.5.0
|
||||
- id: pylint
|
||||
name: pylint with mandatory checks
|
||||
args:
|
||||
- --rcfile=.pylintrc-mandatory
|
||||
additional_dependencies: *pylint_deps
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# Defaults for all prettier-supported languages.
|
||||
# Prettier will complete this with settings from .editorconfig file.
|
||||
bracketSpacing: false
|
||||
printWidth: 88
|
||||
proseWrap: always
|
||||
semi: true
|
||||
trailingComma: "es5"
|
||||
xmlWhitespaceSensitivity: "strict"
|
|
@ -46,8 +46,6 @@ enable=anomalous-backslash-in-string,
|
|||
method-inverse,
|
||||
method-required-super,
|
||||
method-search,
|
||||
missing-import-error,
|
||||
missing-manifest-dependency,
|
||||
openerp-exception-warning,
|
||||
pointless-statement,
|
||||
pointless-string-statement,
|
||||
|
@ -73,6 +71,7 @@ enable=anomalous-backslash-in-string,
|
|||
deprecated-module,
|
||||
file-not-used,
|
||||
invalid-commit,
|
||||
missing-manifest-dependency,
|
||||
missing-newline-extrafiles,
|
||||
missing-readme,
|
||||
no-utf8-coding-comment,
|
||||
|
@ -82,6 +81,7 @@ enable=anomalous-backslash-in-string,
|
|||
too-complex,
|
||||
unnecessary-utf8-coding-comment
|
||||
|
||||
|
||||
[REPORTS]
|
||||
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
|
||||
output-format=colorized
|
||||
|
|
|
@ -39,8 +39,6 @@ enable=anomalous-backslash-in-string,
|
|||
method-inverse,
|
||||
method-required-super,
|
||||
method-search,
|
||||
missing-import-error,
|
||||
missing-manifest-dependency,
|
||||
openerp-exception-warning,
|
||||
pointless-statement,
|
||||
pointless-string-statement,
|
||||
|
|
23
.travis.yml
23
.travis.yml
|
@ -1,8 +1,8 @@
|
|||
language: python
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/.cache/pre-commit
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/.cache/pre-commit
|
||||
|
||||
python:
|
||||
- "3.6"
|
||||
|
@ -11,33 +11,26 @@ addons:
|
|||
postgresql: "9.6"
|
||||
apt:
|
||||
packages:
|
||||
- expect-dev # provides unbuffer utility
|
||||
- expect-dev # provides unbuffer utility
|
||||
|
||||
stages:
|
||||
- linting
|
||||
- test
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: linting
|
||||
name: "pre-commit"
|
||||
before_install:
|
||||
install: pip install pre-commit
|
||||
script: pre-commit run --all --show-diff-on-failure --verbose --color always
|
||||
after_success:
|
||||
- stage: test
|
||||
env:
|
||||
- TESTS="1" ODOO_REPO="odoo/odoo" MAKEPOT="1"
|
||||
- TESTS=1 ODOO_REPO="odoo/odoo" MAKEPOT="1"
|
||||
- stage: test
|
||||
env:
|
||||
- TESTS="1" ODOO_REPO="OCA/OCB"
|
||||
|
||||
- TESTS=1 ODOO_REPO="OCA/OCB"
|
||||
env:
|
||||
global:
|
||||
- VERSION="13.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0"
|
||||
- VERSION="13.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0"
|
||||
|
||||
install:
|
||||
- git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools
|
||||
- git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git
|
||||
${HOME}/maintainer-quality-tools
|
||||
- export PATH=${HOME}/maintainer-quality-tools/travis:${PATH}
|
||||
- travis_install_nightly
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
# OCA Guidelines
|
||||
|
||||
Please follow the official guide from the
|
||||
[OCA Guidelines page](https://odoo-community.org/page/contributing).
|
||||
|
||||
## Project Specific Guidelines
|
||||
|
||||
<!-- /!\ do not modify above this line -->
|
||||
|
||||
This project does not have specific coding guidelines.
|
10
LICENSE
10
LICENSE
|
@ -1,7 +1,7 @@
|
|||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
|
@ -643,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
|
@ -658,4 +658,4 @@ specific requirements.
|
|||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
|
33
README.md
33
README.md
|
@ -1,11 +1,17 @@
|
|||
[](https://runbot.odoo-community.org/runbot/repo/github-com-oca-social-205)
|
||||
[](https://travis-ci.org/OCA/social)
|
||||
[](https://coveralls.io/r/OCA/social?branch=13.0)
|
||||
[](https://travis-ci.com/OCA/social)
|
||||
[](https://codecov.io/gh/OCA/social)
|
||||
[](https://translation.odoo-community.org/engage/social-13-0/?utm_source=widget)
|
||||
|
||||
Social addons for Odoo
|
||||
======================
|
||||
<!-- /!\ do not modify above this line -->
|
||||
|
||||
Addons concerning Odoo's social ERP features and messaging in general
|
||||
# Social addons for Odoo
|
||||
|
||||
Addons concerning Odoo's social features and messaging in general.
|
||||
|
||||
<!-- /!\ do not modify below this line -->
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
|
||||
[//]: # (addons)
|
||||
|
||||
|
@ -44,7 +50,18 @@ addon | version | summary
|
|||
|
||||
[//]: # (end addons)
|
||||
|
||||
Translation Status
|
||||
------------------
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
[](https://translation.odoo-community.org/engage/social-13-0/?utm_source=widget)
|
||||
## Licenses
|
||||
|
||||
This repository is licensed under [AGPL-3.0](LICENSE).
|
||||
|
||||
However, each module can have a totally different license, as long as they adhere to OCA
|
||||
policy. Consult each module's `__manifest__.py` file, which contains a `license` key
|
||||
that explains its license.
|
||||
|
||||
----
|
||||
|
||||
OCA, or the [Odoo Community Association](http://odoo-community.org/), is a nonprofit
|
||||
organization whose mission is to support the collaborative development of Odoo features
|
||||
and promote its widespread use.
|
||||
|
|
|
@ -1,34 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="subject_gin_idx" model="trgm.index">
|
||||
<field name="index_type">gin</field>
|
||||
<field name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','subject')]"/>
|
||||
<field
|
||||
name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','subject')]"
|
||||
/>
|
||||
</record>
|
||||
|
||||
<record id="body_gin_idx" model="trgm.index">
|
||||
<field name="index_type">gin</field>
|
||||
<field name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','body')]"/>
|
||||
<field
|
||||
name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','body')]"
|
||||
/>
|
||||
</record>
|
||||
|
||||
<record id="record_name_gin_idx" model="trgm.index">
|
||||
<field name="index_type">gin</field>
|
||||
<field name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','record_name')]"/>
|
||||
<field
|
||||
name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','record_name')]"
|
||||
/>
|
||||
</record>
|
||||
|
||||
<record id="email_from_gin_idx" model="trgm.index">
|
||||
<field name="index_type">gin</field>
|
||||
<field name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','email_from')]"/>
|
||||
<field
|
||||
name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','email_from')]"
|
||||
/>
|
||||
</record>
|
||||
|
||||
<record id="reply_to_gin_idx" model="trgm.index">
|
||||
<field name="index_type">gin</field>
|
||||
<field name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','reply_to')]"/>
|
||||
<field
|
||||
name="field_id"
|
||||
search="[('model','=','mail.message'),('name','=','reply_to')]"
|
||||
/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<template id="view_email_template_corporate_identity">
|
||||
<body>
|
||||
<html>
|
||||
<img style="float: right" t-attf-src="data:image;base64,{{env.user.company_id.logo}}" />
|
||||
<img
|
||||
style="float: right"
|
||||
t-attf-src="data:image;base64,{{env.user.company_id.logo}}"
|
||||
/>
|
||||
<!-- if some template calling us sets this variable,
|
||||
we print a h1 tag /-->
|
||||
<h1 t-if="email_heading"><t t-esc="email_heading" /></h1>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="email_template_demo1" model="mail.template">
|
||||
<field name="name">QWeb demo</field>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="email_template_form" model="ir.ui.view">
|
||||
<field name="model">mail.template</field>
|
||||
|
@ -9,12 +9,21 @@
|
|||
</field>
|
||||
<field name="body_html" position="before">
|
||||
<group attrs="{'invisible': [('body_type', '!=', 'qweb')]}">
|
||||
<field name="body_view_id" attrs="{'required': [('body_type', '=', 'qweb')]}" />
|
||||
<field name="body_view_arch" widget="ace" attrs="{'required': [('body_type', '=', 'qweb')], 'invisible': [('body_view_id', '=', False)]}" />
|
||||
<field
|
||||
name="body_view_id"
|
||||
attrs="{'required': [('body_type', '=', 'qweb')]}"
|
||||
/>
|
||||
<field
|
||||
name="body_view_arch"
|
||||
widget="ace"
|
||||
attrs="{'required': [('body_type', '=', 'qweb')], 'invisible': [('body_view_id', '=', False)]}"
|
||||
/>
|
||||
</group>
|
||||
</field>
|
||||
<field name="body_html" position="attributes">
|
||||
<attribute name="attrs">{'invisible': [('body_type', '!=', 'jinja2')]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible': [('body_type', '!=', 'jinja2')]}</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"summary": "Post unkonwn messages to an existing thread",
|
||||
"version": "13.0.1.0.0",
|
||||
"category": "Discuss",
|
||||
"website": "https://www.github.com/social",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"author": "Tecnativa, Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2017 Tecnativa - Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="demo_sink" model="mail.channel">
|
||||
<field name="name">mailsink</field>
|
||||
<field name="email_send" eval="True"/>
|
||||
<field name="email_send" eval="True" />
|
||||
<field name="description">Unbounded email sink</field>
|
||||
<field name="alias_contact">everyone</field>
|
||||
<field name="public">private</field>
|
||||
<field name="group_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||
<field name="group_ids" eval="[(4, ref('base.group_user'))]" />
|
||||
</record>
|
||||
|
||||
<record id="demo_server" model="fetchmail.server">
|
||||
<field name="name">Demo server</field>
|
||||
<field name="server_type">pop</field>
|
||||
<field name="server">pop3.example.com</field>
|
||||
<field name="default_thread_id" eval="'mail.channel,%d' % ref('demo_sink')"/>
|
||||
<field name="default_thread_id" eval="'mail.channel,%d' % ref('demo_sink')" />
|
||||
<!-- <field name="default_thread_id">mail.channel,%(demo_sink)d</field> -->
|
||||
</record>
|
||||
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2017 Tecnativa - Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_email_server_form" model="ir.ui.view">
|
||||
<field name="name">Add default thread</field>
|
||||
<field name="model">fetchmail.server</field>
|
||||
<field name="inherit_id" ref="fetchmail.view_email_server_form"/>
|
||||
<field name="inherit_id" ref="fetchmail.view_email_server_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='object_id']" position="after">
|
||||
<field name="default_thread_id"/>
|
||||
<field name="default_thread_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
/* Copyright 2018 David Juaneda
|
||||
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
|
||||
odoo.define('mail.Chatter.activity', function (require) {
|
||||
odoo.define("mail.Chatter.activity", function(require) {
|
||||
"use strict";
|
||||
|
||||
var chatter = require('mail.Chatter');
|
||||
var chatter = require("mail.Chatter");
|
||||
|
||||
chatter.include({
|
||||
|
||||
events: _.extend({}, chatter.prototype.events, {
|
||||
'click .o_chatter_button_list_activity': '_onListActivity',
|
||||
"click .o_chatter_button_list_activity": "_onListActivity",
|
||||
}),
|
||||
|
||||
/**
|
||||
|
@ -16,18 +15,17 @@ odoo.define('mail.Chatter.activity', function (require) {
|
|||
*
|
||||
* @private
|
||||
*/
|
||||
_onListActivity: function () {
|
||||
_onListActivity: function() {
|
||||
this._rpc({
|
||||
model: this.record.model,
|
||||
method: 'redirect_to_activities',
|
||||
method: "redirect_to_activities",
|
||||
args: [[]],
|
||||
kwargs: {
|
||||
'id':this.record.res_id,
|
||||
'model':this.record.model,
|
||||
id: this.record.res_id,
|
||||
model: this.record.model,
|
||||
},
|
||||
context: this.record.getContext(),
|
||||
}).then($.proxy(this, "do_action"));
|
||||
},
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t t-extend="mail.chatter.Buttons">
|
||||
<t t-jquery="button.o_chatter_button_schedule_activity" t-operation="after">
|
||||
<button t-if="scheduleActivityButton" class="btn btn-link o_chatter_button_list_activity"
|
||||
title="See activities list" type="button" disabled="disabled">
|
||||
<i class="fa fa-list"/> Activities
|
||||
<button
|
||||
t-if="scheduleActivityButton"
|
||||
class="btn btn-link o_chatter_button_list_activity"
|
||||
title="See activities list"
|
||||
type="button"
|
||||
disabled="disabled"
|
||||
>
|
||||
<i class="fa fa-list" /> Activities
|
||||
</button>
|
||||
</t>
|
||||
</t>
|
||||
|
|
|
@ -12,38 +12,57 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Activity Form" create="false" edit="false" delete="false">
|
||||
<sheet string="Activity">
|
||||
<button name="open_origin" type="object" class="centre oe_link" nolabel="1">
|
||||
<h1><field name="res_name"/></h1>
|
||||
<button
|
||||
name="open_origin"
|
||||
type="object"
|
||||
class="centre oe_link"
|
||||
nolabel="1"
|
||||
>
|
||||
<h1><field name="res_name" /></h1>
|
||||
</button>
|
||||
<field name="activity_category" invisible="1" />
|
||||
<field name="res_model" invisible="1"/>
|
||||
<field name="res_model_id" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<field name="res_model" invisible="1" />
|
||||
<field name="res_model_id" invisible="1" />
|
||||
<field name="res_id" invisible="1" />
|
||||
<group>
|
||||
<group>
|
||||
<field name="activity_type_id" required="1" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="res_model_id_name"/>
|
||||
<field name="calendar_event_id" invisible="1"/>
|
||||
<field name="create_date" invisible="1"/>
|
||||
<field
|
||||
name="activity_type_id"
|
||||
required="1"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
/>
|
||||
<field name="res_model_id_name" />
|
||||
<field name="calendar_event_id" invisible="1" />
|
||||
<field name="create_date" invisible="1" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="date_deadline"
|
||||
attrs="{'invisible': [('activity_category', '=', 'meeting')]}"/>
|
||||
<field name="calendar_event_id_start" string="Start meeting"
|
||||
attrs="{'invisible': [('calendar_event_id','=', False)]}"/>
|
||||
<field name="duration" widget="float_time"
|
||||
attrs="{'invisible': ['|',('duration', '=', False),
|
||||
('calendar_event_id','=', False)]}"/>
|
||||
<field name="user_id" options="{'no_open': True}"/>
|
||||
<field
|
||||
name="date_deadline"
|
||||
attrs="{'invisible': [('activity_category', '=', 'meeting')]}"
|
||||
/>
|
||||
<field
|
||||
name="calendar_event_id_start"
|
||||
string="Start meeting"
|
||||
attrs="{'invisible': [('calendar_event_id','=', False)]}"
|
||||
/>
|
||||
<field
|
||||
name="duration"
|
||||
widget="float_time"
|
||||
attrs="{'invisible': ['|',('duration', '=', False),
|
||||
('calendar_event_id','=', False)]}"
|
||||
/>
|
||||
<field name="user_id" options="{'no_open': True}" />
|
||||
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': ['|',('calendar_event_id','=', False),('calendar_event_id_partner_ids','=', False)]}">
|
||||
<field name="calendar_event_id_partner_ids" mode="kanban"/>
|
||||
<group
|
||||
attrs="{'invisible': ['|',('calendar_event_id','=', False),('calendar_event_id_partner_ids','=', False)]}"
|
||||
>
|
||||
<field name="calendar_event_id_partner_ids" mode="kanban" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="summary" placeholder="e.g. Discuss proposal"/>
|
||||
<field name="note" placeholder="Log a note..."/>
|
||||
<field name="summary" placeholder="e.g. Discuss proposal" />
|
||||
<field name="note" placeholder="Log a note..." />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
|
@ -55,13 +74,19 @@
|
|||
<record id="mail_activity_view_tree" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.tree</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_tree"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//tree" position="attributes">
|
||||
<attribute name="default_order"/>
|
||||
<attribute name="decoration-danger">(date_deadline < current_date)</attribute>
|
||||
<attribute name="decoration-warning">(date_deadline == current_date)</attribute>
|
||||
<attribute name="decoration-success">(date_deadline > current_date)</attribute>
|
||||
<attribute name="default_order" />
|
||||
<attribute
|
||||
name="decoration-danger"
|
||||
>(date_deadline < current_date)</attribute>
|
||||
<attribute
|
||||
name="decoration-warning"
|
||||
>(date_deadline == current_date)</attribute>
|
||||
<attribute
|
||||
name="decoration-success"
|
||||
>(date_deadline > current_date)</attribute>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
|
@ -72,66 +97,103 @@
|
|||
<record id="mail_activity_view_kanban" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.kanban</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="priority" eval="10" />
|
||||
<field name="arch" type="xml">
|
||||
<kanban default_group_by="activity_type_id" class="_kanban_small_column o_opportunity_kanban" create="0" _order="date_deadline"
|
||||
group_create="false" group_delete="false" group_edit="false">
|
||||
<field name="user_id"/>
|
||||
<field name="res_id"/>
|
||||
<field name="res_name"/>
|
||||
<field name="res_model"/>
|
||||
<field name="summary"/>
|
||||
<field name="date_deadline"/>
|
||||
<field name="state"/>
|
||||
<field name="icon"/>
|
||||
<field name="activity_type_id"/>
|
||||
<field name="activity_category"/>
|
||||
<kanban
|
||||
default_group_by="activity_type_id"
|
||||
class="_kanban_small_column o_opportunity_kanban"
|
||||
create="0"
|
||||
_order="date_deadline"
|
||||
group_create="false"
|
||||
group_delete="false"
|
||||
group_edit="false"
|
||||
>
|
||||
<field name="user_id" />
|
||||
<field name="res_id" />
|
||||
<field name="res_name" />
|
||||
<field name="res_model" />
|
||||
<field name="summary" />
|
||||
<field name="date_deadline" />
|
||||
<field name="state" />
|
||||
<field name="icon" />
|
||||
<field name="activity_type_id" />
|
||||
<field name="activity_category" />
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_content oe_kanban_global_click">
|
||||
<div class="oe_kanban_content">
|
||||
<div>
|
||||
<strong class="o_kanban_record_subtitle">
|
||||
<span t-attf-class="fa #{record.icon.raw_value}" />
|
||||
<field name="summary"/>
|
||||
<span
|
||||
t-attf-class="fa #{record.icon.raw_value}"
|
||||
/>
|
||||
<field name="summary" />
|
||||
</strong>
|
||||
</div>
|
||||
<div>
|
||||
<strong class="o_kanban_record_title"><field name="res_name"/></strong>
|
||||
<strong class="o_kanban_record_title"><field
|
||||
name="res_name"
|
||||
/></strong>
|
||||
</div>
|
||||
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<t t-set="act_date" t-value="new Date(record.date_deadline.raw_value)"/>
|
||||
<t
|
||||
t-set="act_date"
|
||||
t-value="new Date(record.date_deadline.raw_value)"
|
||||
/>
|
||||
<t t-if="act_date < (new Date())">
|
||||
<span t-attf-class="text-danger"><i class="fa fa-clock-o"/></span>
|
||||
<t t-if="record.activity_category.raw_value!='meeting'">
|
||||
<span t-attf-class="text-danger"><i
|
||||
class="fa fa-clock-o"
|
||||
/></span>
|
||||
<t
|
||||
t-if="record.activity_category.raw_value!='meeting'"
|
||||
>
|
||||
<span t-attf-class="text-danger">
|
||||
<field name="date_deadline" t-options='{"widget": "date"}'/>
|
||||
<field
|
||||
name="date_deadline"
|
||||
t-options='{"widget": "date"}'
|
||||
/>
|
||||
</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span t-attf-class="text-danger">
|
||||
<field name="calendar_event_id_start" t-options='{"widget": "date"}'/>
|
||||
<field
|
||||
name="calendar_event_id_start"
|
||||
t-options='{"widget": "date"}'
|
||||
/>
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span><i class="fa fa-clock-o"/></span>
|
||||
<t t-if="record.activity_category.raw_value!='meeting'">
|
||||
<span><i class="fa fa-clock-o" /></span>
|
||||
<t
|
||||
t-if="record.activity_category.raw_value!='meeting'"
|
||||
>
|
||||
<span>
|
||||
<field name="date_deadline" t-options='{"widget": "date"}'/>
|
||||
<field
|
||||
name="date_deadline"
|
||||
t-options='{"widget": "date"}'
|
||||
/>
|
||||
</span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<field name="calendar_event_id_start" t-options='{"widget": "date"}'/>
|
||||
<field
|
||||
name="calendar_event_id_start"
|
||||
t-options='{"widget": "date"}'
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right">
|
||||
<img t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
|
||||
t-att-title="record.user_id.value"
|
||||
t-att-alt="record.user_id.value" width="24" height="24" class="oe_kanban_avatar"/>
|
||||
<img
|
||||
t-att-src="kanban_image('res.users', 'image_small', record.user_id.raw_value)"
|
||||
t-att-title="record.user_id.value"
|
||||
t-att-alt="record.user_id.value"
|
||||
width="24"
|
||||
height="24"
|
||||
class="oe_kanban_avatar"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -147,28 +209,42 @@
|
|||
<record id="mail_activity_view_search" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.search</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_search"/>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_search" />
|
||||
<field name="priority" eval="2" />
|
||||
<field name="mode">primary</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//field[@name="res_model_id"]' position='before'>
|
||||
<field name="user_id"/>
|
||||
<field name="res_name" string="Origin"/>
|
||||
<field name="user_id" />
|
||||
<field name="res_name" string="Origin" />
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//filter[@name="activities_overdue"]' position='before'>
|
||||
<filter string="Act. next month" name="activities_month"
|
||||
domain="[('date_deadline', '<', (context_today()+datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]"
|
||||
help="Show activities scheduled for next month."/>
|
||||
<filter string="Act. next 6 months" name="activities_6_month"
|
||||
domain="[('date_deadline', '<', (context_today()+datetime.timedelta(days=180)).strftime('%Y-%m-%d'))]"
|
||||
help="Show activities scheduled for next 6 months."/>
|
||||
<separator/>
|
||||
<filter
|
||||
string="Act. next month"
|
||||
name="activities_month"
|
||||
domain="[('date_deadline', '<', (context_today()+datetime.timedelta(days=30)).strftime('%Y-%m-%d'))]"
|
||||
help="Show activities scheduled for next month."
|
||||
/>
|
||||
<filter
|
||||
string="Act. next 6 months"
|
||||
name="activities_6_month"
|
||||
domain="[('date_deadline', '<', (context_today()+datetime.timedelta(days=180)).strftime('%Y-%m-%d'))]"
|
||||
help="Show activities scheduled for next 6 months."
|
||||
/>
|
||||
<separator />
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//search/group' position='inside'>
|
||||
<filter string="User" name='assigned_user' context="{'group_by':'user_id'}"/>
|
||||
<filter string="Origin" name='origin' context="{'group_by': 'res_model_id'}"/>
|
||||
<filter
|
||||
string="User"
|
||||
name='assigned_user'
|
||||
context="{'group_by':'user_id'}"
|
||||
/>
|
||||
<filter
|
||||
string="Origin"
|
||||
name='origin'
|
||||
context="{'group_by': 'res_model_id'}"
|
||||
/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
|
@ -184,15 +260,17 @@
|
|||
<field name="view_mode">kanban,form</field>
|
||||
<field name="domain">[]</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="view_ids"
|
||||
eval="[(5, 0, 0),
|
||||
<field
|
||||
name="view_ids"
|
||||
eval="[(5, 0, 0),
|
||||
(0, 0, {'view_mode': 'kanban', 'view_id': ref('mail_activity_view_kanban')}),
|
||||
(0, 0, {'view_mode': 'tree', 'view_id': ref('mail_activity_view_tree')}),
|
||||
(0, 0, {'view_mode': 'form', 'view_id': ref('mail_activity_view_form_board')}),
|
||||
(0, 0, {'view_mode': 'calendar'}),
|
||||
(0, 0, {'view_mode': 'pivot'}),
|
||||
(0, 0, {'view_mode': 'graph'})]"/>
|
||||
<field name="search_view_id" ref="mail_activity_view_search"/>
|
||||
(0, 0, {'view_mode': 'graph'})]"
|
||||
/>
|
||||
<field name="search_view_id" ref="mail_activity_view_search" />
|
||||
</record>
|
||||
|
||||
|
||||
|
@ -200,10 +278,11 @@
|
|||
Menus
|
||||
-->
|
||||
<menuitem
|
||||
id="board_menu_activities"
|
||||
name="Activities"
|
||||
parent="base.menu_board_root"
|
||||
action="open_boards_activities"
|
||||
sequence="1"/>
|
||||
id="board_menu_activities"
|
||||
name="Activities"
|
||||
parent="base.menu_board_root"
|
||||
action="open_boards_activities"
|
||||
sequence="1"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<template id="assets_backend" name="mail_activity_board assets" inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="mail_activity_board assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/mail_activity_board/static/src/js/override_chatter.js"/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_activity_board/static/src/js/override_chatter.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"author": "ForgeFlow, Odoo Community Association (OCA)",
|
||||
"license": "LGPL-3",
|
||||
"category": "Discuss",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"depends": ["mail"],
|
||||
"data": ["views/templates.xml", "views/mail_activity_views.xml"],
|
||||
"pre_init_hook": "pre_init_hook",
|
||||
|
|
|
@ -1,87 +1,86 @@
|
|||
// Copyright 2018-20 ForgeFlow <http://www.forgeflow.com>
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
|
||||
|
||||
odoo.define('mail.Activity.done', function (require) {
|
||||
odoo.define("mail.Activity.done", function(require) {
|
||||
"use strict";
|
||||
|
||||
var mailUtils = require('mail.utils');
|
||||
var core = require('web.core');
|
||||
var time = require('web.time');
|
||||
var mail_activity = require('mail.Activity');
|
||||
var mailUtils = require("mail.utils");
|
||||
var core = require("web.core");
|
||||
var time = require("web.time");
|
||||
var mail_activity = require("mail.Activity");
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
|
||||
// We are forced here to override the method, as there is no possibility
|
||||
// to inherit it.
|
||||
var setDelayLabel = function (activities) {
|
||||
var today = moment().startOf('day');
|
||||
_.each(activities, function (activity) {
|
||||
var to_display = '';
|
||||
var deadline = moment(activity.date_deadline).startOf('day');
|
||||
var setDelayLabel = function(activities) {
|
||||
var today = moment().startOf("day");
|
||||
_.each(activities, function(activity) {
|
||||
var to_display = "";
|
||||
var deadline = moment(activity.date_deadline).startOf("day");
|
||||
// On next line, true means no rounding
|
||||
var diff = deadline.diff(today, 'days', true);
|
||||
var diff = deadline.diff(today, "days", true);
|
||||
if (diff === 0) {
|
||||
to_display = _t('Today');
|
||||
} else {
|
||||
to_display = _t("Today");
|
||||
} else if (diff < 0) {
|
||||
// This block is for overdue
|
||||
if (diff < 0) { // eslint-disable-line no-lonely-if
|
||||
if (diff === -1) {
|
||||
to_display = _t('Yesterday');
|
||||
} else {
|
||||
to_display = _.str.sprintf(
|
||||
_t('%d days overdue'), Math.abs(diff)
|
||||
);
|
||||
}
|
||||
// This block is for due
|
||||
// eslint-disable-line no-lonely-if
|
||||
if (diff === -1) {
|
||||
to_display = _t("Yesterday");
|
||||
} else {
|
||||
if (diff === 1) { // eslint-disable-line no-lonely-if
|
||||
to_display = _t('Tomorrow');
|
||||
} else {
|
||||
to_display = _.str.sprintf(
|
||||
_t('Due in %d days'), Math.abs(diff)
|
||||
);
|
||||
}
|
||||
to_display = _.str.sprintf(_t("%d days overdue"), Math.abs(diff));
|
||||
}
|
||||
// This block is for due
|
||||
} else if (diff === 1) {
|
||||
// eslint-disable-line no-lonely-if
|
||||
to_display = _t("Tomorrow");
|
||||
} else {
|
||||
to_display = _.str.sprintf(_t("Due in %d days"), Math.abs(diff));
|
||||
}
|
||||
activity.label_delay = to_display;
|
||||
});
|
||||
// We do not want to show the activities that have been completed.
|
||||
var open_activities = _.filter(activities, function (activity) {
|
||||
var open_activities = _.filter(activities, function(activity) {
|
||||
return activity.done !== true;
|
||||
});
|
||||
return open_activities;
|
||||
};
|
||||
|
||||
mail_activity.include({
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @private
|
||||
*/
|
||||
_render: function () {
|
||||
_.each(this._activities, function (activity) {
|
||||
_render: function() {
|
||||
_.each(this._activities, function(activity) {
|
||||
var note = mailUtils.parseAndTransform(
|
||||
activity.note || '', mailUtils.inline);
|
||||
var is_blank = (/^\s*$/).test(note);
|
||||
activity.note || "",
|
||||
mailUtils.inline
|
||||
);
|
||||
var is_blank = /^\s*$/.test(note);
|
||||
if (is_blank) {
|
||||
activity.note = '';
|
||||
activity.note = "";
|
||||
} else {
|
||||
activity.note = mailUtils.parseAndTransform(
|
||||
activity.note, mailUtils.addLink);
|
||||
activity.note,
|
||||
mailUtils.addLink
|
||||
);
|
||||
}
|
||||
});
|
||||
var activities = setDelayLabel(this._activities);
|
||||
if (activities.length) {
|
||||
var nbActivities = _.countBy(activities, 'state');
|
||||
this.$el.html(QWeb.render('mail.activity_items', {
|
||||
activities: activities,
|
||||
nbPlannedActivities: nbActivities.planned,
|
||||
nbTodayActivities: nbActivities.today,
|
||||
nbOverdueActivities: nbActivities.overdue,
|
||||
dateFormat: time.getLangDateFormat(),
|
||||
datetimeFormat: time.getLangDatetimeFormat(),
|
||||
}));
|
||||
var nbActivities = _.countBy(activities, "state");
|
||||
this.$el.html(
|
||||
QWeb.render("mail.activity_items", {
|
||||
activities: activities,
|
||||
nbPlannedActivities: nbActivities.planned,
|
||||
nbTodayActivities: nbActivities.today,
|
||||
nbOverdueActivities: nbActivities.overdue,
|
||||
dateFormat: time.getLangDateFormat(),
|
||||
datetimeFormat: time.getLangDatetimeFormat(),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
this.$el.empty();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<!--
|
||||
Copyright 2018-20 ForgeFlow <http://www.forgeflow.com>
|
||||
|
@ -7,15 +7,17 @@
|
|||
<record id="mail_activity_view_form_popup" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.form.popup</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_form_popup"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_form_popup" />
|
||||
<field name="priority">20</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="activity_type_id" position="after">
|
||||
<field name="state"/>
|
||||
<field name="date_done"/>
|
||||
<field name="state" />
|
||||
<field name="date_done" />
|
||||
</field>
|
||||
<button name="action_done" position="attributes">
|
||||
<attribute name="attrs">{'invisible':[('state', '=', 'done')]}</attribute>
|
||||
<attribute
|
||||
name="attrs"
|
||||
>{'invisible':[('state', '=', 'done')]}</attribute>
|
||||
</button>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -23,22 +25,31 @@
|
|||
<record id="mail_activity_view_search" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.search</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_search"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_search" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="res_model_id" position="after">
|
||||
<field name="done"/>
|
||||
<field name="active"/>
|
||||
<filter string="Completed Activities" name="activities_completed"
|
||||
domain="[('active', '=', False), ('state', '=', 'done')]"/>
|
||||
<field name="done" />
|
||||
<field name="active" />
|
||||
<filter
|
||||
string="Completed Activities"
|
||||
name="activities_completed"
|
||||
domain="[('active', '=', False), ('state', '=', 'done')]"
|
||||
/>
|
||||
</field>
|
||||
<filter name="activities_overdue" position="attributes">
|
||||
<attribute name="domain">[('date_deadline', '<', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('date_deadline', '<', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
</filter>
|
||||
<filter name="activities_today" position="attributes">
|
||||
<attribute name="domain">[('date_deadline', '=', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('date_deadline', '=', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
</filter>
|
||||
<filter name="activities_upcoming_all" position="attributes">
|
||||
<attribute name="domain">[('date_deadline', '>', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('date_deadline', '>', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -46,22 +57,34 @@
|
|||
<record id="res_partner_view_search_inherit_mail" model="ir.ui.view">
|
||||
<field name="name">res.partner.view.search.inherit.mail</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="mail.res_partner_view_search_inherit_mail"/>
|
||||
<field name="inherit_id" ref="mail.res_partner_view_search_inherit_mail" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="activities_overdue" position="before">
|
||||
<filter string="Open Activities" name="activities_open"
|
||||
domain="[('activity_ids.active', '=', True)]"/>
|
||||
<filter string="Completed Activities" name="activities_completed"
|
||||
domain="[('activity_ids.active', '=', False), ('activity_ids.state', '=', 'done')]"/>
|
||||
<filter
|
||||
string="Open Activities"
|
||||
name="activities_open"
|
||||
domain="[('activity_ids.active', '=', True)]"
|
||||
/>
|
||||
<filter
|
||||
string="Completed Activities"
|
||||
name="activities_completed"
|
||||
domain="[('activity_ids.active', '=', False), ('activity_ids.state', '=', 'done')]"
|
||||
/>
|
||||
</filter>
|
||||
<filter name="activities_overdue" position="attributes">
|
||||
<attribute name="domain">[('activity_ids.date_deadline', '<', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('activity_ids.date_deadline', '<', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
</filter>
|
||||
<filter name="activities_today" position="attributes">
|
||||
<attribute name="domain">[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('activity_ids.date_deadline', '=', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
</filter>
|
||||
<filter name="activities_upcoming_all" position="attributes">
|
||||
<attribute name="domain">[('activity_ids.date_deadline', '>', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
<attribute
|
||||
name="domain"
|
||||
>[('activity_ids.date_deadline', '>', context_today().strftime('%Y-%m-%d'))]</attribute>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -69,16 +92,20 @@
|
|||
<record id="mail_activity_view_tree" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.tree</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_tree"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="date_deadline" position="after">
|
||||
<field name="state"/>
|
||||
<field name="date_done"/>
|
||||
<field name="state" />
|
||||
<field name="date_done" />
|
||||
</field>
|
||||
<tree position="attributes">
|
||||
<attribute name="decoration-muted">state == 'done'</attribute>
|
||||
<attribute name="decoration-danger">date_deadline < current_date and state != 'done'</attribute>
|
||||
<attribute name="decoration-success">date_deadline == current_date and state != 'done'</attribute>
|
||||
<attribute
|
||||
name="decoration-danger"
|
||||
>date_deadline < current_date and state != 'done'</attribute>
|
||||
<attribute
|
||||
name="decoration-success"
|
||||
>date_deadline == current_date and state != 'done'</attribute>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -86,12 +113,12 @@
|
|||
<record id="mail_activity_view_calendar" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.calendar</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_calendar"/>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_calendar" />
|
||||
<field name="priority" eval="2" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="summary" position="after">
|
||||
<field name="state"/>
|
||||
<field name="date_done"/>
|
||||
<field name="state" />
|
||||
<field name="date_done" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<!--
|
||||
Copyright 2018-20 ForgeFlow <http://www.forgeflow.com>
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
|
||||
-->
|
||||
<template id="assets_backend" name="mail_activity_done assets" inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="mail_activity_done assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/mail_activity_done/static/src/js/mail_activity.js"/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_activity_done/static/src/js/mail_activity.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
<record id="mail_activity_view_form_board" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.form</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_form_board"/>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="mail_activity_board.mail_activity_view_form_board"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="activity_type_id" position="before">
|
||||
<field name="partner_id" readonly="True"/>
|
||||
<field name="commercial_partner_id"/>
|
||||
<field name="partner_id" readonly="True" />
|
||||
<field name="commercial_partner_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -22,11 +25,11 @@
|
|||
<record id="mail_activity_view_tree" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.tree</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_tree"/>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="activity_type_id" position="before">
|
||||
<field name="partner_id" readonly="True"/>
|
||||
<field name="commercial_partner_id"/>
|
||||
<field name="partner_id" readonly="True" />
|
||||
<field name="commercial_partner_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -36,10 +39,10 @@
|
|||
<record id="mail_activity_view_kanban" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.kanban</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_kanban"/>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_kanban" />
|
||||
<field name="arch" type="xml">
|
||||
<strong class="o_kanban_record_title" position="inside">
|
||||
<field name="partner_id"/>
|
||||
<field name="partner_id" />
|
||||
</strong>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -49,11 +52,11 @@
|
|||
<record id="mail_activity_view_search" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.search</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_search"/>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_search" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//field[@name="res_model_id"]' position='before'>
|
||||
<field name="partner_id"/>
|
||||
<field name="commercial_partner_id"/>
|
||||
<field name="partner_id" />
|
||||
<field name="commercial_partner_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="mail_activity_rule_my_team" model="ir.rule">
|
||||
<field name="name">mail.activity: user: my team</field>
|
||||
<field name="model_id" ref="mail.model_mail_activity"/>
|
||||
<field name="domain_force">["|", ('team_id', 'in', user.activity_team_ids.ids), "&", ('team_id', '=', False), ('user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_read" eval="False"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
<field name="model_id" ref="mail.model_mail_activity" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>["|", ('team_id', 'in', user.activity_team_ids.ids), "&", ('team_id', '=', False), ('user_id', '=', user.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_user'))]" />
|
||||
<field name="perm_create" eval="True" />
|
||||
<field name="perm_read" eval="False" />
|
||||
<field name="perm_write" eval="True" />
|
||||
<field name="perm_unlink" eval="True" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -11,32 +11,46 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Activity Team">
|
||||
<header>
|
||||
<field name="count_missing_activities" invisible="1"/>
|
||||
<button name="assign_team_to_unassigned_activities" string="Assign to missing activities"
|
||||
type="object" class="oe_highlight"
|
||||
groups="base.group_no_one"
|
||||
attrs="{'invisible': [('count_missing_activities', '=', 0)]}"/>
|
||||
<field name="count_missing_activities" invisible="1" />
|
||||
<button
|
||||
name="assign_team_to_unassigned_activities"
|
||||
string="Assign to missing activities"
|
||||
type="object"
|
||||
class="oe_highlight"
|
||||
groups="base.group_no_one"
|
||||
attrs="{'invisible': [('count_missing_activities', '=', 0)]}"
|
||||
/>
|
||||
</header>
|
||||
<sheet string="Activity Team">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="toggle_active" type="object"
|
||||
class="oe_stat_button" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button"
|
||||
options='{"terminology": "archive"}'/></button>
|
||||
<button
|
||||
name="toggle_active"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-archive"
|
||||
>
|
||||
<field
|
||||
name="active"
|
||||
widget="boolean_button"
|
||||
options='{"terminology": "archive"}'
|
||||
/></button>
|
||||
</div>
|
||||
<group>
|
||||
<group name="base">
|
||||
<field name="name"/>
|
||||
<field name="user_id"/>
|
||||
<field name="name" />
|
||||
<field name="user_id" />
|
||||
</group>
|
||||
<group name="models">
|
||||
<field name="res_model_ids" widget="many2many_tags"
|
||||
options="{'no_create': True, 'no_open': True}"/>
|
||||
<field
|
||||
name="res_model_ids"
|
||||
widget="many2many_tags"
|
||||
options="{'no_create': True, 'no_open': True}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page name="members" string="Members">
|
||||
<field name="member_ids" nolabel="1"/>
|
||||
<field name="member_ids" nolabel="1" />
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
|
@ -51,8 +65,8 @@
|
|||
<field name="model">mail.activity.team</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
<field name="res_model_ids" widget="many2many_tags"/>
|
||||
<field name="name" />
|
||||
<field name="res_model_ids" widget="many2many_tags" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -64,9 +78,9 @@
|
|||
<field name="model">mail.activity.team</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="res_model_ids"/>
|
||||
<field name="member_ids"/>
|
||||
<field name="name" />
|
||||
<field name="res_model_ids" />
|
||||
<field name="member_ids" />
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -81,7 +95,7 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[]</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="search_view_id" ref="mail_activity_team_view_search"/>
|
||||
<field name="search_view_id" ref="mail_activity_team_view_search" />
|
||||
</record>
|
||||
|
||||
|
||||
|
@ -89,9 +103,10 @@
|
|||
Menus
|
||||
-->
|
||||
<menuitem
|
||||
id="menu_mail_activity_team"
|
||||
name="Activity Teams"
|
||||
parent="base.menu_email"
|
||||
action="mail_activity_team_action"/>
|
||||
id="menu_mail_activity_team"
|
||||
name="Activity Teams"
|
||||
parent="base.menu_email"
|
||||
action="mail_activity_team_action"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="mail_activity_view_form_popup" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.form.popup</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_form_popup"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_form_popup" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="team_id" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="team_id" options="{'no_create': True, 'no_open': True}" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -15,10 +15,10 @@
|
|||
<record id="mail_activity_view_tree" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.tree</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_tree"/>
|
||||
<field name="inherit_id" ref="mail.mail_activity_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="date_deadline" position="after">
|
||||
<field name="team_id"/>
|
||||
<field name="team_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -26,10 +26,13 @@
|
|||
<record id="mail_activity_view_form_board" model="ir.ui.view">
|
||||
<field name="name">mail.activity.view.form</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_form_board"/>
|
||||
<field
|
||||
name="inherit_id"
|
||||
ref="mail_activity_board.mail_activity_view_form_board"
|
||||
/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="team_id"/>
|
||||
<field name="team_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -37,15 +40,15 @@
|
|||
<record id="mail_activity_view_kanban" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.kanban</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_kanban"/>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_kanban" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="user_id" position="after">
|
||||
<field name="team_id"/>
|
||||
<field name="team_id" />
|
||||
</field>
|
||||
<xpath expr="//div[hasclass('oe_kanban_content')]" position="inside">
|
||||
<br/>
|
||||
<br />
|
||||
<div>
|
||||
Team: <field name="team_id"/>
|
||||
Team: <field name="team_id" />
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
|
@ -55,17 +58,21 @@
|
|||
<record id="mail_activity_view_search" model="ir.ui.view">
|
||||
<field name="name">mail.activity.boards.view.search</field>
|
||||
<field name="model">mail.activity</field>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_search"/>
|
||||
<field name="priority" eval="2"/>
|
||||
<field name="inherit_id" ref="mail_activity_board.mail_activity_view_search" />
|
||||
<field name="priority" eval="2" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr='//field[@name="user_id"]' position='before'>
|
||||
<field name="team_id"/>
|
||||
<field name="team_id" />
|
||||
</xpath>
|
||||
<xpath expr='//filter[@name="activities_6_month"]' position='after'>
|
||||
<filter name="my_team_activities" string="My Team Activities" domain="[('team_id.member_ids', '=', uid)]"/>
|
||||
<filter
|
||||
name="my_team_activities"
|
||||
string="My Team Activities"
|
||||
domain="[('team_id.member_ids', '=', uid)]"
|
||||
/>
|
||||
</xpath>
|
||||
<group position='inside'>
|
||||
<filter name='team' string="Team" context="{'group_by': 'team_id'}"/>
|
||||
<filter name='team' string="Team" context="{'group_by': 'team_id'}" />
|
||||
</group>
|
||||
</field>
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
<!-- Update user form !-->
|
||||
<record id="view_users_form_activity_teams" model="ir.ui.view">
|
||||
<field name="name">res.users.form.activity.team</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="inherit_id" ref="base.view_users_form"/>
|
||||
<field name="inherit_id" ref="base.view_users_form" />
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<field name="signature" position="before">
|
||||
<field name="activity_team_ids" widget="many2many_tags"/>
|
||||
<field name="activity_team_ids" widget="many2many_tags" />
|
||||
</field>
|
||||
</data>
|
||||
</field>
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="email_compose_message_wizard_inherit_form">
|
||||
<field name="name">mail.compose.message.form (mail_attach_existing_attachment)</field>
|
||||
<field
|
||||
name="name"
|
||||
>mail.compose.message.form (mail_attach_existing_attachment)</field>
|
||||
<field name="model">mail.compose.message</field>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='attachment_ids']" position="after">
|
||||
<field name="can_attach_attachment" invisible="1"/>
|
||||
<field name="can_attach_attachment" invisible="1" />
|
||||
<div attrs="{'invisible': [('can_attach_attachment', '=', False)]}">
|
||||
<br />
|
||||
<field name="object_attachment_ids" widget="many2many_checkboxes" domain="[('res_model', '=', model), ('res_id', '=', res_id)]" />
|
||||
<field
|
||||
name="object_attachment_ids"
|
||||
widget="many2many_checkboxes"
|
||||
domain="[('res_model', '=', model), ('res_id', '=', res_id)]"
|
||||
/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"summary": "Remove Odoo branding in sent emails",
|
||||
"version": "13.0.2.0.1",
|
||||
"category": "Social Network",
|
||||
"website": "https://github.com/OCA/social/",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"author": "Tecnativa, Eficent, Onestein, Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"installable": True,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"author": "Therp BV,Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"category": "Discuss",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"summary": "Attach emails to Odoo by dragging them from your desktop",
|
||||
"depends": ["mail", "web_drop_target"],
|
||||
"external_dependencies": {"python": ["extract_msg"]},
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
/* global base64js:false, Uint8Array:false */
|
||||
// Copyright 2018 Therp BV <https://therp.nl>
|
||||
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
odoo.define('mail_drop_target', function (require) {
|
||||
odoo.define("mail_drop_target", function(require) {
|
||||
"use strict";
|
||||
var Chatter = require('mail.Chatter');
|
||||
var web_drop_target = require('web_drop_target');
|
||||
var Chatter = require("mail.Chatter");
|
||||
var web_drop_target = require("web_drop_target");
|
||||
|
||||
Chatter.include(web_drop_target.DropTargetMixin);
|
||||
|
||||
Chatter.include({
|
||||
_drop_allowed_types: ['message/rfc822'],
|
||||
_drop_allowed_types: ["message/rfc822"],
|
||||
_get_record_id: function() {
|
||||
return this.record.res_id;
|
||||
},
|
||||
|
||||
_handle_drop_items: function (drop_items, e) {
|
||||
_handle_drop_items: function(drop_items) {
|
||||
var self = this;
|
||||
_.each(drop_items, function(item, e) {
|
||||
return self._handle_file_drop_proxy(item, e);
|
||||
});
|
||||
},
|
||||
_handle_file_drop_proxy: function (item, e) {
|
||||
_handle_file_drop_proxy: function(item, e) {
|
||||
var self = this;
|
||||
var file = item;
|
||||
if (!file || !(file instanceof Blob)) {
|
||||
|
@ -31,20 +31,18 @@ odoo.define('mail_drop_target', function (require) {
|
|||
reader.onloadend = self.proxy(
|
||||
_.partial(self._handle_file_drop, file, reader, e)
|
||||
);
|
||||
reader.onerror = self.proxy('_file_reader_error_handler');
|
||||
reader.onerror = self.proxy("_file_reader_error_handler");
|
||||
reader.readAsArrayBuffer(file);
|
||||
},
|
||||
_handle_file_drop: function (drop_file, reader, e) {
|
||||
_handle_file_drop: function(drop_file, reader) {
|
||||
var self = this,
|
||||
mail_processor = '',
|
||||
data = '';
|
||||
if (drop_file.name.endsWith('.msg')) {
|
||||
mail_processor = 'message_process_msg';
|
||||
data = base64js.fromByteArray(
|
||||
new Uint8Array(reader.result)
|
||||
);
|
||||
mail_processor = "",
|
||||
data = "";
|
||||
if (drop_file.name.endsWith(".msg")) {
|
||||
mail_processor = "message_process_msg";
|
||||
data = base64js.fromByteArray(new Uint8Array(reader.result));
|
||||
} else {
|
||||
mail_processor = 'message_drop';
|
||||
mail_processor = "message_drop";
|
||||
var reader_array = new Uint8Array(reader.result);
|
||||
data = "";
|
||||
for (var i = 0; i < reader_array.length; i++) {
|
||||
|
@ -54,14 +52,14 @@ odoo.define('mail_drop_target', function (require) {
|
|||
// TODO: read some config parameter if this should set
|
||||
// some of the context keys to suppress mail.thread's behavior
|
||||
return this._rpc({
|
||||
model:'mail.thread',
|
||||
method:mail_processor,
|
||||
model: "mail.thread",
|
||||
method: mail_processor,
|
||||
args: [this.record.model, data],
|
||||
kwargs: {
|
||||
thread_id: this.record.data.id,
|
||||
},
|
||||
}).then(function() {
|
||||
self.trigger_up('reload', {});
|
||||
self.trigger_up("reload", {});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.mail</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="mail.res_config_settings_view_form"/>
|
||||
<field name="inherit_id" ref="mail.res_config_settings_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<div id="emails" position="inside">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="disable_notify_mail_drop_target"/>
|
||||
<field name="disable_notify_mail_drop_target" />
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Disable Mail Drag&Drop Notification" for="disable_notify_mail_drop_target"/>
|
||||
<label
|
||||
string="Disable Mail Drag&Drop Notification"
|
||||
for="disable_notify_mail_drop_target"
|
||||
/>
|
||||
<div class="text-muted">
|
||||
When a user drops an email into an existing thread
|
||||
the followers of the thread will not be notified.
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<openerp>
|
||||
<data>
|
||||
<template id="assets_backend" name="mail_drop_target assets" inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="mail_drop_target assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/mail_drop_target/static/src/js/mail_drop_target.js"></script>
|
||||
<link rel="stylesheet" href="/mail_drop_target/static/src/css/mail_drop_target.css"/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_drop_target/static/src/js/mail_drop_target.js"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/mail_drop_target/static/src/css/mail_drop_target.css"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
|
|
|
@ -1,32 +1,33 @@
|
|||
/* Copyright 2014-2015 Grupo ESOC <http://www.grupoesoc.es>
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||
*/
|
||||
odoo.define('mail_full_expand.expand', function (require) {
|
||||
odoo.define("mail_full_expand.expand", function(require) {
|
||||
"use strict";
|
||||
|
||||
var ThreadWidget = require('mail.widget.Thread');
|
||||
var ThreadWidget = require("mail.widget.Thread");
|
||||
|
||||
ThreadWidget.include({
|
||||
events: _.defaults({
|
||||
"click .o_full_expand": "_onClickMessageFullExpand",
|
||||
}, ThreadWidget.prototype.events),
|
||||
events: _.defaults(
|
||||
{
|
||||
"click .o_full_expand": "_onClickMessageFullExpand",
|
||||
},
|
||||
ThreadWidget.prototype.events
|
||||
),
|
||||
|
||||
_onClickMessageFullExpand: function (event) {
|
||||
_onClickMessageFullExpand: function(event) {
|
||||
// Get the action data and execute it to open the full view
|
||||
var do_action = this.do_action,
|
||||
msg_id = $(event.currentTarget).data('message-id');
|
||||
msg_id = $(event.currentTarget).data("message-id");
|
||||
|
||||
this._rpc({
|
||||
route: "/web/action/load",
|
||||
params: {
|
||||
action_id: "mail_full_expand.mail_message_action",
|
||||
},
|
||||
})
|
||||
.then(function (action) {
|
||||
action.res_id = msg_id;
|
||||
do_action(action);
|
||||
});
|
||||
}).then(function(action) {
|
||||
action.res_id = msg_id;
|
||||
do_action(action);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!-- Copyright 2014-2015 Grupo ESOC <http://www.grupoesoc.es>License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<template>
|
||||
<t t-extend="mail.widget.Thread.Message">
|
||||
<t t-jquery=".o_mail_info" t-operation="append">
|
||||
<span class="o_thread_full_spand_icon">
|
||||
<i class="fa o_full_expand fa-arrows-alt" t-att-data-message-id="message.getID()" title="Fully Expand"/>
|
||||
<i
|
||||
class="fa o_full_expand fa-arrows-alt"
|
||||
t-att-data-message-id="message.getID()"
|
||||
title="Fully Expand"
|
||||
/>
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
|
|
|
@ -1,10 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2014-2015 Grupo ESOC <http://www.grupoesoc.es>License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
<template id="assets_backend" inherit_id="web.assets_backend" name="mail_full_expand assets">
|
||||
<template
|
||||
id="assets_backend"
|
||||
inherit_id="web.assets_backend"
|
||||
name="mail_full_expand assets"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<link href="/mail_full_expand/static/src/scss/mail_full_expand.scss" rel="stylesheet" type="text/scss"/>
|
||||
<script src="/mail_full_expand/static/src/js/mail_full_expand.js" type="text/javascript"/>
|
||||
<link
|
||||
href="/mail_full_expand/static/src/scss/mail_full_expand.scss"
|
||||
rel="stylesheet"
|
||||
type="text/scss"
|
||||
/>
|
||||
<script
|
||||
src="/mail_full_expand/static/src/js/mail_full_expand.js"
|
||||
type="text/javascript"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2014-2015 Grupo ESOC <http://www.grupoesoc.es>License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
<record id="mail_message_view_form" model="ir.ui.view">
|
||||
|
@ -8,18 +8,18 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Message">
|
||||
<group>
|
||||
<field name="author_id" readonly="1"/>
|
||||
<field name="email_from" readonly="1"/>
|
||||
<field name="date" readonly="1"/>
|
||||
<field name="partner_ids" readonly="1" widget="many2many_tags"/>
|
||||
<field name="author_id" readonly="1" />
|
||||
<field name="email_from" readonly="1" />
|
||||
<field name="date" readonly="1" />
|
||||
<field name="partner_ids" readonly="1" widget="many2many_tags" />
|
||||
</group>
|
||||
<h1>
|
||||
<field name="subject" readonly="1"/>
|
||||
<field name="subject" readonly="1" />
|
||||
</h1>
|
||||
<field name="body" readonly="1"/>
|
||||
<field name="attachment_ids" readonly="1" widget="many2many_binary"/>
|
||||
<field name="body" readonly="1" />
|
||||
<field name="attachment_ids" readonly="1" widget="many2many_binary" />
|
||||
<footer>
|
||||
<button class="btn-secondary" special="cancel" string="Close"/>
|
||||
<button class="btn-secondary" special="cancel" string="Close" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -28,7 +28,7 @@
|
|||
<field name="name">Read Full Email</field>
|
||||
<field name="res_model">mail.message</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_id" ref="mail_message_view_form"/>
|
||||
<field name="view_id" ref="mail_message_view_form" />
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="0">
|
||||
<record id="email_template_demo" model="mail.template">
|
||||
<field name="name">Inline styles demo</field>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="0">
|
||||
<template id="demo_email_hello" name="demo email hello">
|
||||
<html>
|
||||
|
@ -48,7 +48,10 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td class="left">
|
||||
<img id="main_logo" t-attf-src="data:image;base64,{{env.user.company_id.logo}}" />
|
||||
<img
|
||||
id="main_logo"
|
||||
t-attf-src="data:image;base64,{{env.user.company_id.logo}}"
|
||||
/>
|
||||
</td>
|
||||
<td class="right">
|
||||
<span class="date_today" t-esc="time.strftime('%%d %%B %%Y')" />
|
||||
|
@ -62,18 +65,23 @@
|
|||
<p>Hello <span t-field="object.name" />.</p>
|
||||
</div>
|
||||
<div id="content">
|
||||
<p>This e-mail styles are inline rendered although its template defines styles as embedded CSS!</p>
|
||||
<p
|
||||
>This e-mail styles are inline rendered although its template defines styles as embedded CSS!</p>
|
||||
</div>
|
||||
</main>
|
||||
<footer id="main_footer">
|
||||
<div class="company_info">
|
||||
<p class="website"><a href="https://www.example.com">www.example.com</a></p>
|
||||
<p class="website"><a
|
||||
href="https://www.example.com"
|
||||
>www.example.com</a></p>
|
||||
<div class="address">
|
||||
<div t-field="env.user.company_id.partner_id"
|
||||
t-options='{
|
||||
<div
|
||||
t-field="env.user.company_id.partner_id"
|
||||
t-options='{
|
||||
"widget": "contact",
|
||||
"fields": ["name", "address", "phone", "mobile", "email"]
|
||||
}'/>
|
||||
}'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
|
||||
<template id="email_templates_list">
|
||||
|
@ -17,7 +17,8 @@
|
|||
<li>Copy the link</li>
|
||||
<li>
|
||||
Paste into the address bar and change the record ID (the last value in the URL).
|
||||
<br />If you don't know the ID of the record, just browse to the record via odoo interface and check its ID in the address bar `#id=XXX`.
|
||||
<br
|
||||
/>If you don't know the ID of the record, just browse to the record via odoo interface and check its ID in the address bar `#id=XXX`.
|
||||
</li>
|
||||
<li>Load it</li>
|
||||
</ol>
|
||||
|
@ -31,10 +32,16 @@
|
|||
<strong>XMLID:</strong> <span class="xid" t-esc="xid" /><br />
|
||||
</t>
|
||||
<strong>Link:</strong>
|
||||
<a class="preview" t-attf-href="/email-preview/#{model}/#{xid or tmpl.id}/1">
|
||||
<a
|
||||
class="preview"
|
||||
t-attf-href="/email-preview/#{model}/#{xid or tmpl.id}/1"
|
||||
>
|
||||
Preview
|
||||
</a><br />
|
||||
<a class="preview" t-attf-href="/web#id=#{tmpl.id}&view_type=form&model=mail.template">
|
||||
<a
|
||||
class="preview"
|
||||
t-attf-href="/web#id=#{tmpl.id}&view_type=form&model=mail.template"
|
||||
>
|
||||
View in backend
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="email_template_preview_form">
|
||||
<field name="model">email_template.preview</field>
|
||||
|
@ -6,7 +6,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<footer position="before">
|
||||
<hr />
|
||||
<label for="layout_preview_url"/>
|
||||
<label for="layout_preview_url" />
|
||||
<field name="layout_preview_url" widget="url" />
|
||||
</footer>
|
||||
</field>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Choose if you want to automatically add new recipients as followers
|
||||
on mail.compose.message""",
|
||||
"author": "ACSONE SA/NV," "Odoo Community Association (OCA)",
|
||||
"website": "http://acsone.eu",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"category": "Social Network",
|
||||
"version": "13.0.1.0.0",
|
||||
"license": "AGPL-3",
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="email_compose_message_wizard_inherit_form">
|
||||
<field name="name">mail.compose.message.form (mail_optional_autofollow)</field>
|
||||
<field name="model">mail.compose.message</field>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[field[@name='partner_ids']]" position="after">
|
||||
<field name="autofollow_recipients" attrs="{'invisible': [('composition_mode', '=', 'mass_mail')]}"/>
|
||||
<field
|
||||
name="autofollow_recipients"
|
||||
attrs="{'invisible': [('composition_mode', '=', 'mass_mail')]}"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="email_compose_message_wizard_form" model="ir.ui.view">
|
||||
<field name="model">mail.compose.message</field>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form"/>
|
||||
<field name="inherit_id" ref="mail.email_compose_message_wizard_form" />
|
||||
<field name="arch" type="xml">
|
||||
<span name="document_followers_text" position="before">
|
||||
<field name="notify_followers" attrs="{'invisible': [('composition_mode', '=', 'mass_mail')]}"/>
|
||||
<field
|
||||
name="notify_followers"
|
||||
attrs="{'invisible': [('composition_mode', '=', 'mass_mail')]}"
|
||||
/>
|
||||
</span>
|
||||
<span name="document_followers_text" position="after">
|
||||
<span name="no_followers_text" attrs="{'invisible': [('notify_followers', '=', True)]}" style="color: red;"> - Warning : Followers will not be notified but they can access the notification directly from the document (if they are allowed to)</span>
|
||||
<span
|
||||
name="no_followers_text"
|
||||
attrs="{'invisible': [('notify_followers', '=', True)]}"
|
||||
style="color: red;"
|
||||
> - Warning : Followers will not be notified but they can access the notification directly from the document (if they are allowed to)</span>
|
||||
</span>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright 2017 LasLabs Inc.
|
||||
License LGPL-3 or later (http://www.gnu.org/licenses/lgpl.html).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="ir_mail_server_form" model="ir.ui.view">
|
||||
|
@ -13,8 +11,8 @@
|
|||
<field name="inherit_id" ref="base.ir_mail_server_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='smtp_pass']" position="after">
|
||||
<field name="domain_whitelist"/>
|
||||
<field name="smtp_from" widget="email"/>
|
||||
<field name="domain_whitelist" />
|
||||
<field name="smtp_from" widget="email" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -3,27 +3,24 @@
|
|||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
**********************************************************************************/
|
||||
|
||||
odoo.define("audio_file.preview", function (require) {
|
||||
odoo.define("audio_file.preview", function(require) {
|
||||
"use strict";
|
||||
|
||||
var preview = require("mail_preview_base.preview");
|
||||
var DocumentViewer = preview.DocumentViewer;
|
||||
|
||||
DocumentViewer.include({
|
||||
_checkAttachment: function (attachment) {
|
||||
if (
|
||||
attachment.type !== 'url' && attachment.mimetype.match("audio")
|
||||
) {
|
||||
attachment.type = 'audio';
|
||||
_checkAttachment: function(attachment) {
|
||||
if (attachment.type !== "url" && attachment.mimetype.match("audio")) {
|
||||
attachment.type = "audio";
|
||||
attachment.source_url = this._getImageUrl(attachment);
|
||||
return true;
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
_hasPreview: function (type) {
|
||||
_hasPreview: function(type) {
|
||||
var result = this._super.apply(this, arguments);
|
||||
return result || type === 'audio';
|
||||
return result || type === "audio";
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-extend="DocumentViewer.Content">
|
||||
<t t-jquery=".fa-video-camera" t-operation="after">
|
||||
<i class="fa fa-volume-up mr8"
|
||||
t-if="widget.activeAttachment.type == 'audio'"
|
||||
role="img" aria-label="Audio" title="Audio"/>
|
||||
<i
|
||||
class="fa fa-volume-up mr8"
|
||||
t-if="widget.activeAttachment.type == 'audio'"
|
||||
role="img"
|
||||
aria-label="Audio"
|
||||
title="Audio"
|
||||
/>
|
||||
</t>
|
||||
<t t-jquery=".o_viewer_video" t-operation="after">
|
||||
<audio t-if="widget.activeAttachment.type == 'audio'" class="o_viewer_audio" controls="controls">
|
||||
<source t-attf-src="#{widget.activeAttachment.source_url}" t-att-data-type="widget.activeAttachment.mimetype"/>
|
||||
<audio
|
||||
t-if="widget.activeAttachment.type == 'audio'"
|
||||
class="o_viewer_audio"
|
||||
controls="controls"
|
||||
>
|
||||
<source
|
||||
t-attf-src="#{widget.activeAttachment.source_url}"
|
||||
t-att-data-type="widget.activeAttachment.mimetype"
|
||||
/>
|
||||
</audio>
|
||||
</t>
|
||||
</t>
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
<odoo>
|
||||
<template id="assets_backend" name="audio_assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="//script[last()]" position="after">
|
||||
<script type="text/javascript" src="/mail_preview_audio/static/src/js/preview.js" />
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_preview_audio/static/src/js/preview.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
**********************************************************************************/
|
||||
|
||||
odoo.define("mail_preview_base.preview", function (require) {
|
||||
odoo.define("mail_preview_base.preview", function(require) {
|
||||
"use strict";
|
||||
|
||||
var DocumentViewer = require("mail.DocumentViewer");
|
||||
|
@ -12,12 +12,13 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
var AttachmentBox = require("mail.AttachmentBox");
|
||||
|
||||
DocumentViewer.include({
|
||||
init: function (parent, attachments) {
|
||||
init: function(parent, attachments) {
|
||||
this._super.apply(this, arguments);
|
||||
var self = this;
|
||||
_.forEach(this.attachment, function (attachment) {
|
||||
if (attachment.mimetype === 'application/pdf' ||
|
||||
attachment.type === 'text'
|
||||
_.forEach(this.attachment, function(attachment) {
|
||||
if (
|
||||
attachment.mimetype === "application/pdf" ||
|
||||
attachment.type === "text"
|
||||
) {
|
||||
attachment.source_url = self._getContentUrl(attachment);
|
||||
} else {
|
||||
|
@ -25,7 +26,7 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
}
|
||||
});
|
||||
this.attachment = this.attachment.concat(
|
||||
_.filter(attachments, function (attachment) {
|
||||
_.filter(attachments, function(attachment) {
|
||||
return self._checkAttachment(attachment);
|
||||
})
|
||||
);
|
||||
|
@ -35,41 +36,48 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
This function is a hook, it will allow to define new kind of
|
||||
records
|
||||
*/
|
||||
_checkAttachment: function () {
|
||||
_checkAttachment: function() {
|
||||
return false;
|
||||
},
|
||||
_getContentUrl: function (attachment) {
|
||||
return "/web/content/" + attachment.id +"?filename=" +
|
||||
window.encodeURIComponent(attachment.name);
|
||||
_getContentUrl: function(attachment) {
|
||||
return (
|
||||
"/web/content/" +
|
||||
attachment.id +
|
||||
"?filename=" +
|
||||
window.encodeURIComponent(attachment.name)
|
||||
);
|
||||
},
|
||||
_getImageUrl: function (attachment) {
|
||||
_getImageUrl: function(attachment) {
|
||||
return "/web/image/" + attachment.id;
|
||||
},
|
||||
_hasPreview: function (type, attachment) {
|
||||
return type === 'image' ||
|
||||
type === 'video' ||
|
||||
attachment.mimetype === 'application/pdf';
|
||||
_hasPreview: function(type, attachment) {
|
||||
return (
|
||||
type === "image" ||
|
||||
type === "video" ||
|
||||
attachment.mimetype === "application/pdf"
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
AttachmentBox.include({
|
||||
init: function (parent, record, attachments) {
|
||||
_.each(attachments, function (attachment) {
|
||||
init: function(parent, record, attachments) {
|
||||
_.each(attachments, function(attachment) {
|
||||
attachment.has_preview = DocumentViewer.prototype._hasPreview(
|
||||
attachment.mimetype && attachment.mimetype.split('/').shift(),
|
||||
attachment);
|
||||
attachment.mimetype && attachment.mimetype.split("/").shift(),
|
||||
attachment
|
||||
);
|
||||
});
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
var FieldPreviewViewer = DocumentViewer.extend({
|
||||
init: function (parent, attachments, activeAttachmentID, model, field) {
|
||||
init: function(parent, attachments, activeAttachmentID, model, field) {
|
||||
this.modelName = model;
|
||||
this.fieldName = field;
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
_onDownload: function (e) {
|
||||
_onDownload: function(e) {
|
||||
e.preventDefault();
|
||||
window.location =
|
||||
"/web/content/" +
|
||||
|
@ -82,19 +90,27 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
"datas" +
|
||||
"?download=true";
|
||||
},
|
||||
_getContentUrl: function (attachment) {
|
||||
return "/web/content/" +
|
||||
this.modelName + '/' +
|
||||
attachment.id + '/' +
|
||||
_getContentUrl: function(attachment) {
|
||||
return (
|
||||
"/web/content/" +
|
||||
this.modelName +
|
||||
"/" +
|
||||
attachment.id +
|
||||
"/" +
|
||||
this.fieldName +
|
||||
"?filename=" +
|
||||
window.encodeURIComponent(attachment.name);
|
||||
window.encodeURIComponent(attachment.name)
|
||||
);
|
||||
},
|
||||
_getImageUrl: function (attachment) {
|
||||
return "/web/image/" +
|
||||
this.modelName + '/' +
|
||||
attachment.id + '/' +
|
||||
this.fieldName;
|
||||
_getImageUrl: function(attachment) {
|
||||
return (
|
||||
"/web/image/" +
|
||||
this.modelName +
|
||||
"/" +
|
||||
attachment.id +
|
||||
"/" +
|
||||
this.fieldName
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -102,7 +118,7 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
events: _.extend({}, basic_fields.FieldBinaryFile.prototype.events, {
|
||||
"click .preview_file": "_previewFile",
|
||||
}),
|
||||
_previewFile: function (event) {
|
||||
_previewFile: function(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
var attachmentViewer = new FieldPreviewViewer(
|
||||
|
@ -114,7 +130,7 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
);
|
||||
attachmentViewer.appendTo($("body"));
|
||||
},
|
||||
_renderReadonly: function () {
|
||||
_renderReadonly: function() {
|
||||
this._super.apply(this, arguments);
|
||||
if (this.value) {
|
||||
this.attachment = {
|
||||
|
@ -125,9 +141,7 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
};
|
||||
var mimetype = this.recordData.res_mimetype;
|
||||
var type = mimetype.split("/").shift();
|
||||
if (
|
||||
DocumentViewer.prototype._hasPreview(type, this.attachment)
|
||||
) {
|
||||
if (DocumentViewer.prototype._hasPreview(type, this.attachment)) {
|
||||
this.$el.prepend(
|
||||
$("<span/>").addClass("fa fa-search preview_file")
|
||||
);
|
||||
|
@ -143,5 +157,4 @@ odoo.define("mail_preview_base.preview", function (require) {
|
|||
FieldPreviewBinary: FieldPreviewBinary,
|
||||
DocumentViewer: DocumentViewer,
|
||||
};
|
||||
|
||||
});
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-extend="DocumentViewer.Content">
|
||||
<t t-jquery=".o_viewer_img" t-operation="attributes">
|
||||
<attribute name="t-attf-src">#{widget.activeAttachment.source_url}?unique=1&signature=#{widget.activeAttachment.checksum}</attribute>
|
||||
<attribute
|
||||
name="t-attf-src"
|
||||
>#{widget.activeAttachment.source_url}?unique=1&signature=#{widget.activeAttachment.checksum}</attribute>
|
||||
</t>
|
||||
<t t-jquery=".o_viewer_pdf" t-operation="attributes">
|
||||
<attribute name="t-attf-src">/web/static/lib/pdfjs/web/viewer.html?file=#{widget.activeAttachment.source_url}</attribute>
|
||||
<attribute
|
||||
name="t-attf-src"
|
||||
>/web/static/lib/pdfjs/web/viewer.html?file=#{widget.activeAttachment.source_url}</attribute>
|
||||
</t>
|
||||
<t t-jquery=".o_viewer_video > source" t-operation="attributes">
|
||||
<attribute name="t-attf-src">#{widget.activeAttachment.source_url}</attribute>
|
||||
<attribute
|
||||
name="t-attf-src"
|
||||
>#{widget.activeAttachment.source_url}</attribute>
|
||||
</t>
|
||||
<t t-jquery=".o_viewer_text:first" t-operation="attributes">
|
||||
<attribute name="t-attf-src">#{widget.activeAttachment.source_url}</attribute>
|
||||
<attribute
|
||||
name="t-attf-src"
|
||||
>#{widget.activeAttachment.source_url}</attribute>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
|
@ -22,7 +30,7 @@
|
|||
defined on the preview.
|
||||
TODO: Set the has_preview on a function...
|
||||
-->
|
||||
<t t-set="has_preview" t-value="has_preview || attachment.has_preview"/>
|
||||
<t t-set="has_preview" t-value="has_preview || attachment.has_preview" />
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
|
@ -6,12 +6,22 @@
|
|||
|
||||
-->
|
||||
<odoo>
|
||||
<template id="assets_backend" name="mail_preview_base_assets" inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="mail_preview_base_assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="//script[last()]" position="after">
|
||||
<script type="text/javascript" src="/mail_preview_base/static/src/js/preview.js" />
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_preview_base/static/src/js/preview.js"
|
||||
/>
|
||||
</xpath>
|
||||
<xpath expr="//link[last()]" position="after">
|
||||
<link rel="stylesheet" href="/mail_preview_base/static/src/scss/preview.scss" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/mail_preview_base/static/src/scss/preview.scss"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"author": "Therp BV,Creu Blanca,Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"category": "Social Network",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"summary": "Define a domain from which followers can be selected",
|
||||
"depends": ["mail"],
|
||||
"data": ["data/ir_config_parameter.xml", "data/ir_actions.xml"],
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<act_window id="action_setup" res_model="ir.config_parameter"
|
||||
name="Configure the restriction on followers" view_mode="form" />
|
||||
<act_window
|
||||
id="action_setup"
|
||||
res_model="ir.config_parameter"
|
||||
name="Configure the restriction on followers"
|
||||
view_mode="form"
|
||||
/>
|
||||
<record id="action_setup" model="ir.actions.act_window">
|
||||
<field name="res_id" ref="parameter_domain" />
|
||||
</record>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo noupdate="1">
|
||||
<record id="parameter_domain" model="ir.config_parameter">
|
||||
<field name="key">mail_restrict_follower_selection.domain</field>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"summary": "Email tracking system for all mails sent",
|
||||
"version": "13.0.1.0.6",
|
||||
"category": "Social Network",
|
||||
"website": "http://github.com/OCA/social",
|
||||
"website": "https://github.com/OCA/social",
|
||||
"author": ("Tecnativa, " "Odoo Community Association (OCA)"),
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
<record forcecreate="True" id="decimal_tracking_timestamp" model="decimal.precision">
|
||||
<record
|
||||
forcecreate="True"
|
||||
id="decimal_tracking_timestamp"
|
||||
model="decimal.precision"
|
||||
>
|
||||
<field name="name">MailTracking Timestamp</field>
|
||||
<field name="digits">6</field>
|
||||
</record>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
|
||||
|
@ -8,7 +8,9 @@
|
|||
<field name="res_id" ref="base.partner_demo" />
|
||||
<field name="message_type">comment</field>
|
||||
<field name="subtype_id" ref="mail.mt_comment" />
|
||||
<field name="email_cc">acc@testmail.com,wood.corner26@example.com,toni.rhodes11@example.com</field>
|
||||
<field
|
||||
name="email_cc"
|
||||
>acc@testmail.com,wood.corner26@example.com,toni.rhodes11@example.com</field>
|
||||
<field name="mail_tracking_needs_action">1</field>
|
||||
<field name="body"><![CDATA[<p>This is a message with CC</p>]]></field>
|
||||
<field name="email_from">wood.corner26@example.com</field>
|
||||
|
@ -24,7 +26,7 @@
|
|||
<field name="recipient">demo@yourcompany.example.com</field>
|
||||
<field name="sender">wood.corner26@example.com</field>
|
||||
<field name="state">sent</field>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
|
||||
<!-- Failed Message A -->
|
||||
|
@ -48,7 +50,7 @@
|
|||
<field name="recipient">demo@yourcompany.example.com</field>
|
||||
<field name="sender">wood.corner26@example.com</field>
|
||||
<field name="state">error</field>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
|
||||
<!-- Failed Message B -->
|
||||
|
@ -72,7 +74,7 @@
|
|||
<field name="recipient">demo@yourcompany.example.com</field>
|
||||
<field name="sender">jackson.group82@example.com</field>
|
||||
<field name="state">error</field>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
|
||||
<!-- Failed Message C -->
|
||||
|
@ -96,7 +98,7 @@
|
|||
<field name="recipient">demo@yourcompany.example.com</field>
|
||||
<field name="sender">admin@example.com</field>
|
||||
<field name="state">error</field>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')"/>
|
||||
<field name="time" eval="DateTime.today().strftime('%Y-%m-%d %H:%M')" />
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
||||
<record model="ir.rule" id="mail_tracking_email_portal_public_rule">
|
||||
<field name="name">mail_tracking_email: portal/public: read access on my email trackings</field>
|
||||
<field name="model_id" ref="model_mail_tracking_email"/>
|
||||
<field
|
||||
name="name"
|
||||
>mail_tracking_email: portal/public: read access on my email trackings</field>
|
||||
<field name="model_id" ref="model_mail_tracking_email" />
|
||||
<field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_portal')), (4, ref('base.group_public'))]"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field
|
||||
name="groups"
|
||||
eval="[(4, ref('base.group_portal')), (4, ref('base.group_public'))]"
|
||||
/>
|
||||
<field name="perm_create" eval="False" />
|
||||
<field name="perm_unlink" eval="False" />
|
||||
<field name="perm_write" eval="False" />
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
|
||||
i.fa-caret-down:before {
|
||||
content: '\f0da';
|
||||
content: "\f0da";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@
|
|||
}
|
||||
|
||||
.o_thread_typing_notification_free_space {
|
||||
flex-grow: 1,
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.o_thread_typing_notification_bar {
|
||||
|
@ -60,7 +60,7 @@
|
|||
background-color: rgba($white, 0.75);
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
color: gray('600');
|
||||
color: gray("600");
|
||||
|
||||
&.o_thread_order_asc {
|
||||
@include o-position-sticky($bottom: 0px);
|
||||
|
@ -83,7 +83,7 @@
|
|||
margin-top: 0px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
border-bottom: 1px solid gray('400');
|
||||
border-bottom: 1px solid gray("400");
|
||||
text-align: center;
|
||||
|
||||
.o_thread_date {
|
||||
|
@ -116,8 +116,8 @@
|
|||
margin-bottom: 0px;
|
||||
|
||||
&.o_mail_not_discussion {
|
||||
background-color: rgba(gray('300'), 0.5);
|
||||
border-bottom: 1px solid gray('400');
|
||||
background-color: rgba(gray("300"), 0.5);
|
||||
border-bottom: 1px solid gray("400");
|
||||
}
|
||||
|
||||
.o_thread_message_sidebar {
|
||||
|
@ -155,7 +155,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
&:hover, &.o_thread_selected_message {
|
||||
&:hover,
|
||||
&.o_thread_selected_message {
|
||||
.o_thread_message_side_date {
|
||||
opacity: $o-mail-thread-side-date-opacity;
|
||||
}
|
||||
|
@ -182,8 +183,6 @@
|
|||
text-align: justify;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.o_mail_subject {
|
||||
font-style: italic;
|
||||
}
|
||||
|
@ -193,7 +192,8 @@
|
|||
color: gray;
|
||||
}
|
||||
|
||||
[summary~=o_mail_notification] { // name conflicts with channel notifications, but is odoo notification buttons to hide in chatter if present
|
||||
[summary~="o_mail_notification"] {
|
||||
// name conflicts with channel notifications, but is odoo notification buttons to hide in chatter if present
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.o_thread_message_star, .o_thread_message_needaction, .o_thread_message_reply, .o_thread_message_email {
|
||||
.o_thread_message_star,
|
||||
.o_thread_message_needaction,
|
||||
.o_thread_message_reply,
|
||||
.o_thread_message_email {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
|
@ -232,14 +235,16 @@
|
|||
&.o_thread_message_email_ready {
|
||||
color: grey;
|
||||
}
|
||||
&.o_thread_message_email_exception, &.o_thread_message_email_bounce {
|
||||
&.o_thread_message_email_exception,
|
||||
&.o_thread_message_email_bounce {
|
||||
color: red;
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.o_attachments_list, .o_attachments_previews {
|
||||
.o_attachments_list,
|
||||
.o_attachments_previews {
|
||||
&:last-child {
|
||||
margin-bottom: $grid-gutter-width;
|
||||
}
|
||||
|
@ -299,7 +304,7 @@
|
|||
.o_activity_info {
|
||||
vertical-align: baseline;
|
||||
padding: 4px 6px;
|
||||
background: theme-color('light');
|
||||
background: theme-color("light");
|
||||
border-radius: 2px 2px 0 0;
|
||||
@include o-hover-opacity(1, 1);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Copyright 2019 Alexandre Díaz
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
||||
odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
||||
odoo.define("mail_tracking.FailedMessageDiscuss", function(require) {
|
||||
"use strict";
|
||||
|
||||
// To be considered:
|
||||
|
@ -9,45 +9,40 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
// - A mailbox is a type of thread that is displayed on top of
|
||||
// the discuss menu, has a counter, etc...
|
||||
|
||||
var MailManagerNotif = require('mail.Manager.Notification');
|
||||
var AbstractMessage = require('mail.model.AbstractMessage');
|
||||
var Message = require('mail.model.Message');
|
||||
var Discuss = require('mail.Discuss');
|
||||
var MailManager = require('mail.Manager');
|
||||
var Mailbox = require('mail.model.Mailbox');
|
||||
var core = require('web.core');
|
||||
var session = require('web.session');
|
||||
var MailManagerNotif = require("mail.Manager.Notification");
|
||||
var AbstractMessage = require("mail.model.AbstractMessage");
|
||||
var Message = require("mail.model.Message");
|
||||
var Discuss = require("mail.Discuss");
|
||||
var MailManager = require("mail.Manager");
|
||||
var Mailbox = require("mail.model.Mailbox");
|
||||
var core = require("web.core");
|
||||
var session = require("web.session");
|
||||
|
||||
var QWeb = core.qweb;
|
||||
var _t = core._t;
|
||||
|
||||
/* The states to consider a message as failed message */
|
||||
var FAILED_STATES = [
|
||||
'error', 'rejected', 'spam', 'bounced', 'soft-bounced',
|
||||
];
|
||||
|
||||
var FAILED_STATES = ["error", "rejected", "spam", "bounced", "soft-bounced"];
|
||||
|
||||
AbstractMessage.include({
|
||||
|
||||
/**
|
||||
* Abstract declaration to know if a message is included in the
|
||||
* failed mailbox. By default it should be false.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isFailed: function () {
|
||||
isFailed: function() {
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
Message.include({
|
||||
|
||||
/**
|
||||
* Overrides to store information from server
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init: function (parent, data) {
|
||||
init: function(parent, data) {
|
||||
this._isFailedMessage = data.is_failed_message;
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
@ -58,8 +53,8 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
isFailed: function () {
|
||||
return _.contains(this._threadIDs, 'mailbox_failed');
|
||||
isFailed: function() {
|
||||
return _.contains(this._threadIDs, "mailbox_failed");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -67,11 +62,11 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @param {Boolean} failed
|
||||
*/
|
||||
setFailed: function (failed) {
|
||||
setFailed: function(failed) {
|
||||
if (failed) {
|
||||
this._addThread('mailbox_failed');
|
||||
this._addThread("mailbox_failed");
|
||||
} else {
|
||||
this.removeThread('mailbox_failed');
|
||||
this.removeThread("mailbox_failed");
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -80,21 +75,20 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_processMailboxes: function () {
|
||||
_processMailboxes: function() {
|
||||
this.setFailed(this._isFailedMessage);
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
MailManagerNotif.include({
|
||||
|
||||
/**
|
||||
* Overrides to handle changes in the 'mail_tracking_needs_action' flag
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
_handlePartnerNotification: function (data) {
|
||||
if (data.type === 'toggle_tracking_status') {
|
||||
_handlePartnerNotification: function(data) {
|
||||
if (data.type === "toggle_tracking_status") {
|
||||
this._handleChangeTrackingNeedsActionNotification(data);
|
||||
} else {
|
||||
// Workaround to avoid call '_handlePartnerChannelNotification'
|
||||
|
@ -113,24 +107,23 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
* @private
|
||||
* @param {Object} data
|
||||
*/
|
||||
_handleChangeTrackingNeedsActionNotification: function (data) {
|
||||
_handleChangeTrackingNeedsActionNotification: function(data) {
|
||||
var self = this;
|
||||
var failed = this.getMailbox('failed');
|
||||
_.each(data.message_ids, function (messageID) {
|
||||
var message = _.find(self._messages, function (msg) {
|
||||
var failed = this.getMailbox("failed");
|
||||
_.each(data.message_ids, function(messageID) {
|
||||
var message = _.find(self._messages, function(msg) {
|
||||
return msg.getID() === messageID;
|
||||
});
|
||||
if (message) {
|
||||
message.setFailed(data.needs_actions);
|
||||
if (message.isFailed() === false) {
|
||||
self._removeMessageFromThread(
|
||||
'mailbox_failed', message);
|
||||
self._removeMessageFromThread("mailbox_failed", message);
|
||||
} else {
|
||||
self._addMessageToThreads(message, []);
|
||||
var channelFailed = self.getMailbox('failed');
|
||||
var channelFailed = self.getMailbox("failed");
|
||||
channelFailed.invalidateCaches();
|
||||
}
|
||||
self._mailBus.trigger('update_message', message, data.type);
|
||||
self._mailBus.trigger("update_message", message, data.type);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -143,14 +136,14 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
}
|
||||
|
||||
// Trigger event to refresh threads
|
||||
this._mailBus.trigger('update_failed', failed.getMailboxCounter());
|
||||
this._mailBus.trigger("update_failed", failed.getMailboxCounter());
|
||||
},
|
||||
});
|
||||
|
||||
Discuss.include({
|
||||
events: _.extend({}, Discuss.prototype.events, {
|
||||
'click .o_failed_message_retry': '_onRetryFailedMessage',
|
||||
'click .o_failed_message_reviewed': '_onMarkFailedMessageReviewed',
|
||||
"click .o_failed_message_retry": "_onRetryFailedMessage",
|
||||
"click .o_failed_message_reviewed": "_onMarkFailedMessageReviewed",
|
||||
}),
|
||||
|
||||
/**
|
||||
|
@ -159,8 +152,8 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_sidebarQWebParams: function () {
|
||||
var failed = this.call('mail_service', 'getMailbox', 'failed');
|
||||
_sidebarQWebParams: function() {
|
||||
var failed = this.call("mail_service", "getMailbox", "failed");
|
||||
return {
|
||||
activeThreadID: this._thread ? this._thread.getID() : undefined,
|
||||
failedCounter: failed.getMailboxCounter(),
|
||||
|
@ -173,14 +166,16 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_renderSidebar: function () {
|
||||
_renderSidebar: function() {
|
||||
var $sidebar = this._super.apply(this, arguments);
|
||||
// Because Odoo implementation isn't designed to be inherited
|
||||
// properly, we inject 'failed' button using jQuery.
|
||||
var $failed_item = $(QWeb.render('mail_tracking.SidebarFailed',
|
||||
this._sidebarQWebParams()));
|
||||
var $failed_item = $(
|
||||
QWeb.render("mail_tracking.SidebarFailed", this._sidebarQWebParams())
|
||||
);
|
||||
$failed_item.insertAfter(
|
||||
$sidebar.find(".o_mail_discuss_title_main").filter(":last"));
|
||||
$sidebar.find(".o_mail_discuss_title_main").filter(":last")
|
||||
);
|
||||
return $sidebar;
|
||||
},
|
||||
|
||||
|
@ -190,11 +185,11 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_renderSidebarMailboxes: function () {
|
||||
_renderSidebarMailboxes: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$('.o_mail_discuss_sidebar_mailboxes').append(
|
||||
QWeb.render('mail_tracking.SidebarFailed',
|
||||
this._sidebarQWebParams()));
|
||||
this.$(".o_mail_discuss_sidebar_mailboxes").append(
|
||||
QWeb.render("mail_tracking.SidebarFailed", this._sidebarQWebParams())
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -202,12 +197,15 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_renderButtons: function () {
|
||||
_renderButtons: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.$btn_set_all_reviewed = this.$buttons.find(
|
||||
'.o_mail_discuss_button_set_all_reviewed');
|
||||
this.$btn_set_all_reviewed
|
||||
.on('click', $.proxy(this, "_onSetAllAsReviewedClicked"));
|
||||
".o_mail_discuss_button_set_all_reviewed"
|
||||
);
|
||||
this.$btn_set_all_reviewed.on(
|
||||
"click",
|
||||
$.proxy(this, "_onSetAllAsReviewedClicked")
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -217,11 +215,11 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_updateControlPanelButtons: function (thread) {
|
||||
this.$btn_set_all_reviewed
|
||||
.toggleClass(
|
||||
'd-none d-md-none',
|
||||
thread.getID() !== 'mailbox_failed');
|
||||
_updateControlPanelButtons: function(thread) {
|
||||
this.$btn_set_all_reviewed.toggleClass(
|
||||
"d-none d-md-none",
|
||||
thread.getID() !== "mailbox_failed"
|
||||
);
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
@ -233,18 +231,16 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_updateButtonStatus: function (disabled, type) {
|
||||
if (this._thread.getID() === 'mailbox_failed') {
|
||||
this.$btn_set_all_reviewed
|
||||
.toggleClass('disabled', disabled);
|
||||
_updateButtonStatus: function(disabled, type) {
|
||||
if (this._thread.getID() === "mailbox_failed") {
|
||||
this.$btn_set_all_reviewed.toggleClass("disabled", disabled);
|
||||
// Display Rainbowman when all failed messages are reviewed
|
||||
// through 'TOGGLE TRACKING STATUS' or marking last failed
|
||||
// message as reviewed
|
||||
if (disabled && type === 'toggle_tracking_status') {
|
||||
this.trigger_up('show_effect', {
|
||||
message: _t(
|
||||
"Congratulations, your failed mailbox is empty"),
|
||||
type: 'rainbow_man',
|
||||
if (disabled && type === "toggle_tracking_status") {
|
||||
this.trigger_up("show_effect", {
|
||||
message: _t("Congratulations, your failed mailbox is empty"),
|
||||
type: "rainbow_man",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -255,20 +251,18 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_onMessageUpdated: function (message, type) {
|
||||
_onMessageUpdated: function(message, type) {
|
||||
var self = this;
|
||||
var currentThreadID = this._thread.getID();
|
||||
if (currentThreadID === 'mailbox_failed' && !message.isFailed()) {
|
||||
this._thread.fetchMessages(this.domain)
|
||||
.then(function () {
|
||||
var options = self._getThreadRenderingOptions();
|
||||
self._threadWidget.removeMessageAndRender(
|
||||
message.getID(), self._thread, options)
|
||||
.then(function () {
|
||||
self._updateButtonStatus(
|
||||
!self._thread.hasMessages(), type);
|
||||
});
|
||||
});
|
||||
if (currentThreadID === "mailbox_failed" && !message.isFailed()) {
|
||||
this._thread.fetchMessages(this.domain).then(function() {
|
||||
var options = self._getThreadRenderingOptions();
|
||||
self._threadWidget
|
||||
.removeMessageAndRender(message.getID(), self._thread, options)
|
||||
.then(function() {
|
||||
self._updateButtonStatus(!self._thread.hasMessages(), type);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Workaround to avoid calling '_fetchAndRenderThread' and
|
||||
// refetching thread messages because these messages are
|
||||
|
@ -283,9 +277,9 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_getThreadRenderingOptions: function () {
|
||||
_getThreadRenderingOptions: function() {
|
||||
var values = this._super.apply(this, arguments);
|
||||
if (this._thread.getID() === 'mailbox_failed') {
|
||||
if (this._thread.getID() === "mailbox_failed") {
|
||||
values.displayEmailIcons = true;
|
||||
values.displayReplyIcons = false;
|
||||
values.displayRetryButton = true;
|
||||
|
@ -299,10 +293,13 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_startListening: function () {
|
||||
_startListening: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.call('mail_service', 'getMailBus')
|
||||
.on('update_failed', this, this._throttledUpdateThreads);
|
||||
this.call("mail_service", "getMailBus").on(
|
||||
"update_failed",
|
||||
this,
|
||||
this._throttledUpdateThreads
|
||||
);
|
||||
},
|
||||
|
||||
// Handlers
|
||||
|
@ -312,10 +309,10 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
* @private
|
||||
* @param {Event} event
|
||||
*/
|
||||
_onRetryFailedMessage: function (event) {
|
||||
_onRetryFailedMessage: function(event) {
|
||||
event.preventDefault();
|
||||
var messageID = $(event.currentTarget).data('message-id');
|
||||
this.do_action('mail.mail_resend_message_action', {
|
||||
var messageID = $(event.currentTarget).data("message-id");
|
||||
this.do_action("mail.mail_resend_message_action", {
|
||||
additional_context: {
|
||||
mail_message_to_resend: messageID,
|
||||
},
|
||||
|
@ -329,12 +326,12 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
* @param {Event} event
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_onMarkFailedMessageReviewed: function (event) {
|
||||
_onMarkFailedMessageReviewed: function(event) {
|
||||
event.preventDefault();
|
||||
var messageID = $(event.currentTarget).data('message-id');
|
||||
var messageID = $(event.currentTarget).data("message-id");
|
||||
return this._rpc({
|
||||
model: 'mail.message',
|
||||
method: 'set_need_action_done',
|
||||
model: "mail.message",
|
||||
method: "set_need_action_done",
|
||||
args: [[messageID]],
|
||||
context: this.getSession().user_context,
|
||||
});
|
||||
|
@ -345,22 +342,21 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
*
|
||||
* @private
|
||||
*/
|
||||
_onSetAllAsReviewedClicked: function () {
|
||||
_onSetAllAsReviewedClicked: function() {
|
||||
this._thread.setAllMessagesAsReviewed();
|
||||
},
|
||||
});
|
||||
|
||||
MailManager.include({
|
||||
|
||||
/**
|
||||
* Add the 'failed' mailbox
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
_updateMailboxesFromServer: function (data) {
|
||||
_updateMailboxesFromServer: function(data) {
|
||||
this._super.apply(this, arguments);
|
||||
this._addMailbox({
|
||||
id: 'failed',
|
||||
id: "failed",
|
||||
name: _t("Failed"),
|
||||
mailboxCounter: data.failed_counter || 0,
|
||||
});
|
||||
|
@ -368,20 +364,19 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
});
|
||||
|
||||
Mailbox.include({
|
||||
|
||||
/**
|
||||
* Overrides to add domain for 'failed' mailbox thread
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
_getThreadDomain: function () {
|
||||
if (this._id === 'mailbox_failed') {
|
||||
_getThreadDomain: function() {
|
||||
if (this._id === "mailbox_failed") {
|
||||
return [
|
||||
['mail_tracking_ids.state', 'in', FAILED_STATES],
|
||||
['mail_tracking_needs_action', '=', true],
|
||||
'|',
|
||||
['partner_ids', 'in', [session.partner_id]],
|
||||
['author_id', '=', session.partner_id],
|
||||
["mail_tracking_ids.state", "in", FAILED_STATES],
|
||||
["mail_tracking_needs_action", "=", true],
|
||||
"|",
|
||||
["partner_ids", "in", [session.partner_id]],
|
||||
["author_id", "=", session.partner_id],
|
||||
];
|
||||
}
|
||||
// Workaround to avoid throw 'Missing domain' exception. Call _super
|
||||
|
@ -397,15 +392,14 @@ odoo.define('mail_tracking.FailedMessageDiscuss', function (require) {
|
|||
* @returns {$.Promise} resolved when all messages have been marked as
|
||||
* reviewed on the server
|
||||
*/
|
||||
setAllMessagesAsReviewed: function () {
|
||||
if (this._id === 'mailbox_failed' && this.getMailboxCounter() > 0) {
|
||||
setAllMessagesAsReviewed: function() {
|
||||
if (this._id === "mailbox_failed" && this.getMailboxCounter() > 0) {
|
||||
return this._rpc({
|
||||
model: 'mail.message',
|
||||
method: 'set_all_as_reviewed',
|
||||
model: "mail.message",
|
||||
method: "set_all_as_reviewed",
|
||||
});
|
||||
}
|
||||
return $.when();
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
/* Copyright 2019 Alexandre Díaz
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
||||
odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
||||
odoo.define("mail_tracking.FailedMessageThread", function(require) {
|
||||
"use strict";
|
||||
|
||||
var AbstractField = require('web.AbstractField');
|
||||
var BasicModel = require('web.BasicModel');
|
||||
var BasicView = require('web.BasicView');
|
||||
var Chatter = require('mail.Chatter');
|
||||
var MailThread = require('mail.widget.Thread');
|
||||
var utils = require('mail.utils');
|
||||
var core = require('web.core');
|
||||
var field_registry = require('web.field_registry');
|
||||
var time = require('web.time');
|
||||
var AbstractField = require("web.AbstractField");
|
||||
var BasicModel = require("web.BasicModel");
|
||||
var BasicView = require("web.BasicView");
|
||||
var Chatter = require("mail.Chatter");
|
||||
var MailThread = require("mail.widget.Thread");
|
||||
var utils = require("mail.utils");
|
||||
var core = require("web.core");
|
||||
var field_registry = require("web.field_registry");
|
||||
var time = require("web.time");
|
||||
|
||||
var QWeb = core.qweb;
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to fetch failed messages
|
||||
*
|
||||
|
@ -24,28 +23,29 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @param {Array} ids
|
||||
* @returns {Array}
|
||||
*/
|
||||
function _readMessages (widget, ids) {
|
||||
function _readMessages(widget, ids) {
|
||||
if (!ids.length) {
|
||||
return $.when([]);
|
||||
}
|
||||
var context = widget.record && widget.record.getContext();
|
||||
return widget._rpc({
|
||||
model: 'mail.message',
|
||||
method: 'get_failed_messages',
|
||||
args: [ids],
|
||||
context: context || widget.getSession().user_context,
|
||||
}).then(function (messages) {
|
||||
// Convert date to moment
|
||||
_.each(messages, function (msg) {
|
||||
msg.date = moment(time.auto_str_to_date(msg.date));
|
||||
msg.hour = utils.timeFromNow(msg.date);
|
||||
return widget
|
||||
._rpc({
|
||||
model: "mail.message",
|
||||
method: "get_failed_messages",
|
||||
args: [ids],
|
||||
context: context || widget.getSession().user_context,
|
||||
})
|
||||
.then(function(messages) {
|
||||
// Convert date to moment
|
||||
_.each(messages, function(msg) {
|
||||
msg.date = moment(time.auto_str_to_date(msg.date));
|
||||
msg.hour = utils.timeFromNow(msg.date);
|
||||
});
|
||||
return messages;
|
||||
});
|
||||
return messages;
|
||||
});
|
||||
}
|
||||
|
||||
BasicModel.include({
|
||||
|
||||
/**
|
||||
* Fetch data for the 'mail_failed_message' field widget in form views.
|
||||
*
|
||||
|
@ -54,27 +54,29 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @param {String} fieldName
|
||||
* @returns {Array}
|
||||
*/
|
||||
_fetchSpecialFailedMessages: function (record, fieldName) {
|
||||
var localID = record._changes && fieldName in record._changes
|
||||
? record._changes[fieldName] : record.data[fieldName];
|
||||
_fetchSpecialFailedMessages: function(record, fieldName) {
|
||||
var localID =
|
||||
record._changes && fieldName in record._changes
|
||||
? record._changes[fieldName]
|
||||
: record.data[fieldName];
|
||||
return _readMessages(this, this.localData[localID].res_ids);
|
||||
},
|
||||
});
|
||||
|
||||
var FailedMessage = AbstractField.extend({
|
||||
className: 'o_mail_failed_message',
|
||||
className: "o_mail_failed_message",
|
||||
events: {
|
||||
'click .o_failed_message_retry': '_onRetryFailedMessage',
|
||||
'click .o_failed_message_reviewed': '_onMarkFailedMessageReviewed',
|
||||
"click .o_failed_message_retry": "_onRetryFailedMessage",
|
||||
"click .o_failed_message_reviewed": "_onMarkFailedMessageReviewed",
|
||||
},
|
||||
specialData: '_fetchSpecialFailedMessages',
|
||||
specialData: "_fetchSpecialFailedMessages",
|
||||
|
||||
/**
|
||||
* Overrides to reference failed messages in a easy way
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.failed_messages = this.record.specialData[this.name] || [];
|
||||
},
|
||||
|
@ -84,10 +86,9 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
start: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.call(
|
||||
'bus_service', 'onNotification', this, this._onNotification);
|
||||
this.call("bus_service", "onNotification", this, this._onNotification);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -96,7 +97,7 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @returns {Object}
|
||||
*/
|
||||
_failedItemsQWebParams: function () {
|
||||
_failedItemsQWebParams: function() {
|
||||
return {
|
||||
failed_messages: this.failed_messages,
|
||||
nbFailedMessages: this.failed_messages.length,
|
||||
|
@ -108,11 +109,14 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
/**
|
||||
* @private
|
||||
*/
|
||||
_render: function () {
|
||||
_render: function() {
|
||||
if (this.failed_messages.length) {
|
||||
this.$el.html(QWeb.render(
|
||||
'mail_tracking.failed_message_items',
|
||||
this._failedItemsQWebParams()));
|
||||
this.$el.html(
|
||||
QWeb.render(
|
||||
"mail_tracking.failed_message_items",
|
||||
this._failedItemsQWebParams()
|
||||
)
|
||||
);
|
||||
} else {
|
||||
this.$el.empty();
|
||||
}
|
||||
|
@ -124,7 +128,7 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @param {Object} record
|
||||
*/
|
||||
_reset: function (record) {
|
||||
_reset: function(record) {
|
||||
this._super.apply(this, arguments);
|
||||
this.failed_messages = this.record.specialData[this.name] || [];
|
||||
this.res_id = record.res_id;
|
||||
|
@ -136,8 +140,8 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @param {Array} fieldsToReload
|
||||
*/
|
||||
_reload: function (fieldsToReload) {
|
||||
this.trigger_up('reload_mail_fields', fieldsToReload);
|
||||
_reload: function(fieldsToReload) {
|
||||
this.trigger_up("reload_mail_fields", fieldsToReload);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -147,10 +151,10 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @param {Int} id
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_markFailedMessageReviewed: function (id) {
|
||||
_markFailedMessageReviewed: function(id) {
|
||||
return this._rpc({
|
||||
model: 'mail.message',
|
||||
method: 'set_need_action_done',
|
||||
model: "mail.message",
|
||||
method: "set_need_action_done",
|
||||
args: [[id]],
|
||||
context: this.record.getContext(),
|
||||
});
|
||||
|
@ -165,13 +169,13 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @param {Array} notifs
|
||||
*/
|
||||
_onNotification: function (notifs) {
|
||||
_onNotification: function(notifs) {
|
||||
var self = this;
|
||||
_.each(notifs, function (notif) {
|
||||
_.each(notifs, function(notif) {
|
||||
var model = notif[0][1];
|
||||
if (model === 'res.partner') {
|
||||
if (model === "res.partner") {
|
||||
var data = notif[1];
|
||||
if (data.type === 'toggle_tracking_status') {
|
||||
if (data.type === "toggle_tracking_status") {
|
||||
// Reload 'mail_failed_message' widget
|
||||
self._reload({failed_message: true});
|
||||
}
|
||||
|
@ -186,10 +190,10 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @param {Event} event
|
||||
*/
|
||||
_onRetryFailedMessage: function (event) {
|
||||
_onRetryFailedMessage: function(event) {
|
||||
event.preventDefault();
|
||||
var messageID = $(event.currentTarget).data('message-id');
|
||||
this.do_action('mail.mail_resend_message_action', {
|
||||
var messageID = $(event.currentTarget).data("message-id");
|
||||
this.do_action("mail.mail_resend_message_action", {
|
||||
additional_context: {
|
||||
mail_message_to_resend: messageID,
|
||||
},
|
||||
|
@ -202,26 +206,26 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @param {Event} event
|
||||
*/
|
||||
_onMarkFailedMessageReviewed: function (event) {
|
||||
_onMarkFailedMessageReviewed: function(event) {
|
||||
event.preventDefault();
|
||||
var messageID = $(event.currentTarget).data('message-id');
|
||||
var messageID = $(event.currentTarget).data("message-id");
|
||||
this._markFailedMessageReviewed(messageID).then(
|
||||
$.proxy(this, "_reload", {failed_message: true}));
|
||||
$.proxy(this, "_reload", {failed_message: true})
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
field_registry.add('mail_failed_message', FailedMessage);
|
||||
field_registry.add("mail_failed_message", FailedMessage);
|
||||
|
||||
var mailWidgets = ['mail_failed_message'];
|
||||
var mailWidgets = ["mail_failed_message"];
|
||||
BasicView.include({
|
||||
|
||||
/**
|
||||
* Overrides to add 'mail_failed_message' widget as "mail widget" used
|
||||
* in Chatter.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
var fieldsInfo = this.fieldsInfo[this.viewType];
|
||||
for (var fieldName in fieldsInfo) {
|
||||
|
@ -245,18 +249,21 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
});
|
||||
|
||||
Chatter.include({
|
||||
|
||||
/**
|
||||
* Overrides to initialize 'mail_failed_message' widget.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init: function (parent, record, mailFields, options) {
|
||||
init: function(parent, record, mailFields, options) {
|
||||
this._super.apply(this, arguments);
|
||||
// Initialize mail_failed_message widget
|
||||
if (mailFields.mail_failed_message) {
|
||||
this.fields.failed_message = new FailedMessage(
|
||||
this, mailFields.mail_failed_message, record, options);
|
||||
this,
|
||||
mailFields.mail_failed_message,
|
||||
record,
|
||||
options
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -266,12 +273,13 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
* @private
|
||||
* @returns {Promise}
|
||||
*/
|
||||
_render: function () {
|
||||
_render: function() {
|
||||
var self = this;
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
return this._super.apply(this, arguments).then(function() {
|
||||
if (self.fields.failed_message) {
|
||||
self.fields.failed_message.$el.insertBefore(
|
||||
self.$el.find('.o_mail_thread'));
|
||||
self.$el.find(".o_mail_thread")
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -281,9 +289,9 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
*
|
||||
* @override
|
||||
*/
|
||||
_onReloadMailFields: function (event) {
|
||||
_onReloadMailFields: function(event) {
|
||||
if (this.fields.failed_message && event.data.failed_message) {
|
||||
this.trigger_up('reload', {
|
||||
this.trigger_up("reload", {
|
||||
fieldNames: [this.fields.failed_message.name],
|
||||
keepChanges: true,
|
||||
});
|
||||
|
@ -296,13 +304,12 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
});
|
||||
|
||||
MailThread.include({
|
||||
|
||||
/**
|
||||
* Show 'retry' & 'Set as reviewed' buttons in the Chatter
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this._enabledOptions.displayRetryButton = true;
|
||||
this._enabledOptions.displayReviewedButton = true;
|
||||
|
@ -312,5 +319,4 @@ odoo.define('mail_tracking.FailedMessageThread', function (require) {
|
|||
});
|
||||
|
||||
return FailedMessage;
|
||||
|
||||
});
|
||||
|
|
|
@ -2,25 +2,24 @@
|
|||
Copyright 2018 David Vidal - <david.vidal@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
||||
|
||||
odoo.define('mail_tracking.partner_tracking', function (require) {
|
||||
odoo.define("mail_tracking.partner_tracking", function(require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var ActionManager = require('web.ActionManager');
|
||||
var AbstractMessage = require('mail.model.AbstractMessage');
|
||||
var Message = require('mail.model.Message');
|
||||
var ThreadWidget = require('mail.widget.Thread');
|
||||
var core = require("web.core");
|
||||
var ActionManager = require("web.ActionManager");
|
||||
var AbstractMessage = require("mail.model.AbstractMessage");
|
||||
var Message = require("mail.model.Message");
|
||||
var ThreadWidget = require("mail.widget.Thread");
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
AbstractMessage.include({
|
||||
|
||||
/**
|
||||
* Messages do not have any PartnerTrackings.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasPartnerTrackings: function () {
|
||||
hasPartnerTrackings: function() {
|
||||
return false;
|
||||
},
|
||||
|
||||
|
@ -29,13 +28,13 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasEmailCc: function () {
|
||||
hasEmailCc: function() {
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
Message.include({
|
||||
init: function (parent, data) {
|
||||
init: function(parent, data) {
|
||||
this._super.apply(this, arguments);
|
||||
this._partnerTrackings = data.partner_trackings || [];
|
||||
this._emailCc = data.email_cc || [];
|
||||
|
@ -48,7 +47,7 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
* @override
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasPartnerTrackings: function () {
|
||||
hasPartnerTrackings: function() {
|
||||
return _.some(this._partnerTrackings);
|
||||
},
|
||||
|
||||
|
@ -57,7 +56,7 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasEmailCc: function () {
|
||||
hasEmailCc: function() {
|
||||
return _.some(this._emailCc);
|
||||
},
|
||||
|
||||
|
@ -68,7 +67,7 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
* @override
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
getPartnerTrackings: function () {
|
||||
getPartnerTrackings: function() {
|
||||
if (!this.hasPartnerTrackings()) {
|
||||
return [];
|
||||
}
|
||||
|
@ -81,7 +80,7 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
*
|
||||
* @returns {Array}
|
||||
*/
|
||||
getEmailCc: function () {
|
||||
getEmailCc: function() {
|
||||
if (!this.hasEmailCc()) {
|
||||
return [];
|
||||
}
|
||||
|
@ -95,19 +94,19 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
* @param {String} email
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isEmailCc: function (email) {
|
||||
isEmailCc: function(email) {
|
||||
if (!this.hasEmailCc()) {
|
||||
return false;
|
||||
}
|
||||
return _.some(this._emailCc, function (item) {
|
||||
return _.some(this._emailCc, function(item) {
|
||||
return item[0] === email;
|
||||
});
|
||||
},
|
||||
|
||||
toggleTrackingStatus: function () {
|
||||
toggleTrackingStatus: function() {
|
||||
return this._rpc({
|
||||
model: 'mail.message',
|
||||
method: 'toggle_tracking_status',
|
||||
model: "mail.message",
|
||||
method: "toggle_tracking_status",
|
||||
args: [[this.id]],
|
||||
});
|
||||
},
|
||||
|
@ -115,53 +114,52 @@ odoo.define('mail_tracking.partner_tracking', function (require) {
|
|||
|
||||
ThreadWidget.include({
|
||||
events: _.extend(ThreadWidget.prototype.events, {
|
||||
'click .o_mail_action_tracking_partner':
|
||||
'on_tracking_partner_click',
|
||||
'click .o_mail_action_tracking_status': 'on_tracking_status_click',
|
||||
"click .o_mail_action_tracking_partner": "on_tracking_partner_click",
|
||||
"click .o_mail_action_tracking_status": "on_tracking_status_click",
|
||||
}),
|
||||
on_tracking_partner_click: function (event) {
|
||||
var partner_id = this.$el.find(event.currentTarget).data('partner');
|
||||
on_tracking_partner_click: function(event) {
|
||||
var partner_id = this.$el.find(event.currentTarget).data("partner");
|
||||
var state = {
|
||||
'model': 'res.partner',
|
||||
'id': partner_id,
|
||||
'title': _t("Tracking partner"),
|
||||
model: "res.partner",
|
||||
id: partner_id,
|
||||
title: _t("Tracking partner"),
|
||||
};
|
||||
event.preventDefault();
|
||||
this.action_manager.do_push_state(state);
|
||||
var action = {
|
||||
type:'ir.actions.act_window',
|
||||
view_type: 'form',
|
||||
view_mode: 'form',
|
||||
res_model: 'res.partner',
|
||||
views: [[false, 'form']],
|
||||
target: 'current',
|
||||
type: "ir.actions.act_window",
|
||||
view_type: "form",
|
||||
view_mode: "form",
|
||||
res_model: "res.partner",
|
||||
views: [[false, "form"]],
|
||||
target: "current",
|
||||
res_id: partner_id,
|
||||
};
|
||||
this.do_action(action);
|
||||
},
|
||||
on_tracking_status_click: function (event) {
|
||||
var tracking_email_id = $(event.currentTarget).data('tracking');
|
||||
on_tracking_status_click: function(event) {
|
||||
var tracking_email_id = $(event.currentTarget).data("tracking");
|
||||
var state = {
|
||||
'model': 'mail.tracking.email',
|
||||
'id': tracking_email_id,
|
||||
'title': _t("Message tracking"),
|
||||
model: "mail.tracking.email",
|
||||
id: tracking_email_id,
|
||||
title: _t("Message tracking"),
|
||||
};
|
||||
event.preventDefault();
|
||||
this.action_manager.do_push_state(state);
|
||||
var action = {
|
||||
type:'ir.actions.act_window',
|
||||
view_type: 'form',
|
||||
view_mode: 'form',
|
||||
res_model: 'mail.tracking.email',
|
||||
views: [[false, 'form']],
|
||||
target: 'new',
|
||||
type: "ir.actions.act_window",
|
||||
view_type: "form",
|
||||
view_mode: "form",
|
||||
res_model: "mail.tracking.email",
|
||||
views: [[false, "form"]],
|
||||
target: "new",
|
||||
res_id: tracking_email_id,
|
||||
};
|
||||
this.do_action(action);
|
||||
},
|
||||
init: function () {
|
||||
init: function() {
|
||||
this._super.apply(this, arguments);
|
||||
this.action_manager = this.findAncestor(function (ancestor) {
|
||||
this.action_manager = this.findAncestor(function(ancestor) {
|
||||
return ancestor instanceof ActionManager;
|
||||
});
|
||||
},
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates>
|
||||
|
||||
<t t-extend="mail.widget.Thread.Message">
|
||||
<t t-jquery="span[t-attf-class=o_thread_icons]" t-operation="append">
|
||||
<a t-if="message.isFailed() && options.displayRetryButton" class="btn btn-link o_thread_icon btn-default text-muted btn-sm o_failed_message_reviewed o_activity_link mr8" t-att-data-message-id="message.getID()">
|
||||
<i class="fa fa-check"/> Set as Reviewed
|
||||
<a
|
||||
t-if="message.isFailed() && options.displayRetryButton"
|
||||
class="btn btn-link o_thread_icon btn-default text-muted btn-sm o_failed_message_reviewed o_activity_link mr8"
|
||||
t-att-data-message-id="message.getID()"
|
||||
>
|
||||
<i class="fa fa-check" /> Set as Reviewed
|
||||
</a>
|
||||
<a t-if="message.isFailed() && options.displayReviewedButton" class="btn btn-link o_thread_icon btn-default text-muted btn-sm o_failed_message_retry" t-att-data-message-id="message.getID()">
|
||||
<i class="fa fa-retweet"/> Retry
|
||||
<a
|
||||
t-if="message.isFailed() && options.displayReviewedButton"
|
||||
class="btn btn-link o_thread_icon btn-default text-muted btn-sm o_failed_message_retry"
|
||||
t-att-data-message-id="message.getID()"
|
||||
>
|
||||
<i class="fa fa-retweet" /> Retry
|
||||
</a>
|
||||
</t>
|
||||
</t>
|
||||
|
|
|
@ -1,25 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates>
|
||||
|
||||
<t t-name="mail_tracking.SidebarFailedCounter">
|
||||
<span t-attf-class="o_mail_sidebar_failed badge badge-pill #{(counter ? '' : 'd-none')}">
|
||||
<t t-esc="counter"/>
|
||||
<span
|
||||
t-attf-class="o_mail_sidebar_failed badge badge-pill #{(counter ? '' : 'd-none')}"
|
||||
>
|
||||
<t t-esc="counter" />
|
||||
</span>
|
||||
</t>
|
||||
|
||||
<t t-name="mail_tracking.SidebarFailed">
|
||||
<div t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_failed') ? 'o_active': ''}"
|
||||
data-thread-id="mailbox_failed">
|
||||
<span class="o_thread_name"><i class="fa fa-exclamation mr8"/>Failed</span>
|
||||
<t t-set="counter" t-value="failedCounter"/>
|
||||
<t t-call="mail_tracking.SidebarFailedCounter"/>
|
||||
<div
|
||||
t-attf-class="o_mail_discuss_title_main o_mail_discuss_item #{(activeThreadID === 'mailbox_failed') ? 'o_active': ''}"
|
||||
data-thread-id="mailbox_failed"
|
||||
>
|
||||
<span class="o_thread_name"><i class="fa fa-exclamation mr8" />Failed</span>
|
||||
<t t-set="counter" t-value="failedCounter" />
|
||||
<t t-call="mail_tracking.SidebarFailedCounter" />
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-extend="mail.widget.Thread.Empty">
|
||||
<t t-jquery="t:last-child" t-operation="after">
|
||||
<t t-if="thread.getID() === 'mailbox_failed'">
|
||||
<div class="o_thread_title">Congratulations, you don't have any failed messages</div>
|
||||
<div
|
||||
class="o_thread_title"
|
||||
>Congratulations, you don't have any failed messages</div>
|
||||
<div>Failed messages appear here.</div>
|
||||
</t>
|
||||
</t>
|
||||
|
@ -27,7 +33,11 @@
|
|||
|
||||
<t t-extend="mail.discuss.ControlButtons">
|
||||
<t t-jquery="div" t-operation="append">
|
||||
<button type="button" class="btn btn-secondary o_mail_discuss_button_set_all_reviewed d-none d-md-none d-md-inline-block" title="Mark all as reviewed">Set all as reviewed</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-secondary o_mail_discuss_button_set_all_reviewed d-none d-md-none d-md-inline-block"
|
||||
title="Mark all as reviewed"
|
||||
>Set all as reviewed</button>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="mail_tracking.failed_message_items">
|
||||
<div class="o_thread_date_separator o_border_dashed collapsed" data-toggle="collapse" data-target="#o_chatter_failed_message">
|
||||
<div
|
||||
class="o_thread_date_separator o_border_dashed collapsed"
|
||||
data-toggle="collapse"
|
||||
data-target="#o_chatter_failed_message"
|
||||
>
|
||||
<a role="button" class="o_thread_date btn">
|
||||
<i class="fa fa-fw fa-caret-down"/>
|
||||
<i class="fa fa-fw fa-caret-down" />
|
||||
Failed messages
|
||||
<small class="o_chatter_failed_message_summary ml8">
|
||||
<span class="badge rounded-circle badge-danger"><t t-esc="nbFailedMessages"/></span>
|
||||
<span class="badge rounded-circle badge-danger"><t
|
||||
t-esc="nbFailedMessages"
|
||||
/></span>
|
||||
</small>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -16,40 +22,60 @@
|
|||
<div class="o_thread_message" style="margin-bottom: 10px">
|
||||
<div class="o_thread_message_sidebar">
|
||||
<div class="o_avatar_stack">
|
||||
<img t-attf-src="/web/image/res.partner/#{message.author[0]}/image_small" class="o_thread_message_avatar rounded-circle mb8" t-att-title="message.author[1]" t-att-alt="message.author[1]"/>
|
||||
<i t-att-class="'o_avatar_icon fa fa-exclamation bg-danger-full'"
|
||||
title="Failed"/>
|
||||
<img
|
||||
t-attf-src="/web/image/res.partner/#{message.author[0]}/image_small"
|
||||
class="o_thread_message_avatar rounded-circle mb8"
|
||||
t-att-title="message.author[1]"
|
||||
t-att-alt="message.author[1]"
|
||||
/>
|
||||
<i
|
||||
t-att-class="'o_avatar_icon fa fa-exclamation bg-danger-full'"
|
||||
title="Failed"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_thread_message_core">
|
||||
<div class="o_mail_info text-muted">
|
||||
<strong class="o_thread_author">
|
||||
<t t-esc="message.author[1]"/>
|
||||
<t t-esc="message.author[1]" />
|
||||
</strong>
|
||||
- <small class="o_mail_timestamp" t-att-title="message.date.format(date_format)"><t t-esc="message.hour"/></small>
|
||||
- <small
|
||||
class="o_mail_timestamp"
|
||||
t-att-title="message.date.format(date_format)"
|
||||
><t t-esc="message.hour" /></small>
|
||||
<span t-attf-class="o_thread_icons">
|
||||
<a href="#" class="btn btn-link btn-success o_thread_icon text-muted btn-sm o_failed_message_reviewed o_activity_link" t-att-data-message-id="message.id">
|
||||
<i class="fa fa-check"/> Set as Reviewed
|
||||
<a
|
||||
href="#"
|
||||
class="btn btn-link btn-success o_thread_icon text-muted btn-sm o_failed_message_reviewed o_activity_link"
|
||||
t-att-data-message-id="message.id"
|
||||
>
|
||||
<i class="fa fa-check" /> Set as Reviewed
|
||||
</a>
|
||||
<a href="#" class="btn btn-link btn-default o_thread_icon text-muted btn-sm o_failed_message_retry" t-att-data-message-id="message.id">
|
||||
<i class="fa fa-retweet"/> Retry
|
||||
<a
|
||||
href="#"
|
||||
class="btn btn-link btn-default o_thread_icon text-muted btn-sm o_failed_message_retry"
|
||||
t-att-data-message-id="message.id"
|
||||
>
|
||||
<i class="fa fa-retweet" /> Retry
|
||||
</a>
|
||||
</span>
|
||||
<br/>
|
||||
<br />
|
||||
<strong class="text-danger">Failed Recipients:</strong>
|
||||
<t t-foreach="message.failed_recipients" t-as="recipient">
|
||||
<t t-if="!recipient_first">
|
||||
-
|
||||
</t>
|
||||
<a class="o_mail_action_tracking_partner"
|
||||
t-att-data-partner="recipient[0]"
|
||||
t-attf-href="#model=res.partner&id=#{recipient[0]}">
|
||||
<t t-esc="recipient[1]"/>
|
||||
<a
|
||||
class="o_mail_action_tracking_partner"
|
||||
t-att-data-partner="recipient[0]"
|
||||
t-attf-href="#model=res.partner&id=#{recipient[0]}"
|
||||
>
|
||||
<t t-esc="recipient[1]" />
|
||||
</a>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_thread_message_note small">
|
||||
<t t-raw="message.body"/>
|
||||
<t t-raw="message.body" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
Copyright 2019 Alexandre Díaz
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
|
@ -7,54 +7,57 @@
|
|||
<t t-name="mail.tracking.status">
|
||||
<t t-if="tracking['isCc']">
|
||||
<span class="mail_tracking_cc">
|
||||
<i class="fa fa-cc"></i>
|
||||
<i class="fa fa-cc" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="!tracking['isCc'] && !tracking['partner_id']">
|
||||
<span class="mail_anon_recipient">
|
||||
<i class="fa fa-low-vision"></i>
|
||||
<i class="fa fa-low-vision" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="tracking['status'] === 'unknown'">
|
||||
<span class="mail_tracking_unknown">
|
||||
<i class="fa fa-ban"></i>
|
||||
<i class="fa fa-ban" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="tracking['status'] === 'waiting'">
|
||||
<span class="mail_tracking_waiting mail_tracking_pointer">
|
||||
<i class="fa fa-clock-o"></i>
|
||||
<i class="fa fa-clock-o" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="tracking['status'] === 'error'">
|
||||
<span class="mail_tracking_error mail_tracking_pointer">
|
||||
<i t-if="tracking['error_type'] === 'no_recipient'" class="fa fa-user-times"></i>
|
||||
<i t-else="" class="fa fa-remove"></i>
|
||||
<i
|
||||
t-if="tracking['error_type'] === 'no_recipient'"
|
||||
class="fa fa-user-times"
|
||||
/>
|
||||
<i t-else="" class="fa fa-remove" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="tracking['status'] === 'sent'">
|
||||
<span class="mail_tracking_sent mail_tracking_pointer">
|
||||
<i class="fa fa-check"></i>
|
||||
<i class="fa fa-check" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="tracking['status'] === 'delivered'">
|
||||
<span class="fa-stack mail_tracking_delivered mail_tracking_pointer">
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:1px"></i>
|
||||
<i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;"></i>
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:-3px"></i>
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:1px" />
|
||||
<i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;" />
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:-3px" />
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="tracking['status'] === 'opened'">
|
||||
<span class="fa-stack mail_tracking_opened mail_tracking_pointer">
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:1px"></i>
|
||||
<i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;"></i>
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:-3px"></i>
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:1px" />
|
||||
<i class="fa fa-check fa-inverse fa-stack-1x" style="margin-left:-2px;" />
|
||||
<i class="fa fa-check fa-stack-1x" style="margin-left:-3px" />
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
<t t-extend="mail.widget.Thread.Message">
|
||||
<t t-jquery="p.o_mail_info" t-operation="after">
|
||||
<t t-if="message.hasPartnerTrackings() || message.hasEmailCc()" >
|
||||
<t t-if="message.hasPartnerTrackings() || message.hasEmailCc()">
|
||||
<p class="o_mail_tracking">
|
||||
<strong>To:</strong>
|
||||
<t t-foreach="message.getPartnerTrackings()" t-as="tracking">
|
||||
|
@ -62,21 +65,35 @@
|
|||
-
|
||||
</t>
|
||||
<t t-if="tracking['partner_id']">
|
||||
<a t-attf-class="o_mail_action_tracking_partner #{tracking['isCc'] ? 'o_mail_cc' : ''}"
|
||||
t-att-data-partner="tracking['partner_id']"
|
||||
t-attf-href="#model=res.partner&id=#{tracking['partner_id']}">
|
||||
<t t-esc="tracking['recipient']"/>
|
||||
<a
|
||||
t-attf-class="o_mail_action_tracking_partner #{tracking['isCc'] ? 'o_mail_cc' : ''}"
|
||||
t-att-data-partner="tracking['partner_id']"
|
||||
t-attf-href="#model=res.partner&id=#{tracking['partner_id']}"
|
||||
>
|
||||
<t t-esc="tracking['recipient']" />
|
||||
</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span t-attf-class="#{tracking['isCc'] ? 'o_mail_cc' : ''}"><t t-esc="tracking['recipient']"/></span>
|
||||
<span t-attf-class="#{tracking['isCc'] ? 'o_mail_cc' : ''}"><t
|
||||
t-esc="tracking['recipient']"
|
||||
/></span>
|
||||
</t>
|
||||
<t t-if="tracking['status'] === 'error' && tracking['error_type'] === 'no_recipient'" t-set="title_status" t-value="tracking['error_description']" />
|
||||
<t t-else="" t-set="title_status" t-value="tracking['status_human']" />
|
||||
<span class="mail_tracking o_mail_action_tracking_status"
|
||||
t-att-data-tracking="tracking['tracking_id']"
|
||||
t-att-title="title_status">
|
||||
<t t-call="mail.tracking.status"/>
|
||||
<t
|
||||
t-if="tracking['status'] === 'error' && tracking['error_type'] === 'no_recipient'"
|
||||
t-set="title_status"
|
||||
t-value="tracking['error_description']"
|
||||
/>
|
||||
<t
|
||||
t-else=""
|
||||
t-set="title_status"
|
||||
t-value="tracking['status_human']"
|
||||
/>
|
||||
<span
|
||||
class="mail_tracking o_mail_action_tracking_status"
|
||||
t-att-data-tracking="tracking['tracking_id']"
|
||||
t-att-title="title_status"
|
||||
>
|
||||
<t t-call="mail.tracking.status" />
|
||||
</span>
|
||||
</t>
|
||||
</p>
|
||||
|
|
|
@ -1,21 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
<template id="assets_backend"
|
||||
name="mail_tracking assets"
|
||||
inherit_id="web.assets_backend">
|
||||
<template
|
||||
id="assets_backend"
|
||||
name="mail_tracking assets"
|
||||
inherit_id="web.assets_backend"
|
||||
>
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet"
|
||||
href="/mail_tracking/static/src/css/mail_tracking.scss"/>
|
||||
<link rel="stylesheet"
|
||||
href="/mail_tracking/static/src/css/failed_message.scss"/>
|
||||
<script type="text/javascript"
|
||||
src="/mail_tracking/static/src/js/mail_tracking.js"/>
|
||||
<script type="text/javascript"
|
||||
src="/mail_tracking/static/src/js/failed_message/discuss.js"/>
|
||||
<script type="text/javascript"
|
||||
src="/mail_tracking/static/src/js/failed_message/thread.js"/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/mail_tracking/static/src/css/mail_tracking.scss"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/mail_tracking/static/src/css/failed_message.scss"
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_tracking/static/src/js/mail_tracking.js"
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_tracking/static/src/js/failed_message/discuss.js"
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mail_tracking/static/src/js/failed_message/thread.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="view_message_form">
|
||||
<field name="model">mail.message</field>
|
||||
<field name="inherit_id" ref="mail.view_message_form"/>
|
||||
<field name="inherit_id" ref="mail.view_message_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="subtype_id" position="after">
|
||||
<field name="mail_tracking_needs_action" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
@ -9,50 +9,54 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="MailTracking event" create="false" edit="false" delete="false">
|
||||
<header>
|
||||
<field name="state" widget="statusbar"/>
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="name" />
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<field name="mail_message_id"/>
|
||||
<field name="mail_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="recipient"/>
|
||||
<field name="sender"/>
|
||||
<field name="mail_message_id" />
|
||||
<field name="mail_id" />
|
||||
<field name="partner_id" />
|
||||
<field name="recipient" />
|
||||
<field name="sender" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="timestamp"/>
|
||||
<field name="time"/>
|
||||
<field name="date"/>
|
||||
<field name="timestamp" />
|
||||
<field name="time" />
|
||||
<field name="date" />
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('bounce_type', '=', False)]}">
|
||||
<field name="bounce_type"/>
|
||||
<field name="bounce_description"/>
|
||||
<field name="bounce_type" />
|
||||
<field name="bounce_description" />
|
||||
</group>
|
||||
<group attrs="{'invisible': [('error_type', '=', False)]}">
|
||||
<field name="error_smtp_server"
|
||||
attrs="{'invisible': [('error_smtp_server', '=', False)]}"/>
|
||||
<field name="error_type"/>
|
||||
<field name="error_description"/>
|
||||
<field
|
||||
name="error_smtp_server"
|
||||
attrs="{'invisible': [('error_smtp_server', '=', False)]}"
|
||||
/>
|
||||
<field name="error_type" />
|
||||
<field name="error_description" />
|
||||
</group>
|
||||
<label for="tracking_event_ids"/>
|
||||
<label for="tracking_event_ids" />
|
||||
<div>
|
||||
<field name="tracking_event_ids">
|
||||
<tree string="Tracking events"
|
||||
decoration-muted="event_type == 'deferral'"
|
||||
decoration-danger="event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject')"
|
||||
decoration-info="event_type in ('unsub', 'click', 'open')">
|
||||
<field name="time"/>
|
||||
<field name="event_type"/>
|
||||
<field name="ip"/>
|
||||
<field name="url"/>
|
||||
<field name="user_country_id" string="Country"/>
|
||||
<field name="os_family" string="OS"/>
|
||||
<field name="ua_family" string="User agent"/>
|
||||
<tree
|
||||
string="Tracking events"
|
||||
decoration-muted="event_type == 'deferral'"
|
||||
decoration-danger="event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject')"
|
||||
decoration-info="event_type in ('unsub', 'click', 'open')"
|
||||
>
|
||||
<field name="time" />
|
||||
<field name="event_type" />
|
||||
<field name="ip" />
|
||||
<field name="url" />
|
||||
<field name="user_country_id" string="Country" />
|
||||
<field name="os_family" string="OS" />
|
||||
<field name="ua_family" string="User agent" />
|
||||
</tree>
|
||||
</field>
|
||||
</div>
|
||||
|
@ -65,17 +69,22 @@
|
|||
<field name="name">mail.tracking.email.tree</field>
|
||||
<field name="model">mail.tracking.email</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="MailTracking emails" create="false" edit="false" delete="false"
|
||||
decoration-muted="state in (False, 'deferred')"
|
||||
decoration-success="state == 'opened'"
|
||||
decoration-danger="state in ('rejected', 'spam', 'bounced', 'soft-bounced', 'error')"
|
||||
decoration-info="state == 'unsub'">
|
||||
<field name="time"/>
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="sender" string="Sender"/>
|
||||
<field name="recipient" string="Recipient"/>
|
||||
<field name="state"/>
|
||||
<tree
|
||||
string="MailTracking emails"
|
||||
create="false"
|
||||
edit="false"
|
||||
delete="false"
|
||||
decoration-muted="state in (False, 'deferred')"
|
||||
decoration-success="state == 'opened'"
|
||||
decoration-danger="state in ('rejected', 'spam', 'bounced', 'soft-bounced', 'error')"
|
||||
decoration-info="state == 'unsub'"
|
||||
>
|
||||
<field name="time" />
|
||||
<field name="date" invisible="1" />
|
||||
<field name="name" />
|
||||
<field name="sender" string="Sender" />
|
||||
<field name="recipient" string="Recipient" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -85,25 +94,63 @@
|
|||
<field name="model">mail.tracking.email</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="MailTracking email search">
|
||||
<field name="display_name" string="Email"
|
||||
filter_domain="['|', ('sender', 'ilike', self), ('recipient', 'ilike', self)]"/>
|
||||
<field name="sender" string="Sender"/>
|
||||
<field name="recipient" string="Recipient"/>
|
||||
<field name="name" string="Subject"/>
|
||||
<field name="time" string="Time"/>
|
||||
<field name="date" string="Date"/>
|
||||
<filter name="sent" string="Sent" domain="[('state', 'in', ('sent',))]"/>
|
||||
<filter name="deferred" string="Deferred" domain="[('state', '=', 'deferred')]"/>
|
||||
<filter name="delivered" string="Delivered" domain="[('state', 'in', ('delivered', 'opened'))]"/>
|
||||
<filter name="unsub" string="Unsubscribed" domain="[('state', '=', 'unsub')]"/>
|
||||
<filter name="exception" string="Failed"
|
||||
domain="[('state', 'in', ('error', 'rejected', 'spam', 'bounced', 'soft-bounced'))]"/>
|
||||
<separator/>
|
||||
<field
|
||||
name="display_name"
|
||||
string="Email"
|
||||
filter_domain="['|', ('sender', 'ilike', self), ('recipient', 'ilike', self)]"
|
||||
/>
|
||||
<field name="sender" string="Sender" />
|
||||
<field name="recipient" string="Recipient" />
|
||||
<field name="name" string="Subject" />
|
||||
<field name="time" string="Time" />
|
||||
<field name="date" string="Date" />
|
||||
<filter name="sent" string="Sent" domain="[('state', 'in', ('sent',))]" />
|
||||
<filter
|
||||
name="deferred"
|
||||
string="Deferred"
|
||||
domain="[('state', '=', 'deferred')]"
|
||||
/>
|
||||
<filter
|
||||
name="delivered"
|
||||
string="Delivered"
|
||||
domain="[('state', 'in', ('delivered', 'opened'))]"
|
||||
/>
|
||||
<filter
|
||||
name="unsub"
|
||||
string="Unsubscribed"
|
||||
domain="[('state', '=', 'unsub')]"
|
||||
/>
|
||||
<filter
|
||||
name="exception"
|
||||
string="Failed"
|
||||
domain="[('state', 'in', ('error', 'rejected', 'spam', 'bounced', 'soft-bounced'))]"
|
||||
/>
|
||||
<separator />
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="State" name="group_by_state" domain="[]" context="{'group_by': 'state'}"/>
|
||||
<filter string="Subject" name="group_by_subject" domain="[]" context="{'group_by': 'name'}"/>
|
||||
<filter string="Sender" name="group_by_sender" domain="[]" context="{'group_by': 'sender'}"/>
|
||||
<filter string="Month" name="group_by_month" domain="[]" context="{'group_by': 'date'}"/>
|
||||
<filter
|
||||
string="State"
|
||||
name="group_by_state"
|
||||
domain="[]"
|
||||
context="{'group_by': 'state'}"
|
||||
/>
|
||||
<filter
|
||||
string="Subject"
|
||||
name="group_by_subject"
|
||||
domain="[]"
|
||||
context="{'group_by': 'name'}"
|
||||
/>
|
||||
<filter
|
||||
string="Sender"
|
||||
name="group_by_sender"
|
||||
domain="[]"
|
||||
context="{'group_by': 'sender'}"
|
||||
/>
|
||||
<filter
|
||||
string="Month"
|
||||
name="group_by_month"
|
||||
domain="[]"
|
||||
context="{'group_by': 'date'}"
|
||||
/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -114,12 +161,15 @@
|
|||
<field name="name">MailTracking emails</field>
|
||||
<field name="res_model">mail.tracking.email</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_mail_tracking_email_search"/>
|
||||
<field name="search_view_id" ref="view_mail_tracking_email_search" />
|
||||
</record>
|
||||
|
||||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Tracking emails" id="menu_mail_tracking_email"
|
||||
parent="base.menu_email"
|
||||
action="action_view_mail_tracking_email"/>
|
||||
<menuitem
|
||||
name="Tracking emails"
|
||||
id="menu_mail_tracking_email"
|
||||
parent="base.menu_email"
|
||||
action="action_view_mail_tracking_email"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
@ -11,40 +11,46 @@
|
|||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="tracking_email_id"/>
|
||||
<field name="recipient"/>
|
||||
<field name="event_type"/>
|
||||
<field name="tracking_email_id" />
|
||||
<field name="recipient" />
|
||||
<field name="event_type" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="timestamp"/>
|
||||
<field name="time"/>
|
||||
<field name="date"/>
|
||||
<field name="timestamp" />
|
||||
<field name="time" />
|
||||
<field name="date" />
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('event_type', 'not in', ('sent',))]}">
|
||||
<field name="smtp_server"/>
|
||||
<field name="smtp_server" />
|
||||
</group>
|
||||
<group attrs="{'invisible': [('event_type', 'not in', ('open', 'click'))]}">
|
||||
<field name="url"/>
|
||||
<group
|
||||
attrs="{'invisible': [('event_type', 'not in', ('open', 'click'))]}"
|
||||
>
|
||||
<field name="url" />
|
||||
</group>
|
||||
<group attrs="{'invisible': [('event_type', 'not in', ('open', 'click'))]}">
|
||||
<group
|
||||
attrs="{'invisible': [('event_type', 'not in', ('open', 'click'))]}"
|
||||
>
|
||||
<group>
|
||||
<field name="mobile"/>
|
||||
<field name="ip"/>
|
||||
<field name="user_country_id"/>
|
||||
<field name="mobile" />
|
||||
<field name="ip" />
|
||||
<field name="user_country_id" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_agent"/>
|
||||
<field name="ua_family"/>
|
||||
<field name="ua_type"/>
|
||||
<field name="os_family"/>
|
||||
<field name="user_agent" />
|
||||
<field name="ua_family" />
|
||||
<field name="ua_type" />
|
||||
<field name="os_family" />
|
||||
</group>
|
||||
</group>
|
||||
<group string="Error"
|
||||
attrs="{'invisible': [('error_type', '=', False)]}">
|
||||
<field name="error_type"/>
|
||||
<field name="error_description"/>
|
||||
<field name="error_details"/>
|
||||
<group
|
||||
string="Error"
|
||||
attrs="{'invisible': [('error_type', '=', False)]}"
|
||||
>
|
||||
<field name="error_type" />
|
||||
<field name="error_description" />
|
||||
<field name="error_details" />
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
|
@ -55,21 +61,29 @@
|
|||
<field name="name">mail.tracking.event.tree</field>
|
||||
<field name="model">mail.tracking.event</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="MailTracking events" create="false" edit="false" delete="false"
|
||||
decoration-muted="event_type == 'deferred'"
|
||||
decoration-danger="event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject')"
|
||||
decoration-info="event_type in ('unsub', 'click', 'open')">
|
||||
<field name="time"/>
|
||||
<field name="tracking_email_id"/>
|
||||
<field name="recipient"/>
|
||||
<field name="event_type"/>
|
||||
<field name="error_details" invisible="not context.get('event_error_filter', False)"/>
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="ip"/>
|
||||
<field name="url"/>
|
||||
<field name="user_country_id" string="Country"/>
|
||||
<field name="os_family" string="OS"/>
|
||||
<field name="ua_family" string="User agent"/>
|
||||
<tree
|
||||
string="MailTracking events"
|
||||
create="false"
|
||||
edit="false"
|
||||
delete="false"
|
||||
decoration-muted="event_type == 'deferred'"
|
||||
decoration-danger="event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject')"
|
||||
decoration-info="event_type in ('unsub', 'click', 'open')"
|
||||
>
|
||||
<field name="time" />
|
||||
<field name="tracking_email_id" />
|
||||
<field name="recipient" />
|
||||
<field name="event_type" />
|
||||
<field
|
||||
name="error_details"
|
||||
invisible="not context.get('event_error_filter', False)"
|
||||
/>
|
||||
<field name="date" invisible="1" />
|
||||
<field name="ip" />
|
||||
<field name="url" />
|
||||
<field name="user_country_id" string="Country" />
|
||||
<field name="os_family" string="OS" />
|
||||
<field name="ua_family" string="User agent" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -79,32 +93,88 @@
|
|||
<field name="model">mail.tracking.event</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="MailTracking event search">
|
||||
<field name="tracking_email_id" string="Message"
|
||||
filter_domain="[('tracking_email_id', 'ilike', self)]"/>
|
||||
<field name="recipient" string="Recipient"/>
|
||||
<field name="time" string="Time"/>
|
||||
<field name="date" string="Date"/>
|
||||
<field name="ip" string="IP"/>
|
||||
<field name="url" string="URL"/>
|
||||
<filter name="sent" string="Sent" domain="[('event_type', '=', 'sent')]"/>
|
||||
<filter name="delivered" string="Delivered" domain="[('event_type', '=', 'delivered')]"/>
|
||||
<filter name="click" string="Click" domain="[('event_type', '=', 'click')]"/>
|
||||
<filter name="open" string="Open" domain="[('event_type', '=', 'open')]"/>
|
||||
<filter name="unsub" string="Unsubscribe" domain="[('event_type', '=', 'unsub')]"/>
|
||||
<filter name="bounce" string="Bounce"
|
||||
domain="[('event_type', 'in', ('hard_bounce', 'soft_bounce'))]"/>
|
||||
<filter name="exception" string="Failed"
|
||||
<field
|
||||
name="tracking_email_id"
|
||||
string="Message"
|
||||
filter_domain="[('tracking_email_id', 'ilike', self)]"
|
||||
/>
|
||||
<field name="recipient" string="Recipient" />
|
||||
<field name="time" string="Time" />
|
||||
<field name="date" string="Date" />
|
||||
<field name="ip" string="IP" />
|
||||
<field name="url" string="URL" />
|
||||
<filter name="sent" string="Sent" domain="[('event_type', '=', 'sent')]" />
|
||||
<filter
|
||||
name="delivered"
|
||||
string="Delivered"
|
||||
domain="[('event_type', '=', 'delivered')]"
|
||||
/>
|
||||
<filter
|
||||
name="click"
|
||||
string="Click"
|
||||
domain="[('event_type', '=', 'click')]"
|
||||
/>
|
||||
<filter name="open" string="Open" domain="[('event_type', '=', 'open')]" />
|
||||
<filter
|
||||
name="unsub"
|
||||
string="Unsubscribe"
|
||||
domain="[('event_type', '=', 'unsub')]"
|
||||
/>
|
||||
<filter
|
||||
name="bounce"
|
||||
string="Bounce"
|
||||
domain="[('event_type', 'in', ('hard_bounce', 'soft_bounce'))]"
|
||||
/>
|
||||
<filter
|
||||
name="exception"
|
||||
string="Failed"
|
||||
domain="[('event_type', 'in', ('reject', 'spam'))]"
|
||||
context="{'event_error_filter': True}"/>
|
||||
<separator/>
|
||||
context="{'event_error_filter': True}"
|
||||
/>
|
||||
<separator />
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Type" name="group_by_type" domain="[]" context="{'group_by': 'event_type'}"/>
|
||||
<filter string="Message" name="group_by_message" domain="[]" context="{'group_by': 'tracking_email_id'}"/>
|
||||
<filter string="OS" name="group_by_os" domain="[('os_family', '!=', False)]" context="{'group_by': 'os_family'}"/>
|
||||
<filter string="User agent" name="group_by_user_agent" domain="[('ua_family', '!=', False)]" context="{'group_by': 'ua_family'}"/>
|
||||
<filter string="User agent type" name="group_by_user_agent_type" domain="[('ua_type', '!=', False)]" context="{'group_by': 'ua_type'}"/>
|
||||
<filter string="Country" name="group_by_country" domain="[('user_country_id', '!=', False)]" context="{'group_by': 'user_country_id'}"/>
|
||||
<filter string="Month" name="group_by_date" domain="[]" context="{'group_by': 'date'}"/>
|
||||
<filter
|
||||
string="Type"
|
||||
name="group_by_type"
|
||||
domain="[]"
|
||||
context="{'group_by': 'event_type'}"
|
||||
/>
|
||||
<filter
|
||||
string="Message"
|
||||
name="group_by_message"
|
||||
domain="[]"
|
||||
context="{'group_by': 'tracking_email_id'}"
|
||||
/>
|
||||
<filter
|
||||
string="OS"
|
||||
name="group_by_os"
|
||||
domain="[('os_family', '!=', False)]"
|
||||
context="{'group_by': 'os_family'}"
|
||||
/>
|
||||
<filter
|
||||
string="User agent"
|
||||
name="group_by_user_agent"
|
||||
domain="[('ua_family', '!=', False)]"
|
||||
context="{'group_by': 'ua_family'}"
|
||||
/>
|
||||
<filter
|
||||
string="User agent type"
|
||||
name="group_by_user_agent_type"
|
||||
domain="[('ua_type', '!=', False)]"
|
||||
context="{'group_by': 'ua_type'}"
|
||||
/>
|
||||
<filter
|
||||
string="Country"
|
||||
name="group_by_country"
|
||||
domain="[('user_country_id', '!=', False)]"
|
||||
context="{'group_by': 'user_country_id'}"
|
||||
/>
|
||||
<filter
|
||||
string="Month"
|
||||
name="group_by_date"
|
||||
domain="[]"
|
||||
context="{'group_by': 'date'}"
|
||||
/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -114,13 +184,16 @@
|
|||
<field name="name">MailTracking events</field>
|
||||
<field name="res_model">mail.tracking.event</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_mail_tracking_event_search"/>
|
||||
<field name="search_view_id" ref="view_mail_tracking_event_search" />
|
||||
</record>
|
||||
|
||||
<!-- Add menu entry in Settings/Email -->
|
||||
<menuitem name="Tracking events" id="menu_mail_tracking_event"
|
||||
parent="base.menu_email"
|
||||
action="action_view_mail_tracking_event"/>
|
||||
<menuitem
|
||||
name="Tracking events"
|
||||
id="menu_mail_tracking_event"
|
||||
parent="base.menu_email"
|
||||
action="action_view_mail_tracking_event"
|
||||
/>
|
||||
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
<odoo>
|
||||
|
@ -7,26 +7,32 @@
|
|||
<field name="name">Partner Form with tracking emails</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="priority">46</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||
<field name="inherit_id" ref="base.view_partner_form" />
|
||||
<field name="arch" type="xml">
|
||||
<div name="button_box" position="inside">
|
||||
<button name="%(mail_tracking.action_view_mail_tracking_email)d"
|
||||
<button
|
||||
name="%(mail_tracking.action_view_mail_tracking_email)d"
|
||||
context="{'search_default_recipient': email,
|
||||
'default_recipient': email}"
|
||||
type="action"
|
||||
class="oe_stat_button"
|
||||
icon="fa-envelope-o"
|
||||
attrs="{'invisible': [('email', '=', False)]}">
|
||||
<field name="tracking_emails_count"
|
||||
widget="statinfo"
|
||||
string="Tracking emails"/>
|
||||
attrs="{'invisible': [('email', '=', False)]}"
|
||||
>
|
||||
<field
|
||||
name="tracking_emails_count"
|
||||
widget="statinfo"
|
||||
string="Tracking emails"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<xpath expr="//field[@name='email']/.." position="after">
|
||||
<field name="email_score" widget="progressbar"
|
||||
attrs="{'invisible': [('email', '=', False)]}"/>
|
||||
<field name="email_bounced"
|
||||
attrs="{'invisible': [('email', '=', False)]}"/>
|
||||
<field
|
||||
name="email_score"
|
||||
widget="progressbar"
|
||||
attrs="{'invisible': [('email', '=', False)]}"
|
||||
/>
|
||||
<field name="email_bounced" attrs="{'invisible': [('email', '=', False)]}" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -34,12 +40,15 @@
|
|||
<record model="ir.ui.view" id="view_res_partner_filter">
|
||||
<field name="name">Filter bounced partners</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_res_partner_filter"/>
|
||||
<field name="inherit_id" ref="base.view_res_partner_filter" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="type_company" position="after">
|
||||
<separator/>
|
||||
<filter string="Email bounced" name="email_bounced"
|
||||
domain="[('email', '!=' , False), ('email_bounced', '=', True)]"/>
|
||||
<separator />
|
||||
<filter
|
||||
string="Email bounced"
|
||||
name="email_bounced"
|
||||
domain="[('email', '!=' , False), ('email_bounced', '=', True)]"
|
||||
/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="mailgun_manual_check" model="ir.ui.view">
|
||||
<field name="name">Manual Mailgun check</field>
|
||||
<field name="model">mail.tracking.email</field>
|
||||
<field name="inherit_id" ref="mail_tracking.view_mail_tracking_email_form"/>
|
||||
<field name="inherit_id" ref="mail_tracking.view_mail_tracking_email_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="state" position="before">
|
||||
<button name="action_manual_check_mailgun"
|
||||
type="object" string="Re-sync Mailgun"/>
|
||||
<button
|
||||
name="action_manual_check_mailgun"
|
||||
type="object"
|
||||
string="Re-sync Mailgun"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Tecnativa - Pedro M. Baeza
|
||||
Copyright 2016 Carlos Dauden - Tecnativa <carlos.dauden@tecnativa.com>
|
||||
Copyright 2017 Tecnativa <vicent.cubellsn@tecnativa.com>
|
||||
|
@ -8,18 +8,44 @@
|
|||
<record id="view_partner_form_mailgun" model="ir.ui.view">
|
||||
<field name="name">Partner Mailgun button</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="mail_tracking.view_partner_form"/>
|
||||
<field name="inherit_id" ref="mail_tracking.view_partner_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="email_bounced" position="after">
|
||||
<label for="check_email_bounced" string="Mailgun"
|
||||
attrs="{'invisible': [('email', '=', False)]}"/>
|
||||
<div name="mailgun_buttons" attrs="{'invisible': [('email', '=', False)]}">
|
||||
<button name="check_email_bounced" type="object" string="Check Mailgun" class="oe_link"/>
|
||||
<button name="check_email_validity" type="object" string="Check email validity" class="oe_link"/>
|
||||
<button name="force_set_bounced" type="object" string="Set Bounced" class="oe_link"
|
||||
attrs="{'invisible': [('email_bounced', '=', True)]}"/>
|
||||
<button name="force_unset_bounced" type="object" string="Unset Bounced" class="oe_link"
|
||||
attrs="{'invisible': [('email_bounced', '=', False)]}"/>
|
||||
<label
|
||||
for="check_email_bounced"
|
||||
string="Mailgun"
|
||||
attrs="{'invisible': [('email', '=', False)]}"
|
||||
/>
|
||||
<div
|
||||
name="mailgun_buttons"
|
||||
attrs="{'invisible': [('email', '=', False)]}"
|
||||
>
|
||||
<button
|
||||
name="check_email_bounced"
|
||||
type="object"
|
||||
string="Check Mailgun"
|
||||
class="oe_link"
|
||||
/>
|
||||
<button
|
||||
name="check_email_validity"
|
||||
type="object"
|
||||
string="Check email validity"
|
||||
class="oe_link"
|
||||
/>
|
||||
<button
|
||||
name="force_set_bounced"
|
||||
type="object"
|
||||
string="Set Bounced"
|
||||
class="oe_link"
|
||||
attrs="{'invisible': [('email_bounced', '=', True)]}"
|
||||
/>
|
||||
<button
|
||||
name="force_unset_bounced"
|
||||
type="object"
|
||||
string="Unset Bounced"
|
||||
class="oe_link"
|
||||
attrs="{'invisible': [('email_bounced', '=', False)]}"
|
||||
/>
|
||||
</div>
|
||||
</field>
|
||||
</field>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
Copyright 2017 David Vidal - <david.vidal@tecnativa.com>
|
||||
|
@ -19,15 +19,27 @@
|
|||
<field name="domain">[('mass_mailing_id', '!=', False)]</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Mail tracking" id="mail_tracking_menu"
|
||||
parent="mass_mailing.mass_mailing_menu_root" sequence="50"/>
|
||||
<menuitem
|
||||
name="Mail tracking"
|
||||
id="mail_tracking_menu"
|
||||
parent="mass_mailing.mass_mailing_menu_root"
|
||||
sequence="50"
|
||||
/>
|
||||
|
||||
<menuitem name="Emails" id="mail_tracking_email_menu"
|
||||
parent="mail_tracking_menu" sequence="1"
|
||||
action="action_view_mail_tracking_email"/>
|
||||
<menuitem
|
||||
name="Emails"
|
||||
id="mail_tracking_email_menu"
|
||||
parent="mail_tracking_menu"
|
||||
sequence="1"
|
||||
action="action_view_mail_tracking_email"
|
||||
/>
|
||||
|
||||
<menuitem name="Events" id="mail_tracking_event_menu"
|
||||
parent="mail_tracking_menu" sequence="2"
|
||||
action="action_view_mail_tracking_event"/>
|
||||
<menuitem
|
||||
name="Events"
|
||||
id="mail_tracking_event_menu"
|
||||
parent="mail_tracking_menu"
|
||||
sequence="2"
|
||||
action="action_view_mail_tracking_event"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
|
@ -7,23 +7,26 @@
|
|||
<record model="ir.ui.view" id="mailing_trace_view_form">
|
||||
<field name="name">Add tracking email info</field>
|
||||
<field name="model">mailing.trace</field>
|
||||
<field name="inherit_id" ref="mass_mailing.mailing_trace_view_form"/>
|
||||
<field name="inherit_id" ref="mass_mailing.mailing_trace_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//form/sheet" position="inside">
|
||||
<group>
|
||||
<field name="mail_tracking_id" />
|
||||
</group>
|
||||
<label for="tracking_event_ids"/>
|
||||
<label for="tracking_event_ids" />
|
||||
<div>
|
||||
<field name="tracking_event_ids">
|
||||
<tree string="Tracking events" colors="grey:event_type in ('deferral');black:event_type in ('send');red:event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject');blue:event_type in ('unsub', 'click', 'open')">
|
||||
<field name="time"/>
|
||||
<field name="event_type"/>
|
||||
<field name="ip"/>
|
||||
<field name="url"/>
|
||||
<field name="user_country_id" string="Country"/>
|
||||
<field name="os_family" string="OS"/>
|
||||
<field name="ua_family" string="User agent"/>
|
||||
<tree
|
||||
string="Tracking events"
|
||||
colors="grey:event_type in ('deferral');black:event_type in ('send');red:event_type in ('hard_bounce', 'soft_bounce', 'spam', 'reject');blue:event_type in ('unsub', 'click', 'open')"
|
||||
>
|
||||
<field name="time" />
|
||||
<field name="event_type" />
|
||||
<field name="ip" />
|
||||
<field name="url" />
|
||||
<field name="user_country_id" string="Country" />
|
||||
<field name="os_family" string="OS" />
|
||||
<field name="ua_family" string="User agent" />
|
||||
</tree>
|
||||
</field>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
|
@ -7,11 +7,11 @@
|
|||
<record model="ir.ui.view" id="view_mail_tracking_email_form">
|
||||
<field name="name">Add mass mailing and mail stadistics</field>
|
||||
<field name="model">mail.tracking.email</field>
|
||||
<field name="inherit_id" ref="mail_tracking.view_mail_tracking_email_form"/>
|
||||
<field name="inherit_id" ref="mail_tracking.view_mail_tracking_email_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="date" position="after">
|
||||
<field name="mass_mailing_id"/>
|
||||
<field name="mail_stats_id"/>
|
||||
<field name="mass_mailing_id" />
|
||||
<field name="mail_stats_id" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||
Copyright 2017 Vicent Cubells - <vicent.cubells@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||
|
@ -7,11 +7,11 @@
|
|||
<record model="ir.ui.view" id="view_mail_mass_mailing_contact_tree">
|
||||
<field name="name">Add email score and stars</field>
|
||||
<field name="model">mailing.contact</field>
|
||||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_tree"/>
|
||||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="is_blacklisted" position="after">
|
||||
<field name="email_bounced"/>
|
||||
<field name="email_score" widget="progressbar"/>
|
||||
<field name="email_bounced" />
|
||||
<field name="email_score" widget="progressbar" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -19,11 +19,14 @@
|
|||
<record model="ir.ui.view" id="view_mail_mass_mailing_contact_search">
|
||||
<field name="name">Filter bounced contacts</field>
|
||||
<field name="model">mailing.contact</field>
|
||||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_search"/>
|
||||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_search" />
|
||||
<field name="arch" type="xml">
|
||||
<filter name="filter_not_email_bl" position="after">
|
||||
<filter string="Email bounced" name="email_bounced"
|
||||
domain="[('email_bounced', '=', True)]"/>
|
||||
<filter
|
||||
string="Email bounced"
|
||||
name="email_bounced"
|
||||
domain="[('email_bounced', '=', True)]"
|
||||
/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,39 +1,38 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- © 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="reason_not_interested"
|
||||
model="mail.unsubscription.reason"
|
||||
forcecreate="False">
|
||||
<record
|
||||
id="reason_not_interested"
|
||||
model="mail.unsubscription.reason"
|
||||
forcecreate="False"
|
||||
>
|
||||
<field name="name">I'm not interested</field>
|
||||
<field name="sequence">10</field>
|
||||
<field name="details_required" eval="False"/>
|
||||
<field name="details_required" eval="False" />
|
||||
</record>
|
||||
|
||||
<record id="reason_not_requested"
|
||||
model="mail.unsubscription.reason"
|
||||
forcecreate="False">
|
||||
<record
|
||||
id="reason_not_requested"
|
||||
model="mail.unsubscription.reason"
|
||||
forcecreate="False"
|
||||
>
|
||||
<field name="name">I did not request this</field>
|
||||
<field name="sequence">20</field>
|
||||
<field name="details_required" eval="False"/>
|
||||
<field name="details_required" eval="False" />
|
||||
</record>
|
||||
|
||||
<record id="reason_too_many"
|
||||
model="mail.unsubscription.reason"
|
||||
forcecreate="False">
|
||||
<record id="reason_too_many" model="mail.unsubscription.reason" forcecreate="False">
|
||||
<field name="name">I get too many emails</field>
|
||||
<field name="sequence">30</field>
|
||||
<field name="details_required" eval="False"/>
|
||||
<field name="details_required" eval="False" />
|
||||
</record>
|
||||
|
||||
<record id="reason_other"
|
||||
model="mail.unsubscription.reason"
|
||||
forcecreate="False">
|
||||
<record id="reason_other" model="mail.unsubscription.reason" forcecreate="False">
|
||||
<field name="name">Other reason</field>
|
||||
<field name="sequence">100</field>
|
||||
<field name="details_required" eval="True"/>
|
||||
<field name="details_required" eval="True" />
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<template id="assets_frontend_demo"
|
||||
inherit_id="web.assets_frontend">
|
||||
<template id="assets_frontend_demo" inherit_id="web.assets_frontend">
|
||||
<xpath expr=".">
|
||||
<script type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe/static/src/js/contact.tour.js"/>
|
||||
<script type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe/static/src/js/partner.tour.js"/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe/static/src/js/contact.tour.js"
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe/static/src/js/partner.tour.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!--This is set here to make tours work-->
|
||||
<template id="mass_mailing_custom_unsubscribe.layout"
|
||||
inherit_id="mass_mailing.layout">
|
||||
<template id="mass_mailing_custom_unsubscribe.layout" inherit_id="mass_mailing.layout">
|
||||
<xpath expr="//t[@t-set='head']" position="inside">
|
||||
<t t-call-assets="web_editor.assets_wysiwyg"/>
|
||||
<t t-call-assets="web.assets_frontend"/>
|
||||
<t t-call-assets="web_editor.assets_wysiwyg" />
|
||||
<t t-call-assets="web.assets_frontend" />
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,102 +1,100 @@
|
|||
/* Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
odoo.define("mass_mailing_custom_unsubscribe.contact_tour",
|
||||
function (require) {
|
||||
"use strict";
|
||||
var base = require("web_editor.base");
|
||||
var tour = require("web_tour.tour");
|
||||
odoo.define("mass_mailing_custom_unsubscribe.contact_tour", function(require) {
|
||||
"use strict";
|
||||
var base = require("web_editor.base");
|
||||
var tour = require("web_tour.tour");
|
||||
|
||||
// Allow to know if an element is required
|
||||
$.extend($.expr[':'], {
|
||||
propRequired: function (element) {
|
||||
return $(element).prop("required");
|
||||
},
|
||||
});
|
||||
// Allow to know if an element is required
|
||||
$.extend($.expr[":"], {
|
||||
propRequired: function(element) {
|
||||
return $(element).prop("required");
|
||||
},
|
||||
});
|
||||
|
||||
tour.register(
|
||||
"mass_mailing_custom_unsubscribe_tour_contact",
|
||||
tour.register(
|
||||
"mass_mailing_custom_unsubscribe_tour_contact",
|
||||
{
|
||||
test: true,
|
||||
wait_for: base.ready(),
|
||||
},
|
||||
[
|
||||
{
|
||||
test: true,
|
||||
wait_for: base.ready(),
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio:not(:checked)",
|
||||
extra_trigger: "#reason_form #custom_div_feedback",
|
||||
},
|
||||
[
|
||||
{
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio:not(:checked)",
|
||||
extra_trigger: "#reason_form #custom_div_feedback",
|
||||
},
|
||||
{
|
||||
content: "Switch to not interested reason",
|
||||
trigger:
|
||||
".radio:contains(\"I'm not interested\") :radio:not(:checked)",
|
||||
extra_trigger: "[name='details']:propRequired",
|
||||
},
|
||||
{
|
||||
content: "Unsubscribe",
|
||||
trigger: "#reason_form button:submit",
|
||||
extra_trigger: "body:not(:has([name='details']:propRequired))",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger: "body:not(:has(#reason_form)) #subscription_info " +
|
||||
":contains('successfully unsubscribed from')",
|
||||
},
|
||||
{
|
||||
content: "Unsubscription reasons are invisible",
|
||||
trigger: "#unsubscribe_form:has(#custom_div_feedback:hidden)",
|
||||
},
|
||||
{
|
||||
content: "List 2 is not cross unsubscriptable",
|
||||
trigger: "body:not(:has(li:contains('test list 2')))",
|
||||
},
|
||||
{
|
||||
content: "List 3 is not public",
|
||||
trigger: "body:not(:has(li:contains('test list 3')))",
|
||||
},
|
||||
{
|
||||
content: "Uncheck list 1",
|
||||
trigger: "li:contains('test list 1') input:checked",
|
||||
},
|
||||
{
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio",
|
||||
extra_trigger: ".radio:contains('Other reason') " +
|
||||
":radio:not(:checked)",
|
||||
},
|
||||
{
|
||||
content: "Add details to reason",
|
||||
trigger: "[name='details']:visible:propRequired",
|
||||
run: "text I want to unsubscribe because I want. Period.",
|
||||
extra_trigger: ".radio:contains('Other reason') :radio:checked",
|
||||
},
|
||||
{
|
||||
content: "Update subscriptions 2nd time",
|
||||
trigger: "#unsubscribe_form :submit",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger:
|
||||
"#subscription_info:contains('Your changes have been saved.')",
|
||||
},
|
||||
{
|
||||
content: "Subscribe again to list 0",
|
||||
// eslint-disable-next-line no-multi-str
|
||||
trigger:"body:not(:has(#unsubscribe_form #custom_div_feedback\
|
||||
{
|
||||
content: "Switch to not interested reason",
|
||||
trigger: '.radio:contains("I\'m not interested") :radio:not(:checked)',
|
||||
extra_trigger: "[name='details']:propRequired",
|
||||
},
|
||||
{
|
||||
content: "Unsubscribe",
|
||||
trigger: "#reason_form button:submit",
|
||||
extra_trigger: "body:not(:has([name='details']:propRequired))",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger:
|
||||
"body:not(:has(#reason_form)) #subscription_info " +
|
||||
":contains('successfully unsubscribed from')",
|
||||
},
|
||||
{
|
||||
content: "Unsubscription reasons are invisible",
|
||||
trigger: "#unsubscribe_form:has(#custom_div_feedback:hidden)",
|
||||
},
|
||||
{
|
||||
content: "List 2 is not cross unsubscriptable",
|
||||
trigger: "body:not(:has(li:contains('test list 2')))",
|
||||
},
|
||||
{
|
||||
content: "List 3 is not public",
|
||||
trigger: "body:not(:has(li:contains('test list 3')))",
|
||||
},
|
||||
{
|
||||
content: "Uncheck list 1",
|
||||
trigger: "li:contains('test list 1') input:checked",
|
||||
},
|
||||
{
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio",
|
||||
extra_trigger:
|
||||
".radio:contains('Other reason') " + ":radio:not(:checked)",
|
||||
},
|
||||
{
|
||||
content: "Add details to reason",
|
||||
trigger: "[name='details']:visible:propRequired",
|
||||
run: "text I want to unsubscribe because I want. Period.",
|
||||
extra_trigger: ".radio:contains('Other reason') :radio:checked",
|
||||
},
|
||||
{
|
||||
content: "Update subscriptions 2nd time",
|
||||
trigger: "#unsubscribe_form :submit",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger: "#subscription_info:contains('Your changes have been saved.')",
|
||||
},
|
||||
{
|
||||
content: "Subscribe again to list 0",
|
||||
// eslint-disable-next-line no-multi-str
|
||||
trigger:
|
||||
"body:not(:has(#unsubscribe_form #custom_div_feedback\
|
||||
:visible)):has(.alert-success) li:contains('test list 0') \
|
||||
input:not(:checked)",
|
||||
},
|
||||
{
|
||||
content: "Update subscriptions 3nd time",
|
||||
// eslint-disable-next-line no-multi-str
|
||||
trigger:"#unsubscribe_form:not(\
|
||||
},
|
||||
{
|
||||
content: "Update subscriptions 3nd time",
|
||||
// eslint-disable-next-line no-multi-str
|
||||
trigger:
|
||||
"#unsubscribe_form:not(\
|
||||
:has(.js_unsubscription_reason:visible)) :submit",
|
||||
},
|
||||
{
|
||||
content: "Successfully subscribed",
|
||||
trigger:
|
||||
"#subscription_info:contains('Your changes have been saved.')",
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
{
|
||||
content: "Successfully subscribed",
|
||||
trigger: "#subscription_info:contains('Your changes have been saved.')",
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
/* Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
odoo.define("mass_mailing_custom_unsubscribe.partner_tour",
|
||||
function (require) {
|
||||
"use strict";
|
||||
var base = require("web_editor.base");
|
||||
var tour = require("web_tour.tour");
|
||||
odoo.define("mass_mailing_custom_unsubscribe.partner_tour", function(require) {
|
||||
"use strict";
|
||||
var base = require("web_editor.base");
|
||||
var tour = require("web_tour.tour");
|
||||
|
||||
// Allow to know if an element is required
|
||||
$.extend($.expr[':'], {
|
||||
propRequired: function (element) {
|
||||
return $(element).prop("required");
|
||||
},
|
||||
});
|
||||
// Allow to know if an element is required
|
||||
$.extend($.expr[":"], {
|
||||
propRequired: function(element) {
|
||||
return $(element).prop("required");
|
||||
},
|
||||
});
|
||||
|
||||
tour.register(
|
||||
"mass_mailing_custom_unsubscribe_tour_partner",
|
||||
tour.register(
|
||||
"mass_mailing_custom_unsubscribe_tour_partner",
|
||||
{
|
||||
tour: true,
|
||||
wait_for: base.ready(),
|
||||
},
|
||||
[
|
||||
{
|
||||
tour: true,
|
||||
wait_for: base.ready(),
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio:not(:checked)",
|
||||
extra_trigger: "#reason_form #custom_div_feedback",
|
||||
},
|
||||
[
|
||||
{
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio:not(:checked)",
|
||||
extra_trigger: "#reason_form #custom_div_feedback",
|
||||
},
|
||||
{
|
||||
content: "Switch to not interested reason",
|
||||
// eslint-disable-next-line no-multi-str
|
||||
trigger: ".radio:contains(\"I'm not interested\") \
|
||||
:radio:not(:checked)",
|
||||
extra_trigger: "[name='details']:propRequired",
|
||||
},
|
||||
{
|
||||
content: "Unsubscribe",
|
||||
trigger: "#reason_form button:submit",
|
||||
extra_trigger: "body:not(:has([name='details']:propRequired))",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger: "body:not(:has(#reason_form)) #subscription_info " +
|
||||
":contains('successfully unsubscribed')",
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
{
|
||||
content: "Switch to not interested reason",
|
||||
// eslint-disable-next-line no-multi-str
|
||||
trigger:
|
||||
'.radio:contains("I\'m not interested") \
|
||||
:radio:not(:checked)',
|
||||
extra_trigger: "[name='details']:propRequired",
|
||||
},
|
||||
{
|
||||
content: "Unsubscribe",
|
||||
trigger: "#reason_form button:submit",
|
||||
extra_trigger: "body:not(:has([name='details']:propRequired))",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger:
|
||||
"body:not(:has(#reason_form)) #subscription_info " +
|
||||
":contains('successfully unsubscribed')",
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,30 +5,30 @@
|
|||
* to extend it as it is currently designed. It is almost a copy+paste from
|
||||
* upstream, to allow easier version/patch updates, so linter is disabled. */
|
||||
/* eslint-disable */
|
||||
odoo.define('mass_mailing_custom_unsubscribe.unsubscribe', function (require) {
|
||||
'use strict';
|
||||
odoo.define("mass_mailing_custom_unsubscribe.unsubscribe", function(require) {
|
||||
"use strict";
|
||||
|
||||
var ajax = require('web.ajax');
|
||||
var core = require('web.core');
|
||||
require('web.dom_ready');
|
||||
var ajax = require("web.ajax");
|
||||
var core = require("web.core");
|
||||
require("web.dom_ready");
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
if (!$('.o_unsubscribe_form').length) {
|
||||
if (!$(".o_unsubscribe_form").length) {
|
||||
return $.Deferred().reject("DOM doesn't contain '.o_unsubscribe_form'");
|
||||
}
|
||||
|
||||
var email = $("input[name='email']").val();
|
||||
var mailing_id = parseInt($("input[name='mailing_id']").val(), 10);
|
||||
var res_id = parseInt($("input[name='res_id']").val(), 10);
|
||||
var token = (location.search.split('token' + '=')[1] || '').split('&')[0];
|
||||
var token = (location.search.split("token" + "=")[1] || "").split("&")[0];
|
||||
var $mailing_lists = $("input[name='contact_ids']");
|
||||
var $reasons = $("#custom_div_feedback");
|
||||
var $details = $("textarea[name='details']");
|
||||
var $radio = $(":radio");
|
||||
var $info_state = $("#info_state, #custom_div_feedback");
|
||||
|
||||
$radio.on('change click', function (e) {
|
||||
$radio.on("change click", function(e) {
|
||||
$details.prop(
|
||||
"required",
|
||||
$(e.target).is("[data-details-required]") && $(e.target).is(":visible")
|
||||
|
@ -36,9 +36,9 @@ odoo.define('mass_mailing_custom_unsubscribe.unsubscribe', function (require) {
|
|||
});
|
||||
|
||||
// Display reasons form only if there are unsubscriptions
|
||||
var toggle_reasons = function () {
|
||||
var toggle_reasons = function() {
|
||||
// Find contacts that were checked and now are unchecked
|
||||
var $disabled = $mailing_lists.filter(function () {
|
||||
var $disabled = $mailing_lists.filter(function() {
|
||||
var $this = $(this);
|
||||
return !$this.prop("checked") && $this.attr("checked");
|
||||
});
|
||||
|
@ -47,11 +47,12 @@ odoo.define('mass_mailing_custom_unsubscribe.unsubscribe', function (require) {
|
|||
var $radios = $reasons.find(":radio");
|
||||
if ($reasons.is(":hidden")) {
|
||||
// Uncheck chosen reason
|
||||
$radios.prop("checked", false)
|
||||
// Unrequire specifying a reason
|
||||
.prop("required", false)
|
||||
// Remove possible constraints for details
|
||||
.trigger("change");
|
||||
$radios
|
||||
.prop("checked", false)
|
||||
// Unrequire specifying a reason
|
||||
.prop("required", false)
|
||||
// Remove possible constraints for details
|
||||
.trigger("change");
|
||||
// Clear textarea
|
||||
$details.val("");
|
||||
} else {
|
||||
|
@ -60,76 +61,87 @@ odoo.define('mass_mailing_custom_unsubscribe.unsubscribe', function (require) {
|
|||
}
|
||||
};
|
||||
|
||||
$mailing_lists.change(function (e) {
|
||||
$mailing_lists.change(function(e) {
|
||||
toggle_reasons();
|
||||
$('#info_state').addClass('invisible');
|
||||
$("#info_state").addClass("invisible");
|
||||
});
|
||||
|
||||
if (email != '' && email != undefined) {
|
||||
ajax.jsonRpc('/mailing/blacklist/check', 'call', {
|
||||
'email': email,
|
||||
'mailing_id': mailing_id,
|
||||
'res_id': res_id,
|
||||
'token': token
|
||||
if (email != "" && email != undefined) {
|
||||
ajax.jsonRpc("/mailing/blacklist/check", "call", {
|
||||
email: email,
|
||||
mailing_id: mailing_id,
|
||||
res_id: res_id,
|
||||
token: token,
|
||||
})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized') {
|
||||
$('#button_add_blacklist').hide();
|
||||
$('#button_remove_blacklist').hide();
|
||||
}
|
||||
else if (result == true) {
|
||||
$('#button_remove_blacklist').show();
|
||||
.then(function(result) {
|
||||
if (result == "unauthorized") {
|
||||
$("#button_add_blacklist").hide();
|
||||
$("#button_remove_blacklist").hide();
|
||||
} else if (result == true) {
|
||||
$("#button_remove_blacklist").show();
|
||||
toggle_opt_out_section(false);
|
||||
}
|
||||
else if (result == false) {
|
||||
$('#button_add_blacklist').show();
|
||||
} else if (result == false) {
|
||||
$("#button_add_blacklist").show();
|
||||
toggle_opt_out_section(true);
|
||||
}
|
||||
else {
|
||||
$('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
|
||||
} else {
|
||||
$("#subscription_info").html(
|
||||
_t("An error occured. Please try again later or contact us.")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-warning")
|
||||
.addClass("alert-error");
|
||||
}
|
||||
})
|
||||
.guardedCatch(function () {
|
||||
$('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
|
||||
.guardedCatch(function() {
|
||||
$("#subscription_info").html(
|
||||
_t("An error occured. Please try again later or contact us.")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-warning")
|
||||
.addClass("alert-error");
|
||||
});
|
||||
}
|
||||
else {
|
||||
$('#div_blacklist').hide();
|
||||
} else {
|
||||
$("#div_blacklist").hide();
|
||||
}
|
||||
|
||||
var unsubscribed_list = $("input[name='unsubscribed_list']").val();
|
||||
if (unsubscribed_list){
|
||||
$('#subscription_info').html(_.str.sprintf(
|
||||
_t("You have been <strong>successfully unsubscribed from %s</strong>."),
|
||||
unsubscribed_list
|
||||
));
|
||||
}
|
||||
else{
|
||||
$('#subscription_info').html(_t('You have been <strong>successfully unsubscribed</strong>.'));
|
||||
if (unsubscribed_list) {
|
||||
$("#subscription_info").html(
|
||||
_.str.sprintf(
|
||||
_t("You have been <strong>successfully unsubscribed from %s</strong>."),
|
||||
unsubscribed_list
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$("#subscription_info").html(
|
||||
_t("You have been <strong>successfully unsubscribed</strong>.")
|
||||
);
|
||||
}
|
||||
|
||||
$('#unsubscribe_form').on('submit', function (e) {
|
||||
$("#unsubscribe_form").on("submit", function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
var checked_ids = [];
|
||||
$("input[type='checkbox']:checked").each(function (i) {
|
||||
$("input[type='checkbox']:checked").each(function(i) {
|
||||
checked_ids[i] = parseInt($(this).val(), 10);
|
||||
});
|
||||
|
||||
var unchecked_ids = [];
|
||||
$("input[type='checkbox']:not(:checked)").each(function (i) {
|
||||
$("input[type='checkbox']:not(:checked)").each(function(i) {
|
||||
unchecked_ids[i] = parseInt($(this).val(), 10);
|
||||
});
|
||||
|
||||
var values = {
|
||||
'opt_in_ids': checked_ids,
|
||||
'opt_out_ids': unchecked_ids,
|
||||
'email': email,
|
||||
'mailing_id': mailing_id,
|
||||
'res_id': res_id,
|
||||
'token': token
|
||||
opt_in_ids: checked_ids,
|
||||
opt_out_ids: unchecked_ids,
|
||||
email: email,
|
||||
mailing_id: mailing_id,
|
||||
res_id: res_id,
|
||||
token: token,
|
||||
};
|
||||
// Only send reason and details if an unsubscription was found
|
||||
if ($reasons.is(":visible")) {
|
||||
|
@ -140,41 +152,53 @@ odoo.define('mass_mailing_custom_unsubscribe.unsubscribe', function (require) {
|
|||
values.details = $details.val();
|
||||
}
|
||||
|
||||
ajax.jsonRpc('/mail/mailing/unsubscribe', 'call', values)
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized') {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('You are not authorized to do this!'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
|
||||
}
|
||||
else if (result == true) {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('Your changes have been saved.'));
|
||||
$info_state.removeClass('alert-info').addClass('alert-success');
|
||||
ajax.jsonRpc("/mail/mailing/unsubscribe", "call", values)
|
||||
.then(function(result) {
|
||||
if (result == "unauthorized") {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t("You are not authorized to do this!")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-error")
|
||||
.addClass("alert-warning");
|
||||
} else if (result == true) {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(_t("Your changes have been saved."));
|
||||
$info_state.removeClass("alert-info").addClass("alert-success");
|
||||
// Store checked status, to enable further changes
|
||||
$mailing_lists.each(function () {
|
||||
$mailing_lists.each(function() {
|
||||
var $this = $(this);
|
||||
$this.attr("checked", $this.prop("checked"));
|
||||
});
|
||||
toggle_reasons();
|
||||
}
|
||||
else {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('An error occurred. Your changes have not been saved, try again later.'));
|
||||
$info_state.removeClass('alert-info').addClass('alert-warning');
|
||||
} else {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t(
|
||||
"An error occurred. Your changes have not been saved, try again later."
|
||||
)
|
||||
);
|
||||
$info_state.removeClass("alert-info").addClass("alert-warning");
|
||||
}
|
||||
})
|
||||
.guardedCatch(function () {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('An error occurred. Your changes have not been saved, try again later.'));
|
||||
$info_state.removeClass('alert-info').addClass('alert-warning');
|
||||
.guardedCatch(function() {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t(
|
||||
"An error occurred. Your changes have not been saved, try again later."
|
||||
)
|
||||
);
|
||||
$info_state.removeClass("alert-info").addClass("alert-warning");
|
||||
});
|
||||
});
|
||||
|
||||
// ==================
|
||||
// Blacklist
|
||||
// ==================
|
||||
$('#button_add_blacklist').click(function (e) {
|
||||
$("#button_add_blacklist").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
if ($reasons.is(":hidden")) {
|
||||
|
@ -185,104 +209,161 @@ odoo.define('mass_mailing_custom_unsubscribe.unsubscribe', function (require) {
|
|||
return;
|
||||
}
|
||||
|
||||
ajax.jsonRpc('/mailing/blacklist/add', 'call', {
|
||||
'email': email,
|
||||
'mailing_id': mailing_id,
|
||||
'res_id': res_id,
|
||||
'token': token,
|
||||
'reason_id': parseInt($reasons.find("[name='reason_id']:checked").val(), 10),
|
||||
'details': $details.val(),
|
||||
ajax.jsonRpc("/mailing/blacklist/add", "call", {
|
||||
email: email,
|
||||
mailing_id: mailing_id,
|
||||
res_id: res_id,
|
||||
token: token,
|
||||
reason_id: parseInt($reasons.find("[name='reason_id']:checked").val(), 10),
|
||||
details: $details.val(),
|
||||
})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized') {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('You are not authorized to do this!'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
|
||||
}
|
||||
else {
|
||||
.then(function(result) {
|
||||
if (result == "unauthorized") {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t("You are not authorized to do this!")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-error")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
if (result) {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('You have been successfully <strong>added to our blacklist</strong>. '
|
||||
+ 'You will not be contacted anymore by our services.'));
|
||||
$info_state.removeClass('alert-warning').removeClass('alert-info').removeClass('alert-error').addClass('alert-success');
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t(
|
||||
"You have been successfully <strong>added to our blacklist</strong>. " +
|
||||
"You will not be contacted anymore by our services."
|
||||
)
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-warning")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-error")
|
||||
.addClass("alert-success");
|
||||
toggle_opt_out_section(false);
|
||||
// set mailing lists checkboxes to previous state
|
||||
$mailing_lists.each(function () {
|
||||
$mailing_lists.each(function() {
|
||||
var $this = $(this);
|
||||
$this.prop("checked", $(this)[0].hasAttribute("checked"));
|
||||
});
|
||||
// Hide reasons and reset reason fields
|
||||
$reasons.toggleClass("d-none", true)
|
||||
.find(":radio").prop("checked", false);
|
||||
$reasons
|
||||
.toggleClass("d-none", true)
|
||||
.find(":radio")
|
||||
.prop("checked", false);
|
||||
$details.val("").prop("required", false);
|
||||
} else {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t(
|
||||
"An error occured. Please try again later or contact us."
|
||||
)
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-warning")
|
||||
.addClass("alert-error");
|
||||
}
|
||||
else {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
|
||||
}
|
||||
$('#button_add_blacklist').hide();
|
||||
$('#button_remove_blacklist').show();
|
||||
$('#unsubscribed_info').hide();
|
||||
$("#button_add_blacklist").hide();
|
||||
$("#button_remove_blacklist").show();
|
||||
$("#unsubscribed_info").hide();
|
||||
}
|
||||
})
|
||||
.guardedCatch(function () {
|
||||
$('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
|
||||
.guardedCatch(function() {
|
||||
$("#subscription_info").html(
|
||||
_t("An error occured. Please try again later or contact us.")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-warning")
|
||||
.addClass("alert-error");
|
||||
});
|
||||
});
|
||||
|
||||
$('#button_remove_blacklist').click(function (e) {
|
||||
$("#button_remove_blacklist").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
ajax.jsonRpc('/mailing/blacklist/remove', 'call', {
|
||||
'email': email,
|
||||
'mailing_id': mailing_id,
|
||||
'res_id': res_id,
|
||||
'token': token
|
||||
ajax.jsonRpc("/mailing/blacklist/remove", "call", {
|
||||
email: email,
|
||||
mailing_id: mailing_id,
|
||||
res_id: res_id,
|
||||
token: token,
|
||||
})
|
||||
.then(function (result) {
|
||||
if (result == 'unauthorized') {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('You are not authorized to do this!'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-error').addClass('alert-warning');
|
||||
}
|
||||
else {
|
||||
.then(function(result) {
|
||||
if (result == "unauthorized") {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t("You are not authorized to do this!")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-error")
|
||||
.addClass("alert-warning");
|
||||
} else {
|
||||
if (result) {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t("You have been successfully <strong>removed from our blacklist</strong>. "
|
||||
+ "You are now able to be contacted by our services."));
|
||||
$info_state.removeClass('alert-warning').removeClass('alert-info').removeClass('alert-error').addClass('alert-success');
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t(
|
||||
"You have been successfully <strong>removed from our blacklist</strong>. " +
|
||||
"You are now able to be contacted by our services."
|
||||
)
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-warning")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-error")
|
||||
.addClass("alert-success");
|
||||
toggle_opt_out_section(true);
|
||||
} else {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t(
|
||||
"An error occured. Please try again later or contact us."
|
||||
)
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-warning")
|
||||
.addClass("alert-error");
|
||||
}
|
||||
else {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
|
||||
}
|
||||
$('#button_add_blacklist').show();
|
||||
$('#button_remove_blacklist').hide();
|
||||
$('#unsubscribed_info').hide();
|
||||
$("#button_add_blacklist").show();
|
||||
$("#button_remove_blacklist").hide();
|
||||
$("#unsubscribed_info").hide();
|
||||
}
|
||||
})
|
||||
.guardedCatch(function () {
|
||||
$('#info_state').removeClass('invisible');
|
||||
$('#subscription_info').html(_t('An error occured. Please try again later or contact us.'));
|
||||
$info_state.removeClass('alert-success').removeClass('alert-info').removeClass('alert-warning').addClass('alert-error');
|
||||
.guardedCatch(function() {
|
||||
$("#info_state").removeClass("invisible");
|
||||
$("#subscription_info").html(
|
||||
_t("An error occured. Please try again later or contact us.")
|
||||
);
|
||||
$info_state
|
||||
.removeClass("alert-success")
|
||||
.removeClass("alert-info")
|
||||
.removeClass("alert-warning")
|
||||
.addClass("alert-error");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function toggle_opt_out_section(value) {
|
||||
var result = !value;
|
||||
$("#div_opt_out").find('*').attr('disabled', result);
|
||||
$("#button_add_blacklist").attr('disabled', false);
|
||||
$("#button_remove_blacklist").attr('disabled', false);
|
||||
$("#custom_div_feedback").find('*').attr('disabled', false);
|
||||
$("#div_opt_out")
|
||||
.find("*")
|
||||
.attr("disabled", result);
|
||||
$("#button_add_blacklist").attr("disabled", false);
|
||||
$("#button_remove_blacklist").attr("disabled", false);
|
||||
$("#custom_div_feedback")
|
||||
.find("*")
|
||||
.attr("disabled", false);
|
||||
if (value) {
|
||||
$('[name="button_subscription"]').addClass('clickable');
|
||||
}
|
||||
else {
|
||||
$('[name="button_subscription"]').removeClass('clickable');
|
||||
$('[name="button_subscription"]').addClass("clickable");
|
||||
} else {
|
||||
$('[name="button_subscription"]').removeClass("clickable");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<template id="reason" name="UI for Providing Unsubscription Reasons">
|
||||
<div id="custom_div_feedback" t-attf-class="alert alert-success mt-4 #{extra_class or ''}" role="status">
|
||||
<p>We would appreciate if you provide feedback about why you updated<br/>your subscriptions
|
||||
<div
|
||||
id="custom_div_feedback"
|
||||
t-attf-class="alert alert-success mt-4 #{extra_class or ''}"
|
||||
role="status"
|
||||
>
|
||||
<p>We would appreciate if you provide feedback about why you updated<br
|
||||
/>your subscriptions
|
||||
</p>
|
||||
<div class="col-md-12 mb16">
|
||||
<t t-foreach="reasons" t-as="reason">
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="reason_id" t-att-data-details-required="reason.details_required" t-att-value="reason.id" required="required"/>
|
||||
<t t-esc="reason.display_name"/>
|
||||
<input
|
||||
type="radio"
|
||||
name="reason_id"
|
||||
t-att-data-details-required="reason.details_required"
|
||||
t-att-value="reason.id"
|
||||
required="required"
|
||||
/>
|
||||
<t t-esc="reason.display_name" />
|
||||
</label>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
<textarea class="form-control" name="details" cols="60" rows="3"></textarea>
|
||||
<textarea class="form-control" name="details" cols="60" rows="3" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -26,12 +36,25 @@
|
|||
<t t-call="mass_mailing.layout">
|
||||
<div class="container o_unsubscribe_form">
|
||||
<div class="row">
|
||||
<form id="reason_form" t-attf-action="/mail/mailing/#{mailing_id}/unsubscribe?token=#{token}" method="post" class="col-lg-6 offset-lg-3 mt-4">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="email" t-att-value="email"/>
|
||||
<input type="hidden" name="mailing_id" t-att-value="mailing_id"/>
|
||||
<input type="hidden" name="res_id" t-att-value="res_id"/>
|
||||
<t t-call="mass_mailing_custom_unsubscribe.reason"/>
|
||||
<form
|
||||
id="reason_form"
|
||||
t-attf-action="/mail/mailing/#{mailing_id}/unsubscribe?token=#{token}"
|
||||
method="post"
|
||||
class="col-lg-6 offset-lg-3 mt-4"
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
name="csrf_token"
|
||||
t-att-value="request.csrf_token()"
|
||||
/>
|
||||
<input type="hidden" name="email" t-att-value="email" />
|
||||
<input
|
||||
type="hidden"
|
||||
name="mailing_id"
|
||||
t-att-value="mailing_id"
|
||||
/>
|
||||
<input type="hidden" name="res_id" t-att-value="res_id" />
|
||||
<t t-call="mass_mailing_custom_unsubscribe.reason" />
|
||||
<div class="form-group mb16 mt16">
|
||||
<button type="submit" class="btn btn-danger">
|
||||
Unsubscribe now
|
||||
|
|
|
@ -1,31 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<template id="unsubscribe" inherit_id="mass_mailing.unsubscribe" name="Add Reasons to Mailing List Management Form">
|
||||
<template
|
||||
id="unsubscribe"
|
||||
inherit_id="mass_mailing.unsubscribe"
|
||||
name="Add Reasons to Mailing List Management Form"
|
||||
>
|
||||
<!-- Hide original feedback textarea to put another one after mailing lists checkboxes -->
|
||||
<xpath expr="//div[@id='div_feedback']" position="attributes">
|
||||
<attribute name="class" add="d-none" separator=" "/>
|
||||
<attribute name="class" add="d-none" separator=" " />
|
||||
</xpath>
|
||||
|
||||
<!-- Add reasons to mass mailing list manager -->
|
||||
<xpath expr="//ul[hasclass('list-group')]" position="after">
|
||||
<t t-call="mass_mailing_custom_unsubscribe.reason">
|
||||
<t t-set="extra_class" t-value="'d-none'"/>
|
||||
<t t-set="extra_class" t-value="'d-none'" />
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="unsubscribed"
|
||||
inherit_id="mass_mailing.unsubscribed"
|
||||
name="Add Reasons to Blacklist Management Form">
|
||||
<template
|
||||
id="unsubscribed"
|
||||
inherit_id="mass_mailing.unsubscribed"
|
||||
name="Add Reasons to Blacklist Management Form"
|
||||
>
|
||||
<!-- Add reasons to blacklist manager -->
|
||||
<xpath expr="//div[@id='button_add_blacklist']" position="before">
|
||||
<form id="unsubscribe_form">
|
||||
<t t-call="mass_mailing_custom_unsubscribe.reason">
|
||||
<t t-set="extra_class" t-value="'d-none'"/>
|
||||
<t t-set="extra_class" t-value="'d-none'" />
|
||||
</t>
|
||||
</form>
|
||||
</xpath>
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<template id="assets_backend"
|
||||
inherit_id="mass_mailing.assets_backend">
|
||||
<template id="assets_backend" inherit_id="mass_mailing.assets_backend">
|
||||
<!-- Need to replace the asset because upstream is impossible to extend -->
|
||||
<xpath expr="//script[@src='/mass_mailing/static/src/js/unsubscribe.js']" position="replace">
|
||||
<script type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe/static/src/js/unsubscribe.js"/>
|
||||
<xpath
|
||||
expr="//script[@src='/mass_mailing/static/src/js/unsubscribe.js']"
|
||||
position="replace"
|
||||
>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe/static/src/js/unsubscribe.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_mail_mass_mailing_list_form" model="ir.ui.view">
|
||||
<field name="model">mailing.list</field>
|
||||
<field name="inherit_id" ref="mass_mailing.mailing_list_view_form"/>
|
||||
<field name="inherit_id" ref="mass_mailing.mailing_list_view_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="is_public" position="after">
|
||||
<field name="not_cross_unsubscriptable"
|
||||
attrs="{'invisible': [('is_public', '=', False)]}"/>
|
||||
<field
|
||||
name="not_cross_unsubscriptable"
|
||||
attrs="{'invisible': [('is_public', '=', False)]}"
|
||||
/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="mail_unsubscription_reason_view_form" model="ir.ui.view">
|
||||
|
@ -11,11 +10,11 @@
|
|||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="details_required"/>
|
||||
<field name="sequence"/>
|
||||
<field name="name" />
|
||||
<field name="details_required" />
|
||||
<field name="sequence" />
|
||||
</group>
|
||||
<div class="oe_chatter"/>
|
||||
<div class="oe_chatter" />
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -26,9 +25,9 @@
|
|||
<field name="model">mail.unsubscription.reason</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="name"/>
|
||||
<field name="details_required"/>
|
||||
<field name="sequence" widget="handle" />
|
||||
<field name="name" />
|
||||
<field name="details_required" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -38,20 +37,22 @@
|
|||
<field name="model">mail.unsubscription.reason</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="details_required"/>
|
||||
<field name="name" />
|
||||
<field name="details_required" />
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
id="mail_unsubscription_reason_action"
|
||||
name="Unsubscription Reasons"
|
||||
res_model="mail.unsubscription.reason"/>
|
||||
id="mail_unsubscription_reason_action"
|
||||
name="Unsubscription Reasons"
|
||||
res_model="mail.unsubscription.reason"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="mail_unsubscription_reason_menu"
|
||||
parent="mass_mailing.mass_mailing_configuration"
|
||||
action="mail_unsubscription_reason_action"/>
|
||||
id="mail_unsubscription_reason_menu"
|
||||
parent="mass_mailing.mass_mailing_configuration"
|
||||
action="mail_unsubscription_reason_action"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Jairo Llopis <jairo.llopis@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="mail_unsubscription_view_form" model="ir.ui.view">
|
||||
|
@ -11,26 +10,31 @@
|
|||
<form>
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
<field name="mass_mailing_id"/>
|
||||
<field name="unsubscriber_id"/>
|
||||
<field name="mailing_list_ids" widget="many2many_tags"/>
|
||||
<field name="email"/>
|
||||
<field name="action"/>
|
||||
<field name="reason_id"
|
||||
attrs="{'required': [('action', '=', 'unsubscription')]}"/>
|
||||
<field name="details"
|
||||
attrs="{'required': [('details_required', '=', True)]}"/>
|
||||
<field name="details_required" invisible="True"/>
|
||||
<field name="metadata"/>
|
||||
<field name="date" />
|
||||
<field name="mass_mailing_id" />
|
||||
<field name="unsubscriber_id" />
|
||||
<field name="mailing_list_ids" widget="many2many_tags" />
|
||||
<field name="email" />
|
||||
<field name="action" />
|
||||
<field
|
||||
name="reason_id"
|
||||
attrs="{'required': [('action', '=', 'unsubscription')]}"
|
||||
/>
|
||||
<field
|
||||
name="details"
|
||||
attrs="{'required': [('details_required', '=', True)]}"
|
||||
/>
|
||||
<field name="details_required" invisible="True" />
|
||||
<field name="metadata" />
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids"
|
||||
widget="mail_followers"
|
||||
groups="base.group_user"/>
|
||||
<field name="message_ids"
|
||||
widget="mail_thread"/>
|
||||
<field
|
||||
name="message_follower_ids"
|
||||
widget="mail_followers"
|
||||
groups="base.group_user"
|
||||
/>
|
||||
<field name="message_ids" widget="mail_thread" />
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -41,14 +45,14 @@
|
|||
<field name="model">mail.unsubscription</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-warning="action in ['unsubscription', 'blacklist_add']">
|
||||
<field name="date"/>
|
||||
<field name="mass_mailing_id"/>
|
||||
<field name="unsubscriber_id"/>
|
||||
<field name="mailing_list_ids" widget="many2many_tags"/>
|
||||
<field name="email" invisible="True"/>
|
||||
<field name="action"/>
|
||||
<field name="reason_id"/>
|
||||
<field name="details" invisible="True"/>
|
||||
<field name="date" />
|
||||
<field name="mass_mailing_id" />
|
||||
<field name="unsubscriber_id" />
|
||||
<field name="mailing_list_ids" widget="many2many_tags" />
|
||||
<field name="email" invisible="True" />
|
||||
<field name="action" />
|
||||
<field name="reason_id" />
|
||||
<field name="details" invisible="True" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -58,32 +62,44 @@
|
|||
<field name="model">mail.unsubscription</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="mass_mailing_id"/>
|
||||
<field name="unsubscriber_id"/>
|
||||
<field name="mailing_list_ids"/>
|
||||
<field name="email"/>
|
||||
<field name="reason_id"/>
|
||||
<field name="details"/>
|
||||
<separator/>
|
||||
<field name="mass_mailing_id" />
|
||||
<field name="unsubscriber_id" />
|
||||
<field name="mailing_list_ids" />
|
||||
<field name="email" />
|
||||
<field name="reason_id" />
|
||||
<field name="details" />
|
||||
<separator />
|
||||
<group string="Group by">
|
||||
<filter name="group_by_month"
|
||||
<filter
|
||||
name="group_by_month"
|
||||
string="Month"
|
||||
context="{'group_by': 'date:month'}"/>
|
||||
<filter name="group_by_year"
|
||||
context="{'group_by': 'date:month'}"
|
||||
/>
|
||||
<filter
|
||||
name="group_by_year"
|
||||
string="Year"
|
||||
context="{'group_by': 'date:year'}"/>
|
||||
<filter name="group_by_action"
|
||||
context="{'group_by': 'date:year'}"
|
||||
/>
|
||||
<filter
|
||||
name="group_by_action"
|
||||
string="Action"
|
||||
context="{'group_by': 'action'}"/>
|
||||
<filter name="group_by_email"
|
||||
context="{'group_by': 'action'}"
|
||||
/>
|
||||
<filter
|
||||
name="group_by_email"
|
||||
string="Email"
|
||||
context="{'group_by': 'email'}"/>
|
||||
<filter name="group_by_reason"
|
||||
context="{'group_by': 'email'}"
|
||||
/>
|
||||
<filter
|
||||
name="group_by_reason"
|
||||
string="Reason"
|
||||
context="{'group_by': 'reason_id'}"/>
|
||||
<filter name="group_by_mass_mailing"
|
||||
context="{'group_by': 'reason_id'}"
|
||||
/>
|
||||
<filter
|
||||
name="group_by_mass_mailing"
|
||||
string="Mass mailing"
|
||||
context="{'group_by': 'mass_mailing_id'}"/>
|
||||
context="{'group_by': 'mass_mailing_id'}"
|
||||
/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -94,9 +110,9 @@
|
|||
<field name="model">mail.unsubscription</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="(Un)subscriptions">
|
||||
<field name="reason_id" type="row"/>
|
||||
<field name="mailing_list_ids" type="row"/>
|
||||
<field name="action" type="col"/>
|
||||
<field name="reason_id" type="row" />
|
||||
<field name="mailing_list_ids" type="row" />
|
||||
<field name="action" type="col" />
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -106,18 +122,23 @@
|
|||
<field name="model">mail.unsubscription</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="(Un)subscriptions">
|
||||
<field name="date" type="row"/>
|
||||
<field name="action" type="col"/>
|
||||
<field name="date" type="row" />
|
||||
<field name="action" type="col" />
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window id="mail_unsubscription_action"
|
||||
name="(Un)subscriptions"
|
||||
view_mode="tree,form,pivot,graph"
|
||||
res_model="mail.unsubscription"/>
|
||||
<act_window
|
||||
id="mail_unsubscription_action"
|
||||
name="(Un)subscriptions"
|
||||
view_mode="tree,form,pivot,graph"
|
||||
res_model="mail.unsubscription"
|
||||
/>
|
||||
|
||||
<menuitem id="mail_unsubscription_menu" parent="mass_mailing.mass_mailing_menu_root"
|
||||
action="mail_unsubscription_action"/>
|
||||
<menuitem
|
||||
id="mail_unsubscription_menu"
|
||||
parent="mass_mailing.mass_mailing_menu_root"
|
||||
action="mail_unsubscription_action"
|
||||
/>
|
||||
|
||||
</odoo>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 Tecnativa - João Marques
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<template id="assets_frontend_demo"
|
||||
inherit_id="web.assets_frontend">
|
||||
<template id="assets_frontend_demo" inherit_id="web.assets_frontend">
|
||||
<xpath expr=".">
|
||||
<script type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe_event/static/src/js/tour.js"/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/mass_mailing_custom_unsubscribe_event/static/src/js/tour.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,47 +1,45 @@
|
|||
/* Copyright 2020 Tecnativa - João Marques
|
||||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
odoo.define("mass_mailing_custom_unsubscribe_event.tour",
|
||||
function (require) {
|
||||
"use strict";
|
||||
var base = require("web_editor.base");
|
||||
var tour = require("web_tour.tour");
|
||||
odoo.define("mass_mailing_custom_unsubscribe_event.tour", function(require) {
|
||||
"use strict";
|
||||
var base = require("web_editor.base");
|
||||
var tour = require("web_tour.tour");
|
||||
|
||||
// Allow to know if an element is required
|
||||
$.extend($.expr[':'], {
|
||||
propRequired: function (element) {
|
||||
return $(element).prop("required");
|
||||
},
|
||||
});
|
||||
// Allow to know if an element is required
|
||||
$.extend($.expr[":"], {
|
||||
propRequired: function(element) {
|
||||
return $(element).prop("required");
|
||||
},
|
||||
});
|
||||
|
||||
tour.register(
|
||||
"mass_mailing_custom_unsubscribe_event_tour",
|
||||
tour.register(
|
||||
"mass_mailing_custom_unsubscribe_event_tour",
|
||||
{
|
||||
test: true,
|
||||
wait_for: base.ready(),
|
||||
},
|
||||
[
|
||||
{
|
||||
test: true,
|
||||
wait_for: base.ready(),
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio:not(:checked)",
|
||||
extra_trigger: "#reason_form #custom_div_feedback",
|
||||
},
|
||||
[
|
||||
{
|
||||
content: "Choose other reason",
|
||||
trigger: ".radio:contains('Other reason') :radio:not(:checked)",
|
||||
extra_trigger: "#reason_form #custom_div_feedback",
|
||||
},
|
||||
{
|
||||
content: "Switch to not interested reason",
|
||||
trigger:
|
||||
".radio:contains(\"I'm not interested\") :radio:not(:checked)",
|
||||
extra_trigger: "[name='details']:propRequired",
|
||||
},
|
||||
{
|
||||
content: "Unsubscribe",
|
||||
trigger: "#reason_form button:submit",
|
||||
extra_trigger: "body:not(:has([name='details']:propRequired))",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger: "body:not(:has(#reason_form)) #subscription_info " +
|
||||
":contains('successfully unsubscribed')",
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
{
|
||||
content: "Switch to not interested reason",
|
||||
trigger: '.radio:contains("I\'m not interested") :radio:not(:checked)',
|
||||
extra_trigger: "[name='details']:propRequired",
|
||||
},
|
||||
{
|
||||
content: "Unsubscribe",
|
||||
trigger: "#reason_form button:submit",
|
||||
extra_trigger: "body:not(:has([name='details']:propRequired))",
|
||||
},
|
||||
{
|
||||
content: "Successfully unsubscribed",
|
||||
trigger:
|
||||
"body:not(:has(#reason_form)) #subscription_info " +
|
||||
":contains('successfully unsubscribed')",
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2020 Tecnativa - Pedro M. Baeza
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="view_event_registration_form" model="ir.ui.view">
|
||||
<field name="name">event.registration.form - Add opt_out</field>
|
||||
<field name="model">event.registration</field>
|
||||
<field name="inherit_id" ref="event.view_event_registration_form"/>
|
||||
<field name="inherit_id" ref="event.view_event_registration_form" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="email" position="after">
|
||||
<field name="opt_out" />
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!-- Copyright 2016 Antonio Espinosa <antonio.espinosa@tecnativa.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="event_draft" model="event.registration.state">
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue