[REF] web_planner: refactor to make less brittle and reliant on layout
This introduces a new way to define web_planners. They now take the
following form:
<template id="project_planner">
<t t-call="web_planner.pages">
<t t-call="web_planner.category">
<t t-set="menu_categorytitle" t-value="'Prepare'"/>
<t t-set="menu_categoryclasses" t-value="'fa-flag-checkered'"/>
<t t-call="web_planner.page">
<t t-set="page_title" t-value="'Welcome'"/>
<t t-set="hide_mark_as_done" t-value="True"/>
<t t-set="hide_from_menu" t-value="True"/>
<!-- content here -->
</t>
</t>
</template>
The menu is not manually created anymore, it is automatically generated.
Pages do not have to be part of a category and can just be defined as
children of web_planner.pages. A page can have hide_mark_as_done and
hide_from_menu, these are optional and will both default to False when
omitted.
This commit is contained in:
committed by
Simon Lejeune
parent
c505f00c3e
commit
b2eafca067
@@ -1,10 +1,12 @@
|
||||
odoo.define('web.planner', function (require) {
|
||||
"use strict";
|
||||
|
||||
var core = require('web.core');
|
||||
var Model = require('web.Model');
|
||||
var SystrayMenu = require('web.SystrayMenu');
|
||||
var Widget = require('web.Widget');
|
||||
var planner = require('web.planner.common');
|
||||
var WebClient = require('web.WebClient');
|
||||
|
||||
var PlannerDialog = planner.PlannerDialog;
|
||||
|
||||
@@ -52,26 +54,32 @@ var PlannerLauncher = Widget.extend({
|
||||
this.setup(this.planner_apps[menu_id]);
|
||||
this.need_reflow = true;
|
||||
} else {
|
||||
if (this.$el.is(":visible")) {
|
||||
this.$el.hide();
|
||||
this.need_reflow = true;
|
||||
}
|
||||
this.$el.hide();
|
||||
this.hide_dialog();
|
||||
this.need_reflow = true;
|
||||
}
|
||||
if (this.need_reflow) {
|
||||
this.webclient.menu.reflow();
|
||||
core.bus.trigger('resize');
|
||||
this.need_reflow = false;
|
||||
}
|
||||
},
|
||||
setup: function(planner){
|
||||
var self = this;
|
||||
var webclient = this.findAncestor(function (a) {
|
||||
return a instanceof WebClient;
|
||||
});
|
||||
|
||||
this.planner = planner;
|
||||
this.dialog && this.dialog.destroy();
|
||||
if (this.dialog) {
|
||||
this.dialog.destroy();
|
||||
}
|
||||
this.dialog = new PlannerDialog(this, planner);
|
||||
this.dialog.$el.remove();
|
||||
this.dialog.appendTo(webclient.$el);
|
||||
this.$(".o_planner_progress").tooltip({html: true, title: this.planner.tooltip_planner, placement: 'bottom', delay: {'show': 500}});
|
||||
this.dialog.on("planner_progress_changed", this, function(percent){
|
||||
self.update_parent_progress_bar(percent);
|
||||
});
|
||||
this.dialog.appendTo(document.body);
|
||||
},
|
||||
// event
|
||||
update_parent_progress_bar: function(percent) {
|
||||
@@ -83,8 +91,13 @@ var PlannerLauncher = Widget.extend({
|
||||
this.$el.show();
|
||||
this.$(".progress-bar").css('width', percent+"%");
|
||||
},
|
||||
hide_dialog: function() {
|
||||
if (this.dialog) {
|
||||
this.dialog.$el.hide();
|
||||
}
|
||||
},
|
||||
toggle_dialog: function() {
|
||||
this.dialog.$('#PlannerModal').modal('toggle');
|
||||
this.dialog.$el.toggle();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -99,4 +112,3 @@ return {
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -9,23 +9,51 @@ var utils = require('web.utils');
|
||||
var QWeb = core.qweb;
|
||||
var bus = core.bus;
|
||||
|
||||
var Page = core.Class.extend({
|
||||
init: function (dom, page_index) {
|
||||
var $dom = $(dom);
|
||||
this.dom = dom;
|
||||
this.hide_from_menu = $dom.attr('hide-from-menu');
|
||||
this.hide_mark_as_done = $dom.attr('hide-mark-as-done');
|
||||
this.done = false;
|
||||
this.menu_item = null;
|
||||
this.title = $dom.find('[data-menutitle]').data('menutitle');
|
||||
|
||||
var page_id = this.title.replace(/\s/g, '') + page_index;
|
||||
this.set_page_id(page_id);
|
||||
},
|
||||
set_page_id: function (id) {
|
||||
this.id = id;
|
||||
$(this.dom).attr('id', id);
|
||||
},
|
||||
toggle_done: function () {
|
||||
this.done = ! this.done;
|
||||
},
|
||||
get_category_name: function (category_selector) {
|
||||
var $page = $(this.dom);
|
||||
|
||||
return $page.parents(category_selector).attr('menu-category-id');
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
Widget implementing the Modal of the planner (with all form, menu items, mark buttons, pages, ...). The content (the view_id) is fetched by
|
||||
calling the 'render' method (server side), then footer are appended to every pages (client side). Data are saved when a 'mark button' is clicked.
|
||||
Some element of the template MUST respect naming convention :
|
||||
* Input elements (select, textarea, radio, ...) MUST HAVE an 'id' as 'input_element_#####', where ##### is a string.
|
||||
* Page div MUST HAVE the class "o_planner_page" and an 'id' as 'planner_page#', where # is ideally a
|
||||
number. !!! The declaration order of the page are important. The 'id' number is NOT the sequence order.
|
||||
* Menu item MUST HAVE an href attribute containing the id of the page they are referencing.
|
||||
Template rules:
|
||||
Input elements (select, textarea, radio, ...) MUST HAVE an 'id' as 'input_element_#####', where ##### is a string.
|
||||
Page div MUST HAVE the class "o_planner_page" and an 'id' as 'planner_page#', where # is ideally a
|
||||
number. The declaration order of the page are important. The 'id' number is NOT the sequence order.
|
||||
Menu item MUST HAVE an href attribute containing the id of the page they are referencing.
|
||||
*/
|
||||
var PlannerDialog = Widget.extend({
|
||||
template: "PlannerDialog",
|
||||
pages: [],
|
||||
menu_items: [],
|
||||
currently_shown_page: null,
|
||||
currently_active_menu_item: null,
|
||||
category_selector: 'div[menu-category-id]',
|
||||
events: {
|
||||
'click .o_planner div[id^="planner_page"] a[href^="#planner_page"]': 'change_page',
|
||||
'click .o_planner li a[href^="#planner_page"]': 'change_page',
|
||||
'click .o_planner div[id^="planner_page"] button[data-pageid^="planner_page"]': 'mark_as_done',
|
||||
'hidden.bs.modal': 'on_modal_hide',
|
||||
'shown.bs.modal': 'on_modal_show',
|
||||
'click li a[href^="#"]': 'change_page',
|
||||
'click button.mark_as_done': 'click_on_done',
|
||||
'click a.btn-next': 'change_to_next_page',
|
||||
},
|
||||
init: function(parent, planner) {
|
||||
this._super(parent);
|
||||
@@ -33,11 +61,45 @@ var PlannerDialog = Widget.extend({
|
||||
this.planner = planner;
|
||||
this.cookie_name = this.planner['planner_application'] + '_last_page';
|
||||
this.set('progress', 0);
|
||||
this.pages = [];
|
||||
this.menu_items = [];
|
||||
},
|
||||
start: function() {
|
||||
var self = this;
|
||||
this._super.apply(this, arguments);
|
||||
this._setup_view().then(function(){
|
||||
self.$el.hide();
|
||||
return (new Model('web.planner')).call('render', [self.planner.view_id[0], self.planner.planner_application]).then(function(res) {
|
||||
var $res = $(res);
|
||||
$res.find('.o_planner_page').each(function(index, dom_page) {
|
||||
var page = new Page(dom_page, index);
|
||||
|
||||
self.pages.push(page);
|
||||
});
|
||||
|
||||
var $menu = self.render_menu($res);
|
||||
self.$('.o_planner_menu ul').html($menu);
|
||||
self.menu_items = self.$('.o_planner_menu li');
|
||||
|
||||
self.pages.forEach(function(page) {
|
||||
page.menu_item = self._find_menu_item_by_page_id(page.id);
|
||||
});
|
||||
|
||||
self.$('.o_content_page').html($res);
|
||||
|
||||
// update the planner_data with the new inputs of the view
|
||||
var actual_vals = self._get_values();
|
||||
self.planner.data = _.defaults(self.planner.data, actual_vals);
|
||||
// set the default value
|
||||
self._set_values(self.planner.data);
|
||||
// show last opened page
|
||||
self._show_last_open_page();
|
||||
|
||||
self.$el.on('keyup', "textarea", function() {
|
||||
if (this.scrollHeight != this.clientHeight) {
|
||||
this.style.height = this.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
}).then(function() {
|
||||
self.prepare_planner_event();
|
||||
});
|
||||
},
|
||||
@@ -49,83 +111,185 @@ var PlannerDialog = Widget.extend({
|
||||
});
|
||||
this.on('planner_progress_changed', this, this.update_ui_progress_bar);
|
||||
this.set('progress', this.planner.progress); // init progress to trigger ui update
|
||||
|
||||
$(window).on('resize', function() {
|
||||
self.resize_dialog();
|
||||
});
|
||||
},
|
||||
// ui
|
||||
_setup_view: function(){
|
||||
var self = this;
|
||||
return (new Model('web.planner')).call('render', [self.planner.view_id[0], self.planner.planner_application]).then(function(res) {
|
||||
self.$('.content_page').html(res);
|
||||
// add footer to each page
|
||||
self.add_pages_footer();
|
||||
// update the planner_data with the new inputs of the view
|
||||
var actual_vals = self._get_values();
|
||||
self.planner.data = _.defaults(self.planner.data, actual_vals);
|
||||
// set the default value
|
||||
self._set_values(self.planner.data);
|
||||
// show last opened page
|
||||
var last_open_page = (utils.get_cookie(self.cookie_name)) ? utils.get_cookie(self.cookie_name) : self.planner.data['last_open_page'] || false;
|
||||
if (last_open_page) {
|
||||
self._switch_page(last_open_page);
|
||||
}
|
||||
// Call resize function at the beginning
|
||||
self.resize_dialog();
|
||||
self.$el.on('keyup', "textarea", function() {
|
||||
if (this.scrollHeight != this.clientHeight) {
|
||||
this.style.height = this.scrollHeight + "px";
|
||||
}
|
||||
});
|
||||
});
|
||||
_render_done_page: function (page) {
|
||||
var mark_as_done_button = this.$('.mark_as_done');
|
||||
var next_button = this.$('a.btn-next');
|
||||
var active_menu = $(page.menu_item).find('span');
|
||||
if (page.done) {
|
||||
active_menu.addClass('fa-check');
|
||||
mark_as_done_button.removeClass('fa-square-o btn-primary');
|
||||
mark_as_done_button.addClass('fa-check-square-o btn-default');
|
||||
next_button.removeClass('btn-default');
|
||||
next_button.addClass('btn-primary');
|
||||
|
||||
// page checked animation
|
||||
$(page.dom).addClass('marked');
|
||||
setTimeout(function() {
|
||||
$(page.dom).removeClass('marked');
|
||||
}, 1000);
|
||||
} else {
|
||||
active_menu.removeClass('fa-check');
|
||||
mark_as_done_button.removeClass('fa-check-square-o btn-default');
|
||||
mark_as_done_button.addClass('fa-square-o btn-primary');
|
||||
next_button.removeClass('btn-primary');
|
||||
next_button.addClass('btn-default');
|
||||
}
|
||||
},
|
||||
_show_last_open_page: function () {
|
||||
var last_open_page = utils.get_cookie(this.cookie_name);
|
||||
|
||||
if (! last_open_page) {
|
||||
last_open_page = this.planner.data['last_open_page'] || false;
|
||||
}
|
||||
|
||||
if (last_open_page) {
|
||||
this._display_page(last_open_page);
|
||||
} else {
|
||||
this._display_page(this.pages[0].id);
|
||||
}
|
||||
},
|
||||
update_ui_progress_bar: function(percent) {
|
||||
this.$(".progress-bar").css('width', percent+"%");
|
||||
this.$(".o_planner_progress_col").find('.o_planner_progress_counter').text(percent+"%");
|
||||
},
|
||||
add_pages_footer: function() {
|
||||
create_menu_item: function(page, menu_items, menu_item_page_map) {
|
||||
var $page = $(page.dom);
|
||||
var $menu_item_element = $page.find('h1[data-menutitle]');
|
||||
var menu_title = $menu_item_element.data('menutitle') || $menu_item_element.text();
|
||||
|
||||
menu_items.push(menu_title);
|
||||
menu_item_page_map[menu_title] = page.id;
|
||||
},
|
||||
render_menu: function($res) {
|
||||
var self = this;
|
||||
//find all the pages and append footer to each pages
|
||||
_.each(self.$('.o_planner div[id^="planner_page"]'), function(element) {
|
||||
var $el = $(element);
|
||||
var next_page_name = self.$(".o_planner .o_planner_sidebar li a[href='#"+$el.next().attr('id')+"']").text() || ' Finished!';
|
||||
var footer_template = QWeb.render("PlannerFooter", {
|
||||
'next_page_name': next_page_name,
|
||||
'next_page_id': $el.next().attr('id'),
|
||||
'current_page_id': $el.attr('id'),
|
||||
'start': $el.prev().length ? false: true,
|
||||
'end': $el.next().length ? false: true
|
||||
});
|
||||
$el.append(footer_template);
|
||||
var orphan_pages = [];
|
||||
var menu_categories = [];
|
||||
var menu_item_page_map = {};
|
||||
|
||||
// pages with no category
|
||||
self.pages.forEach(function(page) {
|
||||
var $page = $(page.dom);
|
||||
if (! page.hide_from_menu && ! page.get_category_name(self.category_selector)) {
|
||||
self.create_menu_item(page, orphan_pages, menu_item_page_map);
|
||||
}
|
||||
});
|
||||
|
||||
// pages with a category
|
||||
$res.find(self.category_selector).each(function(index, menu_category) {
|
||||
var $menu_category = $(menu_category);
|
||||
var menu_category_item = {
|
||||
name: $menu_category.attr('menu-category-id'),
|
||||
classes: $menu_category.attr('menu-classes'),
|
||||
menu_items: [],
|
||||
};
|
||||
|
||||
self.pages.forEach(function(page) {
|
||||
if (! page.hide_from_menu && page.get_category_name(self.category_selector) === menu_category_item.name) {
|
||||
self.create_menu_item(page, menu_category_item.menu_items, menu_item_page_map);
|
||||
}
|
||||
});
|
||||
|
||||
menu_categories.push(menu_category_item);
|
||||
});
|
||||
|
||||
var menu = QWeb.render('PlannerMenu', {
|
||||
'orphan_pages': orphan_pages,
|
||||
'menu_categories': menu_categories,
|
||||
'menu_item_page_map': menu_item_page_map
|
||||
});
|
||||
|
||||
return menu;
|
||||
},
|
||||
resize_dialog: function() {
|
||||
var winH = $(window).height();
|
||||
var $modal = this.$('.o_planner_dialog');
|
||||
$modal.height(winH/1.1);
|
||||
this.$('.o_planner_pages').height($modal.height() - 60);
|
||||
this.$('.o_planner_sidebar').height($modal.height() - 75);
|
||||
get_next_page_id: function() {
|
||||
var self = this;
|
||||
var current_page_found = false;
|
||||
var next_page_id = null;
|
||||
self.pages.every(function(page) {
|
||||
if (current_page_found) {
|
||||
next_page_id = page.id;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (page.id === self.currently_shown_page.id) {
|
||||
current_page_found = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return next_page_id;
|
||||
},
|
||||
change_to_next_page: function(ev) {
|
||||
var next_page_id = this.get_next_page_id();
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
if (next_page_id) {
|
||||
this._display_page(next_page_id);
|
||||
}
|
||||
},
|
||||
// page switching
|
||||
change_page: function(ev) {
|
||||
ev.preventDefault();
|
||||
var page_id = $(ev.currentTarget).attr('href').replace('#', '');
|
||||
this._switch_page(page_id);
|
||||
this._display_page(page_id);
|
||||
},
|
||||
_switch_page: function(page_id) {
|
||||
this.$(".o_planner li a[href^='#planner_page']").parent().removeClass('active');
|
||||
this.$(".o_planner li a[href=#"+page_id+"]").parent().addClass('active');
|
||||
this.$(".o_planner div[id^='planner_page']").removeClass('show');
|
||||
this.$(".o_planner div[id="+page_id+"]").addClass('show');
|
||||
this.$(".o_planner .o_planner_pages").scrollTop("0");
|
||||
_find_page_by_id: function (id) {
|
||||
var result = _.find(this.pages, function (page) {
|
||||
return page.id === id;
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
_find_menu_item_by_page_id: function (page_id) {
|
||||
var result = _.find(this.menu_items, function (menu_item) {
|
||||
var $menu_item = $(menu_item);
|
||||
return $($menu_item.find('a')).attr('href') === '#' + page_id;
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
_display_page: function(page_id) {
|
||||
var mark_as_done_button = this.$('button.mark_as_done');
|
||||
var next_button = this.$('a.btn-next');
|
||||
var page = this._find_page_by_id(page_id);
|
||||
if (this.currently_active_menu_item) {
|
||||
$(this.currently_active_menu_item).removeClass('active');
|
||||
}
|
||||
|
||||
var menu_item = this._find_menu_item_by_page_id(page_id);
|
||||
$(menu_item).addClass('active');
|
||||
this.currently_active_menu_item = menu_item;
|
||||
|
||||
if (this.currently_shown_page) {
|
||||
$(this.currently_shown_page.dom).removeClass('show');
|
||||
}
|
||||
|
||||
$(page.dom).addClass('show');
|
||||
this.currently_shown_page = page;
|
||||
|
||||
if (! this.get_next_page_id()) {
|
||||
next_button.hide();
|
||||
} else {
|
||||
next_button.show();
|
||||
}
|
||||
|
||||
if (page.hide_mark_as_done) {
|
||||
mark_as_done_button.hide();
|
||||
} else {
|
||||
mark_as_done_button.show();
|
||||
}
|
||||
|
||||
this.$('.o_planner_title').text(this.currently_shown_page.title);
|
||||
this._render_done_page(this.currently_shown_page);
|
||||
|
||||
this.planner.data['last_open_page'] = page_id;
|
||||
utils.set_cookie(this.cookie_name, page_id, 8*60*60); // create cookie for 8h
|
||||
this.$(".o_content_page").scrollTop("0");
|
||||
},
|
||||
// planner data functions
|
||||
_get_values: function(page_id){
|
||||
_get_values: function(page){
|
||||
// if no page_id, take the complete planner
|
||||
var base_elem = page_id ? this.$(".o_planner div[id="+page_id+"]") : this.$(".o_planner div[id^='planner_page']");
|
||||
var base_elem = page ? $(page.dom) : this.$(".o_planner_page");
|
||||
var values = {};
|
||||
// get the selector for all the input and mark_button
|
||||
// only INPUT (select, textearea, input, checkbox and radio), and BUTTON (.mark_button#) are observed
|
||||
@@ -152,16 +316,20 @@ var PlannerDialog = Widget.extend({
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.pages.forEach(function(page) {
|
||||
values[page.id] = page.done;
|
||||
});
|
||||
return values;
|
||||
},
|
||||
_set_values: function(values){
|
||||
var self = this;
|
||||
_.each(values, function(val, id){
|
||||
var $elem = self.$('#'+id);
|
||||
var $elem = self.$('[id="'+id+'"]');
|
||||
if ($elem.prop("tagName") == 'BUTTON'){
|
||||
if(val == 'marked'){
|
||||
$elem.addClass('fa-check-square-o btn-default').removeClass('fa-square-o btn-primary');
|
||||
self.$(".o_planner li a[href=#"+$elem.data('pageid')+"] span").addClass('fa-check');
|
||||
self.$("li a[href=#"+$elem.data('pageid')+"] span").addClass('fa-check');
|
||||
}
|
||||
}
|
||||
if ($elem.prop("tagName") == 'INPUT' || $elem.prop("tagName") == 'TEXTAREA'){
|
||||
@@ -175,15 +343,31 @@ var PlannerDialog = Widget.extend({
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.pages.forEach(function(page) {
|
||||
page.done = values[page.id];
|
||||
self._render_done_page(page);
|
||||
});
|
||||
},
|
||||
update_planner: function(page_id){
|
||||
update_planner: function(){
|
||||
// update the planner.data with the inputs
|
||||
var vals = this._get_values(page_id);
|
||||
var vals = this._get_values(this.currently_shown_page);
|
||||
this.planner.data = _.extend(this.planner.data, vals);
|
||||
|
||||
// re compute the progress percentage
|
||||
var mark_btn = this.$(".o_planner button[id^='mark_button']");
|
||||
var marked_btn = this.$(".o_planner button[id^='mark_button'].fa-check-square-o");
|
||||
var percent = parseInt((marked_btn.length+1) / (mark_btn.length+1) * 100);
|
||||
var total_pages = 0;
|
||||
var done_pages = 0;
|
||||
|
||||
this.pages.forEach(function(page) {
|
||||
if (! page.hide_mark_as_done) {
|
||||
total_pages++;
|
||||
}
|
||||
if (page.done) {
|
||||
done_pages++;
|
||||
}
|
||||
});
|
||||
|
||||
var percent = parseInt((done_pages / total_pages) * 100, 10);
|
||||
this.set('progress', percent);
|
||||
this.planner.progress = percent;
|
||||
// save data and progress in database
|
||||
@@ -193,39 +377,13 @@ var PlannerDialog = Widget.extend({
|
||||
return (new Model('web.planner')).call('write', [this.planner.id, {'data': JSON.stringify(this.planner.data), 'progress': this.planner.progress}]);
|
||||
},
|
||||
// user actions
|
||||
mark_as_done: function(ev) {
|
||||
var self = this;
|
||||
var btn = $(ev.currentTarget);
|
||||
var page_id = btn.attr('data-pageid');
|
||||
var active_menu = self.$(".o_planner li a[href=#"+page_id+"] span");
|
||||
var active_page = self.$(".o_planner div[id^='planner_page'].o_planner_page.show");
|
||||
|
||||
var next_button = self.$(".o_planner a[data-parent="+page_id+"]");
|
||||
if (!btn.hasClass('fa-check-square-o')) {
|
||||
active_menu.addClass('fa-check');
|
||||
btn.addClass('fa-check-square-o btn-default').removeClass('fa-square-o btn-primary');
|
||||
next_button.addClass('btn-primary').removeClass('btn-default');
|
||||
// page checked animation
|
||||
active_page.addClass('marked');
|
||||
setTimeout(function() { active_page.removeClass('marked'); }, 1000);
|
||||
} else {
|
||||
btn.removeClass('fa-check-square-o btn-default').addClass('fa-square-o btn-primary');
|
||||
next_button.addClass('btn-default').removeClass('btn-primary');
|
||||
active_menu.removeClass('fa-check');
|
||||
}
|
||||
self.update_planner(page_id);
|
||||
},
|
||||
on_modal_show : function(e) {
|
||||
bus.on('action', this, _.bind(this.on_webclient_action, this));
|
||||
$(window).on("unload", this, _.bind(this.on_webclient_action, this)); // bind the action of quitting the window
|
||||
},
|
||||
on_modal_hide : function(e) {
|
||||
bus.off('action', this, _.bind(this.on_webclient_action, this));
|
||||
$(window).off("unload", this, _.bind(this.on_webclient_action, this)); // unbind the action of quitting the window
|
||||
this.update_planner(); // explicit call to save data
|
||||
click_on_done: function(ev) {
|
||||
this.currently_shown_page.toggle_done();
|
||||
this._render_done_page(this.currently_shown_page);
|
||||
this.update_planner();
|
||||
},
|
||||
on_webclient_action: function(e) {
|
||||
this.$('#PlannerModal').modal('hide');
|
||||
this.$('#PlannerDialog').hide();
|
||||
},
|
||||
});
|
||||
return {
|
||||
@@ -233,4 +391,3 @@ return {
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -194,201 +194,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**************** PLANNER MODAL ****************/
|
||||
#PlannerModal {
|
||||
|
||||
@o_planner_width: 480px;
|
||||
#PlannerDialog {
|
||||
font-family: "Lato", serif;
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
right: 5px; // include box shadow
|
||||
bottom: 5px;
|
||||
width: @o_planner_width;
|
||||
z-index: 1001; // z-index website + 1
|
||||
padding-bottom: 80px;
|
||||
|
||||
a {
|
||||
color: #2E917D
|
||||
}
|
||||
.btn-default {
|
||||
background-color: transparent;
|
||||
color: #7C7C7C;
|
||||
line-height: 19px;
|
||||
}
|
||||
.btn-default:hover {
|
||||
color: #333;
|
||||
}
|
||||
.btn-primary {
|
||||
background: #21b799;
|
||||
border-color: #26A38A;
|
||||
color: white;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #2E917D;
|
||||
color: white;
|
||||
}
|
||||
.odoo_purple, a.btn.odoo_purple {
|
||||
background-color: #A24689;
|
||||
color: white;
|
||||
}
|
||||
.odoo_purple.btn:hover{
|
||||
background: #a24689;
|
||||
color: #fff;
|
||||
.row { // website adds negative margins
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.o_planner_page{
|
||||
display : none;
|
||||
.box-shadow(@shadow) {
|
||||
-webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
|
||||
box-shadow: @shadow;
|
||||
}
|
||||
.o_planner_dialog {
|
||||
width: 85%;
|
||||
max-width: 1024px;
|
||||
//overflow: hidden;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
.box-shadow(0 3px 9px #666666);
|
||||
background-color: white;
|
||||
|
||||
// button close
|
||||
button.close {
|
||||
line-height: 30px;
|
||||
color: rgba(51, 51, 51, 0.54);
|
||||
.o_planner_header {
|
||||
padding: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.5em;
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
.o_content_page {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
|
||||
.marked:after {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
z-index:9999;
|
||||
}
|
||||
button.close:hover {
|
||||
color:#222;
|
||||
}
|
||||
|
||||
// modal core
|
||||
.modal-content {
|
||||
background: #f3f3f3;
|
||||
}
|
||||
.modal-body {
|
||||
overflow-x: hidden;
|
||||
max-height: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
.row.o_planner {
|
||||
padding: 0 15px;
|
||||
}
|
||||
.o_planner_footer {
|
||||
padding: 0;
|
||||
height: auto;
|
||||
overflow-y: visible;
|
||||
overflow-x: initial;
|
||||
display: block;
|
||||
background: transparent;
|
||||
position: fixed;
|
||||
z-index: 99;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
.shadow {
|
||||
background: url("/web_planner/static/src/img/shadow.png") center center repeat-x;
|
||||
height: 12px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
border-bottom: 1px solid #E5E5E5;
|
||||
opacity: 0.3;
|
||||
}
|
||||
> div {
|
||||
padding: 1em 15px;
|
||||
background: #f7f7f7;
|
||||
min-height: 60px;
|
||||
}
|
||||
.mark_as_done span{
|
||||
font-family: Lato,serif;
|
||||
}
|
||||
// mark/uncheck button animation
|
||||
button.fa-check-square-o {
|
||||
left: 5em;
|
||||
font-size: 2em;
|
||||
border: none;
|
||||
&:focus {outline:none}
|
||||
&:hover:before{
|
||||
content: "\f096";
|
||||
color: #888;
|
||||
position: absolute;
|
||||
margin-left: 2px;
|
||||
}
|
||||
&:hover i:before{
|
||||
content: "\f00c";
|
||||
color: #CACACA;
|
||||
}
|
||||
span {display: none;}
|
||||
}
|
||||
button.fa-check-square-o:after {
|
||||
color: #7C7C7C;
|
||||
position: absolute;
|
||||
font-size: .5em;
|
||||
opacity: 0;
|
||||
-webkit-transition: all 0.3s ease-in-out;
|
||||
-moz-transition: all 0.3s ease-in-out;
|
||||
-ms-transition: all 0.3s ease-in-out;
|
||||
-o-transition: all 0.3s ease-in-out;
|
||||
}
|
||||
button.fa-check-square-o:hover:after {
|
||||
opacity: 1;
|
||||
-webkit-transition: all 0.3s ease-in-out;
|
||||
-moz-transition: all 0.3s ease-in-out;
|
||||
-ms-transition: all 0.3s ease-in-out;
|
||||
-o-transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.btn-next i {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.span-next {
|
||||
position: absolute;
|
||||
right: 9em;
|
||||
top: 0.8em;
|
||||
opacity: 0;
|
||||
height: 1.3em;
|
||||
font-size: 1em;
|
||||
display: block;
|
||||
-webkit-transition: all 0.3s ease-in-out;
|
||||
-moz-transition: all 0.3s ease-in-out;
|
||||
-ms-transition: all 0.3s ease-in-out;
|
||||
-o-transition: all 0.3s ease-in-out;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
.next-block:hover .span-next {
|
||||
right: 9.6em;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
// PROGRESS
|
||||
.o_planner_progress_container {
|
||||
padding: 0;
|
||||
.o_planner_progress_col {
|
||||
border-right: 1px solid #E5E5E5;
|
||||
background: #f7f7f7;
|
||||
padding: 10px 12px 0 12px;
|
||||
i.fa{
|
||||
font-size: 1.7em;
|
||||
padding-left: 0;
|
||||
margin-right: 0.2em;
|
||||
margin-top: 0.1em;
|
||||
color: #929292;
|
||||
}
|
||||
.o_planner_progress_counter {
|
||||
padding: 6px 0 0 8px;
|
||||
font-weight: bold;
|
||||
color: #727272;
|
||||
}
|
||||
.progress {
|
||||
background-color: #C4C4C4;
|
||||
height: 30px;
|
||||
padding: 3px;
|
||||
}
|
||||
.progress-bar {
|
||||
background: #A24689;
|
||||
border-radius: 4px;
|
||||
height: 95%;
|
||||
box-shadow: 0 1px 0 #7A3067;
|
||||
}
|
||||
}
|
||||
}
|
||||
// MARKED ANIMATION
|
||||
.o_planner_page.marked:after {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
left: 105px;
|
||||
font-size: 20em;
|
||||
font-family: "FontAwesome";
|
||||
content: "\f00c";
|
||||
color: #21b799;
|
||||
vertical-align: middle;
|
||||
padding: 0.3em 0.7em;
|
||||
animation: markAnim ease-in-out 1s;
|
||||
animation-iteration-count: 1;
|
||||
transform-origin: 50% 50%;
|
||||
@@ -410,70 +261,6 @@
|
||||
-ms-transform-origin: 50% 50%;
|
||||
-ms-animation-fill-mode:forwards; /*IE 10+*/
|
||||
}
|
||||
// MENU MOBILE
|
||||
.dropdown.mobile {
|
||||
padding: 10px 12px 0 0px;
|
||||
.dropdown-menu{
|
||||
height: 250px;
|
||||
overflow: auto;
|
||||
}
|
||||
.btn {
|
||||
text-align: justify;
|
||||
}
|
||||
.dropdown-menu a {
|
||||
color: #333;
|
||||
padding: 3px;
|
||||
}
|
||||
.dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus {
|
||||
background-color: #F3F3F3;
|
||||
}
|
||||
.dropdown-menu h4 {
|
||||
padding: 10px 15px 0;
|
||||
border-top: 1px solid #EAEAEA;
|
||||
}
|
||||
.fa {
|
||||
color: #21b799;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.o_planner_sidebar {
|
||||
padding: 5px 5px 20px 10px;
|
||||
border-right: 1px solid #E5E5E5;
|
||||
background: #f7f7f7;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
.nav-stacked h4 {
|
||||
font-size: 15px;
|
||||
color: #444;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.nav-stacked h4 i {
|
||||
margin-right: 8px;
|
||||
color: #A24689;
|
||||
}
|
||||
.nav-stacked li a {
|
||||
padding: 3px 0 3px 38px;
|
||||
margin: auto -10px;
|
||||
color: #444;
|
||||
font-size: 13px;
|
||||
}
|
||||
.nav-stacked li a:hover, .nav-stacked li a:focus {
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.nav-stacked li.active a{
|
||||
background-color: #EAEAEA;
|
||||
}
|
||||
.fa.fa-fw.fa-check {
|
||||
color: #21b799;
|
||||
margin-left: -5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
//NOTEBOOK
|
||||
.o_planner_notebook_container {
|
||||
margin: 20px 0;
|
||||
@@ -581,26 +368,40 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_planner_pages {
|
||||
color: #444;
|
||||
margin-top:-60px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
> div {
|
||||
padding-top: 25px;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
> h1, > h2, > h3, > h4, > h5, > h6, > p, > strong, > i {
|
||||
text-shadow:none;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 0;
|
||||
font-size: 3.5em;
|
||||
font-weight: 100;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2E917D
|
||||
}
|
||||
.btn-default {
|
||||
background-color: transparent;
|
||||
color: #7C7C7C;
|
||||
line-height: 19px;
|
||||
}
|
||||
.btn-default:hover {
|
||||
color: #333;
|
||||
}
|
||||
.btn-primary {
|
||||
background: #21b799;
|
||||
border-color: #26A38A;
|
||||
color: white;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #2E917D;
|
||||
color: white;
|
||||
}
|
||||
.odoo_purple, a.btn.odoo_purple {
|
||||
background-color: #A24689;
|
||||
color: white;
|
||||
}
|
||||
.odoo_purple.btn:hover {
|
||||
background: #a24689;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.o_planner_page {
|
||||
display : none;
|
||||
}
|
||||
|
||||
// PARAGRAPHS
|
||||
.o_planner_paragraphs .icon {
|
||||
text-align: center;
|
||||
@@ -614,39 +415,4 @@
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XS size
|
||||
@media screen and (max-width: 768px) {
|
||||
#PlannerModal .pages {
|
||||
margin-top: 0px;
|
||||
}
|
||||
#PlannerModal .o_planner_progress_counter {
|
||||
padding: 6px 0 0 5px;
|
||||
}
|
||||
}
|
||||
// SM size
|
||||
@media screen and (min-width: 769px) {
|
||||
#PlannerModal .o_planner_paragraphs {
|
||||
div.col-md-10 {
|
||||
margin-top:1em;
|
||||
}
|
||||
span {
|
||||
transform: translateX(-8px);
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
// MD size
|
||||
@media screen and (min-width: 992px) {
|
||||
#PlannerModal .o_planner_paragraphs .icon {
|
||||
font-size: 4em;
|
||||
margin: 0.3em auto .5em;
|
||||
span{
|
||||
transform: translateX(0px);
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,54 +13,41 @@
|
||||
</li>
|
||||
</t>
|
||||
|
||||
<t t-name="PlannerFooter">
|
||||
<div class="o_planner_footer col-sm-8 col-md-9 col-xs-12 hidden-print">
|
||||
<span class="shadow" />
|
||||
|
||||
<div class="col-xs-6 text-left mark-block">
|
||||
<t t-if="!start and !end">
|
||||
<button t-attf-id='mark_button#{current_page_id}'
|
||||
t-attf-data-pageid='#{current_page_id}'
|
||||
class='fa fa-square-o btn btn-primary mark_as_done'><i /> <span>Mark As Done</span>
|
||||
<t t-name="PlannerDialog">
|
||||
<div id="PlannerDialog" tabindex="-1">
|
||||
<div class="row dropdown o_planner_menu">
|
||||
<a class="col-xs-12 btn btn-default" data-toggle="dropdown" href="#" aria-expanded="false">Steps <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"/>
|
||||
</div>
|
||||
<div class="row o_planner_header">
|
||||
<div class="col-xs-4">
|
||||
<button class='fa fa-square-o btn btn-primary mark_as_done'>
|
||||
<i/>
|
||||
<span>Mark As Done</span>
|
||||
</button>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-xs-6 next-block">
|
||||
<t t-if="!end">
|
||||
<a t-attf-class="pull-right btn btn-#{start and 'primary' or 'default'} btn-next"
|
||||
t-attf-data-parent='#{current_page_id}'
|
||||
t-attf-href='##{next_page_id}'>Next step<i class="fa fa-angle-right"></i>
|
||||
</div>
|
||||
<div class="col-xs-4 text-center"><span class="help-block span-next o_planner_title"/></div>
|
||||
<div class="col-xs-4">
|
||||
<a class="pull-right btn btn-next">
|
||||
Next step
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<span class="help-block span-next"> <t t-esc="next_page_name"/></span>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row o_content_page"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="PlannerDialog">
|
||||
<div>
|
||||
<div class="modal fade odoo_colors" id="PlannerModal" tabindex="-1" role="dialog" aria-labelledby="PlannerModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog o_planner_dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-body">
|
||||
<button type="button" class="close" data-dismiss="modal"><i class="fa fa-times"></i></button>
|
||||
<div>
|
||||
<div class="col-sm-12 col-xs-7 o_planner_progress_container">
|
||||
<div class="col-sm-4 col-md-3 col-xs-12 o_planner_progress_col">
|
||||
<i class="fa fa-question-circle col-xs-1"></i>
|
||||
<div class="progress col-xs-9">
|
||||
<div class="progress-bar" t-attf-style="width:0%;"></div>
|
||||
</div>
|
||||
<span class="o_planner_progress_counter col-xs-1"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content_page"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<t t-name="PlannerMenu">
|
||||
<li t-foreach="orphan_pages" t-as="orphan_page">
|
||||
<a t-att-href="'#' + menu_item_page_map[orphan_page]"><span class="fa fa-fw"/><t t-esc="orphan_page"/></a>
|
||||
</li>
|
||||
<t t-foreach="menu_categories" t-as="menu_category">
|
||||
<h4><i t-att-class="'fa ' + menu_category.classes"/><t t-esc="menu_category.name"/></h4>
|
||||
<li t-foreach="menu_category.menu_items" t-as="menu_item">
|
||||
<a t-att-href="'#' + menu_item_page_map[menu_item]"><span class="fa fa-fw"/><t t-esc="menu_item"/></a>
|
||||
</li>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
||||
@@ -12,4 +12,23 @@
|
||||
<script type="text/javascript" src="/web_planner/static/src/js/web_planner_common.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="pages">
|
||||
<div class ="row">
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="category">
|
||||
<div t-att-menu-category-id="menu_categorytitle" t-att-menu-classes="menu_categoryclasses">
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="page">
|
||||
<div t-att-id="page_id" t-att-title="page_title" t-att-hide-from-menu="hide_from_menu" t-att-hide-mark-as-done="hide_mark_as_done" class="o_planner_page">
|
||||
<h1 t-esc="page_title" t-att-data-menutitle="page_menutitle or page_title"/>
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
</template>
|
||||
</odoo>
|
||||
|
||||
@@ -48,7 +48,7 @@ planner.WebsitePlannerLauncher = Widget.extend({
|
||||
this.$(".progress-bar").css('width', percent+"%");
|
||||
},
|
||||
toggle_dialog: function() {
|
||||
this.dialog.$('#PlannerModal').modal('toggle');
|
||||
this.dialog.$el.toggle();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user