Commit a0e68da7 authored by Rafael Monnerat's avatar Rafael Monnerat

Drop Handlebars

See merge request nexedi/slapos.core!393
parents efcbe3a4 1ace7ddc
Pipeline #22800 failed with stage
in 0 seconds
......@@ -2,10 +2,10 @@ url_list = [
"gadget_slapos_translation.html",
"gadget_translation.js",
"gadget_slapos_translation_data.js",
"handlebars.js",
"jiodev.js",
"renderjs.js",
"rsvp.js",
"domsugar.js",
"gadget_erp5_page_map.css",
"gadget_erp5_page_map.html",
"gadget_erp5_page_map.js",
......
......@@ -8,50 +8,24 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Information</title>
<!-- renderjs -->
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<!-- custom script -->
<script src="gadget_erp5_attention_point.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="gadget_erp5_attention_point.css">
<script id="attention_point-item-template" type="text/x-handlebars-template">
{{#each option}}
<div class="attention-point">
{{#if link}}
<a href={{link}}>
{{/if}}
{{text}}
{{#if link}}
</a>
{{/if}}
</div>
{{/each}}
</script>
<script id="attention_point-template" type="text/x-handlebars-template">
<div class="ui-panel-inner">
<div data-role="header" role="banner" class="ui-header ui-bar-inherit">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-right">
<div class="ui-controlgroup-controls">
<button data-rel="save" data-i18n="Submit" type="submit" class="submit responsive ui-last-child ui-btn ui-btn-icon-left"></button>
</div>
</div>
<h1 class="ui-title" role="heading" data-i18n="Warnings" aria-level="1">Warnings</h1>
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<div class="ui-controlgroup-controls">
<button data-i18n="Close" data-rel="close" type="submit" class="close responsive ui-first-child ui-btn ui-btn-icon-left ui-icon-times">Close</button>
</div>
</div>
</div>
<section class="ui-body-c ui-content-section">
<div class="attention_point_item_container ui-controlgroup ui-corner_all"></div>
</section>
</div>
</script>
</head>
<body>
<form class="attention_point_editor">
<div class="container"></div>
<div class="container">
<div class="ui-panel-inner">
<div data-role="header" role="banner" class="ui-header ui-bar-inherit attention_point_header">
</div>
<section class="ui-body-c ui-content-section">
<div class="attention_point_item_container ui-controlgroup ui-corner_all"></div>
</section>
</div>
</div>
</form>
</body>
</html>
\ No newline at end of file
......@@ -232,7 +232,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>975.18443.44162.42615</string> </value>
<value> <string>1001.26171.19762.42854</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -250,7 +250,7 @@
</tuple>
<state>
<tuple>
<float>1556250011.09</float>
<float>1657056446.76</float>
<string>UTC</string>
</tuple>
</state>
......
/*jslint indent: 2, maxerr: 3, nomen: true */
/*global window, document, rJS, RSVP, Handlebars*/
(function (window, document, rJS, RSVP, Handlebars) {
/*global window, document, rJS, RSVP, domsugar*/
(function (window, document, rJS, RSVP, domsugar) {
"use strict";
var gadget_klass = rJS(window),
template_element = gadget_klass.__template_element,
attention_point_item_template = Handlebars.compile(template_element
.getElementById("attention_point-item-template")
.innerHTML),
attention_point_template = Handlebars.compile(template_element
.getElementById("attention_point-template")
.innerHTML);
Handlebars.registerHelper('equal', function (left_value, right_value, options) {
if (arguments.length < 3) {
throw new Error("Handlebars Helper equal needs 2 parameters");
}
if (left_value !== right_value) {
return options.inverse(this);
function createAttentionPointItem(item_list) {
var i, attention_point_item = [];
for (i in item_list) {
if (item_list.hasOwnProperty(i)) {
if (item_list[i].link) {
attention_point_item.push(
domsugar("div", {class: "attention-point"}, [
domsugar("a", {
href: item_list[i].link,
text: item_list[i].text
})
])
);
} else {
attention_point_item.push(
domsugar("div", {
class: "attention-point",
text: item_list[i].text
})
);
}
}
}
return options.fn(this);
});
return attention_point_item;
}
function createAttentionPointTemplate(gadget, attention_point) {
var page = "slap_controller", option_dict = {};
......@@ -32,55 +41,71 @@
}
return gadget.getUrlFor({command: 'change', options: option_dict})
.push(function (link) {
return gadget.translateHtml(attention_point_item_template({
option: [{
return createAttentionPointItem([
{
text: attention_point.text,
link: link
}]
}));
}]);
});
}
return gadget.translateHtml(attention_point_item_template({
option: [{
return createAttentionPointItem([
{
text: attention_point.text,
link: attention_point.link
}]
}));
}]);
}
function createAttentionPointHeader(container) {
while (container.firstChild) {
container.removeChild(container.firstChild);
}
return domsugar(container, {
class: "ui-header ui-bar-inherit attention_point_header",
"data-role": "header",
role: "banner"
}, [
domsugar("div", {class: "ui-controlgroup ui-controlgroup-horizontal ui-btn-right"}, [
domsugar("div", {class: "ui-controlgroup-controls"})
]),
domsugar('h1', {class: "ui-title", role: "heading", "aria-level": "1", text: "Warnings" }),
domsugar("div", {class: "ui-controlgroup ui-controlgroup-horizontal ui-btn-left"}, [
domsugar("div", {class: "ui-controlgroup-controls"}, [
domsugar("button", {
text: "Close",
type: "submit",
"data-rel": "save",
class: "close responsive ui-first-child ui-btn ui-btn-icon-left ui-icon-times"
})])
])
]);
}
gadget_klass
rJS(window)
//////////////////////////////////////////////
// acquired method
//////////////////////////////////////////////
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("trigger", "trigger")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.onStateChange(function onStateChange() {
var gadget = this,
div = document.createElement("div"),
container = gadget.element.querySelector(".container");
return gadget.translateHtml(attention_point_template())
.push(function (translated_html) {
div.innerHTML = translated_html;
container = gadget.element.querySelector(".attention_point_header");
createAttentionPointHeader(container);
return new RSVP.Queue()
.push(function () {
return RSVP.all(gadget.state.attention_point_list
.map(function (attention_point) {
return createAttentionPointTemplate(gadget, attention_point);
})
);
}));
})
.push(function (result_list) {
var i,
subdiv,
attention_point_item_container = div.querySelector('.attention_point_item_container');
attention_point_item_container = gadget.element.querySelector('.attention_point_item_container');
for (i = 0; i < result_list.length; i += 1) {
subdiv = document.createElement("div");
subdiv.innerHTML = result_list[i];
attention_point_item_container.appendChild(subdiv);
}
while (container.firstChild) {
container.removeChild(container.firstChild);
attention_point_item_container.appendChild(
domsugar("div", {}, [result_list[i]])
);
}
container.appendChild(div);
return createAttentionPointHeader(container);
});
})
.declareMethod('render', function render(options) {
......@@ -119,4 +144,4 @@
options: options
});
});
}(window, document, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, document, rJS, RSVP, domsugar));
\ No newline at end of file
......@@ -228,7 +228,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>987.9086.39006.59579</string> </value>
<value> <string>1001.29163.33217.42752</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -246,7 +246,7 @@
</tuple>
<state>
<tuple>
<float>1602096464.77</float>
<float>1657227587.75</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -14,11 +14,6 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script id="dialog-button-template" type="text/x-handlebars-template">
<input name="action_update" type="submit" value="{{button_text}}"></input>
</script>
<script src="gadget_erp5_page_slap_access_denied_view.js" type="text/javascript"></script>
</head>
......
......@@ -238,7 +238,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>982.32792.55683.53538</string> </value>
<value> <string>1001.25024.39363.52411</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -256,7 +256,7 @@
</tuple>
<state>
<tuple>
<float>1584116736.52</float>
<float>1656979474.06</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP, Handlebars, UriTemplate */
/*global window, rJS, RSVP, UriTemplate */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, UriTemplate) {
"use strict";
var gadget_klass = rJS(window);
gadget_klass
rJS(window)
.declareAcquiredMethod("getUrlForList", "getUrlForList")
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("updatePanel", "updatePanel")
......@@ -66,15 +65,10 @@
]);
})
.push(function () {
gadget.element.querySelector('input').value = logout_translation;
return gadget.updatePanel({
jio_key: false
});
})
.push(function () {
// return gadget.translate('Logout');
// })
// .push(function (translated_text) {
gadget.element.querySelector('input').value = logout_translation;
});
})
.onEvent('submit', function () {
......
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>987.11841.53639.29696</string> </value>
<value> <string>999.2068.62564.17</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -252,7 +252,7 @@
</tuple>
<state>
<tuple>
<float>1602261270.19</float>
<float>1656979418.26</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -4,30 +4,21 @@
data-i18n=Success...
data-i18n=Fail...
data-i18n=Unknown action to take:
data-i18n=Continue
-->
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Site List</title>
<title>Notify and Redirect</title>
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<!-- custom script -->
<script src="gadget_erp5_page_slap_notify_and_redirect.js" type="text/javascript"></script>
<script id="message-template" type="text/x-handlebars-template">
<p> <center><strong>{{message_to_acknowledge}} </strong> </center> </p>
<p> </p>
<p> <center><a class="ui-btn ui-first-child ui-btn-icon-center" data-i18n="Continue" href="{{redirect_url}}"> Continue </a></center> </p>
</script>
</head>
</head>
<body>
<form class="save_form ui-body-c" novalidate>
......
......@@ -238,7 +238,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>982.16656.9604.44475</string> </value>
<value> <string>1001.20452.64295.54357</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -256,7 +256,7 @@
</tuple>
<state>
<tuple>
<float>1583494234.93</float>
<float>1656704984.93</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, window, rJS, RSVP, loopEventListener, i18n, Handlebars, $*/
/*globals console, window, rJS, RSVP, loopEventListener, i18n, domsugar, $*/
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, RSVP, domsugar) {
"use strict";
var gadget_klass = rJS(window),
message_source = gadget_klass.__template_element
.getElementById("message-template")
.innerHTML,
message_template = Handlebars.compile(message_source);
gadget_klass
rJS(window)
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
......@@ -27,7 +22,8 @@
translation_list = [
"Success...",
"Fail...",
"Unknown action to take:"
"Unknown action to take:",
"Continue"
];
return new RSVP.Queue()
.push(function () {
......@@ -37,28 +33,42 @@
})
.push(function () {
return RSVP.all([
gadget.getElement(),
gadget.getUrlFor({command: 'change',
options: {jio_key: "/", page: "slapos"}}),
gadget.getTranslationList(translation_list)
]);
})
.push(function (result) {
var redirect_url = result[1],
element = result[0],
var redirect_url = result[0],
message = options.portal_status_message,
page_title;
if (options.message_type === "success") {
page_title = result[2][0];
page_title = result[1][0];
} else if (options.message_type === "error") {
page_title = result[2][1];
page_title = result[1][1];
} else {
throw new Error(result[2][2] + " " + options.result);
throw new Error(result[1][2] + " " + options.result);
}
element.innerHTML = message_template({
message_to_acknowledge: message,
redirect_url: redirect_url
});
domsugar(gadget.element,
{},
[
domsugar("p", {}, [
domsugar("center", {}, [
domsugar("strong", {text: message})
])
]),
domsugar("p"),
domsugar("p", {}, [
domsugar("center", {}, [
domsugar("a", {
text: result[1][3],
"data-i18n": "Continue",
href: redirect_url,
class: "ui-btn ui-first-child ui-btn-icon-center"
})
])
])
]);
return page_title;
})
.push(function (page_title) {
......@@ -68,4 +78,4 @@
return gadget.updateHeader(header_dict);
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, RSVP, domsugar));
\ No newline at end of file
......@@ -277,7 +277,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>986.45437.22132.61764</string> </value>
<value> <string>999.2068.62564.17</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -295,7 +295,7 @@
</tuple>
<state>
<tuple>
<float>1602259359.35</float>
<float>1656704900.93</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -8,17 +8,8 @@
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="gadget_slapos_payment_result.js"></script>
<script id="message-template" type="text/x-handlebars-template">
<p> <center><strong>{{message_to_acknowledge}} </strong> </center> </p>
<p> <center>{{advice}} </center></p>
<p> </p>
<p> <center><a class="ui-btn ui-first-child ui-btn-icon-center" data-i18n="Return to Invoice List" href="{{payment_url}}"> Return to Invoice List</a></center> </p>
</script>
</head>
<body>
......
......@@ -240,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.64930.42858.1297</string> </value>
<value> <string>1000.2322.46712.16657</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -258,7 +258,7 @@
</tuple>
<state>
<tuple>
<float>1516648499.4</float>
<float>1655131178.92</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -7,7 +7,8 @@
float: right;
}
.box-gadget-bottom {
.box-gadget-bottom,
.box-gadget-bottom-header {
float: left;
width: 100%;
padding-top: 17px;
......
......@@ -251,7 +251,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>975.6713.31372.10752</string> </value>
<value> <string>1000.2322.46712.16657</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -269,7 +269,7 @@
</tuple>
<state>
<tuple>
<float>1555545224.77</float>
<float>1654593711.96</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -16,7 +16,7 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="renderjs.js" type="text/javascript"></script>
<!-- custom script -->
......@@ -24,16 +24,6 @@
<script src="gadget_erp5_page_slapos.js" type="text/javascript"></script>
<link href="gadget_erp5_page_slapos.css" rel="stylesheet" type="text/css"/>
<script id="ticket-link-control-template" type="text/x-handlebars-template">
<div class="slapos-control-front">
<center>
<a class="ui-btn ui-first-child ui-btn-white-front ui-btn-icon-left ui-icon-sort-alpha-asc" href="{{ show_all_url }}" data-i18n="Show All Tickets" > Show All Tickets</a>
<a class="ui-btn ui-first-child ui-btn-white-front ui-btn-icon-left ui-icon-rss" href="{{ rss_all_url }}" data-i18n="RSS (all)" > RSS </a>
<a class="ui-btn ui-first-child ui-btn-white-front ui-btn-icon-left ui-icon-rss" href="{{ rss_critical_url }}" data-i18n="RSS Critical" > Critical </a>
</center>
</div>
</script>
</head>
<body>
......@@ -49,6 +39,8 @@
<div data-gadget-url="gadget_erp5_pt_form_view.html"
data-gadget-scope="right"></div>
</div>
<div class="box-gadget-bottom-header">
</div>
<div class="box-gadget-bottom">
<div data-gadget-url="gadget_erp5_pt_form_view.html"
data-gadget-scope="last"></div>
......
......@@ -251,7 +251,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>981.53386.41888.4846</string> </value>
<value> <string>1000.49354.9268.54869</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -269,7 +269,7 @@
</tuple>
<state>
<tuple>
<float>1581602507.86</float>
<float>1654593490.4</float>
<string>UTC</string>
</tuple>
</state>
......
/*global document, window, Option, rJS, RSVP, Chart, UriTemplate, Handlebars*/
/*global document, window, Option, rJS, RSVP, Chart, UriTemplate, domsugar */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, RSVP, domsugar) {
"use strict";
var gadget_klass = rJS(window),
ticket_control_source = gadget_klass.__template_element
.getElementById("ticket-link-control-template")
.innerHTML,
ticket_control_template = Handlebars.compile(ticket_control_source);
var gadget_klass = rJS(window);
gadget_klass
.ready(function (gadget) {
gadget.property_dict = {};
......@@ -22,7 +17,6 @@
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("updatePanel", "updatePanel")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getTranslationList", "getTranslationList")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("updateHeader", "updateHeader")
......@@ -249,49 +243,51 @@
"Modification Date",
"State",
"Pending Tickets to Process",
"Dashboard"
"Dashboard",
"Show All Tickets",
"RSS",
"Critical"
];
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getDeclaredGadget('last'),
gadget.getTranslationList(translation_list1),
gadget.getUrlFor({command: 'change', options: {page: "slap_ticket_list"}}),
gadget.getUrlFor({command: 'change', options: {page: "slap_rss_ticket"}}),
gadget.getUrlFor({command: 'change', options: {page: "slap_rss_critical_ticket"}})
]);
})
.push(function (result) {
return RSVP.all([
gadget.getDeclaredGadget('last'),
gadget.translateHtml(ticket_control_template({
show_all_url: result[0],
rss_all_url: result[1],
rss_critical_url: result[2]
})),
gadget.getTranslationList(translation_list1)
]);
})
.push(function (result) {
gadget.page_title_translation = result[2][4];
gadget.page_title_translation = result[1][4];
var form_list = result[0],
bottom_header = domsugar('div', {"class": "slapos-control-front"},
[
domsugar("center", {}, [
domsugar("a",
{"class": "ui-btn ui-first-child ui-btn-white-front ui-btn-icon-left ui-icon-sort-alpha-asc",
"text": result[1][5],
"href": result[2]}),
domsugar("a",
{"class": "ui-btn ui-first-child ui-btn-white-front ui-btn-icon-left ui-icon-rss",
"text": result[1][6],
"href": result[3]}),
domsugar("a",
{"class": "ui-btn ui-first-child ui-btn-white-front ui-btn-icon-left ui-icon-rss",
"text": result[1][7],
"href": result[4]})
])
]),
div_bottom_header = gadget.element.querySelector(".box-gadget-bottom-header"),
column_list = [
['title', result[2][0]],
['modification_date', result[2][1]],
['translated_simulation_state_title', result[2][2]]
['title', result[1][0]],
['modification_date', result[1][1]],
['translated_simulation_state_title', result[1][2]]
];
div_bottom_header.appendChild(bottom_header);
return form_list.render({
erp5_document: {
"_embedded": {"_view": {
"control": {
"description": "",
"title": "Link Control",
"default": result[1],
"css_class": "",
"required": 1,
"editable": 0,
"key": "control",
"hidden": 0,
"type": "EditorField"
},
"listbox": {
"column_list": column_list,
"show_anchor": 0,
......@@ -307,7 +303,7 @@
"search_column_list": column_list,
"sort_column_list": column_list,
"sort": [["modification_date", "Descending"]],
"title": result[2][3],
"title": result[1][3],
"type": "ListBox"
}
}},
......@@ -398,4 +394,4 @@
});
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, RSVP, domsugar));
\ No newline at end of file
......@@ -247,7 +247,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>994.34705.53932.19848</string> </value>
<value> <string>1000.49340.48222.40550</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -265,7 +265,7 @@
</tuple>
<state>
<tuple>
<float>1631134229.82</float>
<float>1654593493.33</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -6,32 +6,9 @@
<title>Message Alert</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="gadget_slapos_alert_listbox_field.js"></script>
<link href="gadget_slapos_alert_listbox_field.css" rel="stylesheet" type="text/css"/>
<script id="alert-message-template" type="text/x-handlebars-template">
{{#if link}}
<a href={{link}}>
{{/if}}
<div class="alert alert-{{type}}">
{{#if title}}
<h2>{{title}}</h2>
{{/if}}
<p>{{message}}</p>
</div>
{{#if link}}
</a>
{{/if}}
</script>
<script id="alert-message-with-link-template" type="text/x-handlebars-template">
<div class="alert alert-{{type}}">
{{#if title}}
<h2>{{title}}</h2>
{{/if}}
<p>{{message}}</p>
</div>
</a>
</script>
</head>
<body>
</body>
......
......@@ -238,7 +238,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>975.18310.62830.45960</string> </value>
<value> <string>1000.2322.46712.16657</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -256,7 +256,7 @@
</tuple>
<state>
<tuple>
<float>1556243125.51</float>
<float>1655194738.64</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, document, window, rJS, RSVP, Handlebars*/
/*globals console, document, window, rJS */
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (document, window, rJS, RSVP, Handlebars) {
(function (document, window, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window),
alert_message_content = gadget_klass.__template_element
......@@ -14,27 +14,21 @@
.declareMethod("render", function (options) {
var gadget = this,
html_message,
message_content = document.createElement('div'),
closable = options.can_close || false,
id = "alert" + new Date().getTime();
// html_message,
message_content = domsugar('div'),
// closable = options.can_close || false,
id = "alert" + new Date().getTime();
message_content.id = id;
message_content.setAttribute("data-key", options.key || "");
return new RSVP.Queue()
.push(function () {
if (options.value.link) {
return RSVP.all([
gadget.getElement(),
gadget.getUrlFor({command: "index",
return gadget.getUrlFor({command: "index",
options: {jio_key: options.value.link,
page: "slap_controller"}})
page: "slap_controller"}
]);
} else {
return RSVP.all([
gadget.getElement()
]);
}
return
})
.push(function (result) {
var element = result[0],
......
......@@ -8,24 +8,10 @@
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="gadget_slapos_annotated_helper.js"></script>
<link href="gadget_slapos_annotated_helper.css" rel="stylesheet" type="text/css"/>
<script id="add-new-login-header-text" type="text/x-handlebars-template">
<details>
<summary>Password Policy</summary>
<ul>
<li> Minimum 7 characters in length </li>
<li> At least one Uppercase Letter</li>
<li> At least one Lowercase Letter </li>
<li> At least one Number (0 to 9)</li>
<li> At least one Symbol out of $!:;_- .</li>
</ul>
</p>
</details>
<p></p>
</script>
</head>
<body>
......
......@@ -274,7 +274,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>984.14224.386.63232</string> </value>
<value> <string>1000.2322.46712.16657</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -292,7 +292,7 @@
</tuple>
<state>
<tuple>
<float>1590780907.93</float>
<float>1655193614.45</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, window, rJS, RSVP, loopEventListener, i18n, Handlebars, $*/
/*globals console, window, rJS, domsugar */
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window);
function getTemplateById(template_id) {
var template_source = gadget_klass.__template_element
.getElementById(template_id)
.innerHTML;
return Handlebars.compile(template_source);
}
gadget_klass
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("translateHtml", "translateHtml")
.ready(function (gadget) {
gadget.props = {};
return gadget.getSetting("hateoas_url")
.push(function (url) {
gadget.props.hateoas_url = url;
})
.push(function () {
gadget.render({});
});
})
rJS(window)
.declareMethod("getContent", function () {
return {};
})
.declareMethod("render", function (options) {
.onStateChange(function () {
var gadget = this,
annotated_message = "",
annotated_message_template,
annotated_template_id;
gadget.options = options;
if (options.template_id === undefined) {
annotated_template_id,
div = gadget.element.querySelector('div.annotated_help')
if (gadget.state.template_id === undefined) {
// Verify if template-id is present on the div element
annotated_template_id = gadget.element.getAttribute("data-template-id");
annotated_message_template = getTemplateById(annotated_template_id);
annotated_message = annotated_message_template({});
} else if (options.template_id !== undefined) {
annotated_message_template = getTemplateById(options.template_id);
annotated_message = annotated_message_template({});
if (annotated_template_id === "add-new-login-header-text") {
annotated_message = domsugar('detatils', {}, [
domsugar('summary', {text: 'Password Policy'}),
domsugar('ul', {}, [
domsugar('li', {text: 'Minimum 7 characters in length'}),
domsugar('li', {text: 'At least one Uppercase Letter'}),
domsugar('li', {text: 'At least one Lowercase Letter'}),
domsugar('li', {text: 'At least one Number (0 to 9)'}),
domsugar('li', {text: 'At least one Symbol out of $!:;_- .'})
]),
domsugar('p'),
domsugar('p')
]);
}
}
return gadget.getElement()
.push(function (element) {
var div = element.querySelector('div.annotated_help');
div.innerHTML = annotated_message;
return element;
});
return domsugar(div, {class: 'annotated_help'}, [annotated_message];
})
.declareMethod("render", function (options) {
var gadget = this;
return gadget.changeState({
template_id: options.template_id
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, domsugar));
\ No newline at end of file
......@@ -272,7 +272,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>984.14237.41788.53213</string> </value>
<value> <string>1000.58812.62894.1518</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -290,7 +290,7 @@
</tuple>
<state>
<tuple>
<float>1590781349.1</float>
<float>1655193553.67</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -8,30 +8,9 @@
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="gadget_slapos_event_discussion_entry.js"></script>
<link href="gadget_slapos_event_discussion_entry.css" rel="stylesheet" type="text/css"/>
<script id="inline-event-template" type="text/x-handlebars-template">
<div class="slapos-event-discussion-message-header">
<p>By <strong>{{author}} </strong> on {{modification_date}}: </p>
</div>
<div class="slapos-event-discussion-message-body">
<pre>{{message}}</pre>
</div>
</script>
<script id="inline-html-event-template" type="text/x-handlebars-template">
<div class="slapos-event-discussion-message-header">
<p>By <strong>{{author}} </strong> on {{modification_date}}: </p>
</div>
<div class="slapos-event-discussion-message-body">{{{message}}}</div>
</script>
</head>
<body>
......
......@@ -226,7 +226,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superthomas</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -240,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>974.21419.55105.18158</string> </value>
<value> <string>1000.2322.46712.16657</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -258,7 +258,7 @@
</tuple>
<state>
<tuple>
<float>1552496307.06</float>
<float>1655126611.0</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, window, rJS, RSVP, Handlebars, $*/
/*globals console, window, rJS, RSVP, domsugar */
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window),
inline_event_source = gadget_klass.__template_element
.getElementById("inline-event-template")
.innerHTML,
inline_status_template = Handlebars.compile(inline_event_source),
inline_html_event_source = gadget_klass.__template_element
.getElementById("inline-html-event-template")
.innerHTML,
inline_html_status_template = Handlebars.compile(inline_html_event_source);
gadget_klass
rJS(window)
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareMethod("getContent", function () {
return {};
})
.declareMethod("render", function (options) {
.onStateChange(function () {
var gadget = this,
template = inline_status_template,
source = options.value.doc.source,
modification_date = options.value.doc.modification_date,
text_content = options.value.doc.text_content,
title = options.value.doc.title,
content_type = options.value.doc.content_type;
return new RSVP.Queue()
.push(function () {
if (content_type === 'text/html') {
template = inline_html_status_template;
}
gadget.element.innerHTML = template({
title: title,
author: source,
modification_date: modification_date,
message: text_content
});
});
header_text = "By " + gadget.state.author +
" on " + gadget.state.modification_date + ":",
header = domsugar("div", {
class: "slapos-event-discussion-message-header"
}, [
domsugar('p', {text: header_text})
]);
if (gadget.state.content_type === 'text/html') {
return domsugar(gadget.element, {}, [
header,
domsugar('div', {
class: "slapos-event-discussion-message-body",
text: gadget.state.text_content
})
]);
}
return domsugar(gadget.element, {}, [
header,
domsugar('div', {
class: "slapos-event-discussion-message-body"
}, [
domsugar("pre", {text: gadget.state.text_content})
])
]);
})
.declareMethod("render", function (options) {
var gadget = this;
return gadget.changeState({
author: options.value.doc.source,
modification_date: options.value.doc.modification_date,
text_content: options.value.doc.text_content,
content_type: options.value.doc.content_type
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, domsugar));
\ No newline at end of file
......@@ -222,7 +222,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superthomas</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>974.21419.16980.58675</string> </value>
<value> <string>1000.58263.12906.59494</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1552579622.59</float>
<float>1655128468.51</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -8,15 +8,9 @@
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="gadget_slapos_invoice_printout.js"></script>
<script id="download-link-template" type="text/x-handlebars-template">
<ul class="grid-items">
<li><a class="ui-btn ui-first-child ui-btn-icon-center" data-i18n="Download Invoice" target=_blank href={{invoice_url}} > <img src='pdf_icon.png'></img></a></li>
</ul>
</script>
</head>
<body>
<button data-i18n="loading" type="submit" class="responsive ui-btn ui-icon-spinner ui-icon-spin ui-btn-icon-center ui-disabled" style="border:none;">loading</button>
......
......@@ -240,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.60140.15778.40123</string> </value>
<value> <string>1000.58223.44192.61900</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -258,7 +258,7 @@
</tuple>
<state>
<tuple>
<float>1516361248.37</float>
<float>1655126135.42</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, window, rJS, RSVP, loopEventListener, i18n, Handlebars $*/
/*globals console, window, rJS, domsugar */
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window),
download_invoice_source = gadget_klass.__template_element
.getElementById("download-link-template")
.innerHTML,
download_invoice_template = Handlebars.compile(download_invoice_source);
gadget_klass
rJS(window)
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareMethod("getContent", function () {
return {};
})
.declareMethod("render", function (options) {
.onStateChange(function () {
var gadget = this;
return gadget.getElement()
.push(function (element) {
return gadget.getSetting("hateoas_url")
.push(function (hateoas_url) {
var link = hateoas_url + "/" +
options.value.jio_key +
"/SaleInvoiceTransaction_viewSlapOSPrintout";
element.innerHTML = download_invoice_template({
invoice_url: link
});
return element;
});
return gadget.getSetting("hateoas_url")
.push(function (hateoas_url) {
var link = hateoas_url + "/" +
gadget.state.jio_key +
"/SaleInvoiceTransaction_viewSlapOSPrintout";
return domsugar(gadget.element, {}, [
domsugar('ul', {class : 'grid-items'}, [
domsugar('li', {}, [
domsugar('a',
{
class: "ui-btn ui-first-child ui-btn-icon-center",
target: "_blank",
href: link
}, [
domsugar("img", {src: 'pdf_icon.png'})
])
])
])
]);
});
})
.declareMethod("render", function (options) {
var gadget = this;
return gadget.changeState({
jio_key: options.value.jio_key
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, domsugar));
\ No newline at end of file
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.60112.26500.11690</string> </value>
<value> <string>1000.58770.5501.41881</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1516360952.96</float>
<float>1656974249.61</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -8,21 +8,8 @@
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="handlebars.js"></script>
<script src="domsugar.js"></script>
<script src="gadget_slapos_invoice_state.js"></script>
<script id="payment-link-template" type="text/x-handlebars-template">
<ul class="grid-items">
<li><a class="ui-btn ui-first-child ui-btn-icon-center" data-i18n="Pay Now" href={{invoice_url}}> Pay Now</a></li>
</ul>
</script>
<script id="payment-state-template" type="text/x-handlebars-template">
<ul class="grid-items">
<li>{{invoice_state}}</li>
</ul>
</script>
</head>
<body>
<button data-i18n="loading" type="submit" class="responsive ui-btn ui-icon-spinner ui-icon-spin ui-btn-icon-center ui-disabled" style="border:none;">loading</button>
......
......@@ -240,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>964.60162.4991.21401</string> </value>
<value> <string>1000.58194.15602.170</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -258,7 +258,7 @@
</tuple>
<state>
<tuple>
<float>1516362382.75</float>
<float>1655123719.67</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, window, rJS, RSVP, loopEventListener, i18n, Handlebars $*/
/*globals console, window, rJS, RSVP, domsugar */
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, domsugar) {
"use strict";
var gadget_klass = rJS(window),
payment_link_source = gadget_klass.__template_element
.getElementById("payment-link-template")
.innerHTML,
payment_link_template = Handlebars.compile(payment_link_source),
payment_state_source = gadget_klass.__template_element
.getElementById("payment-state-template")
.innerHTML,
payment_state_template = Handlebars.compile(payment_state_source);
gadget_klass
.declareAcquiredMethod("jio_get", "jio_get")
rJS(window)
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getTranslationDict", "getTranslationDict")
.declareMethod("getContent", function () {
return {};
})
.declareMethod("render", function (options) {
var gadget = this;
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getElement(),
gadget.getSetting("hateoas_url")
.onStateChange(function () {
var gadget = this,
link;
return gadget.getTranslationDict(['Pay Now'])
.push(function (translation_dict) {
if (gadget.state.payment_transaction !== null) {
link = domsugar("li", {},
[
domsugar("a", {
class: "ui-btn ui-first-child ui-btn-icon-center",
// XXX Translation
text: translation_dict["Pay Now"],
href: gadget.state.hateoas_url + gadget.state.payment_transaction +
"/PaymentTransaction_redirectToManualSlapOSPayment"
})
]);
} else {
link = domsugar("li", {"text": gadget.state.payment_transaction});
}
domsugar(gadget.element, {}, [
domsugar("ul", {"class": "grid-items"}, [link])
]);
return translation_dict;
})
.push(function (result) {
var hateoas_url = result[1],
element = result[0];
})
.declareMethod("render", function (options) {
var gadget = this;
return gadget.getSetting("hateoas_url")
.push(function (hateoas_url) {
// XXX RAFAEL this should comes from the options and not from a query like this.
return gadget.jio_getAttachment(options.value.jio_key,
hateoas_url + options.value.jio_key +
"/AccountingTransaction_getPaymentStateAsHateoas")
.push(function (state) {
console.log(state);
var link, payment_transaction = state.payment_transaction;
if (payment_transaction !== null) {
link = payment_link_template({
invoice_state: state.state,
invoice_url: hateoas_url + payment_transaction +
"/PaymentTransaction_redirectToManualSlapOSPayment"
});
} else {
link = payment_state_template({
invoice_state: state.state
});
}
element.innerHTML = link;
return state;
return gadget.changeState({
payment_transaction: state.payment_transaction,
payment_state: state.state,
hateoas_url: hateoas_url
});
});
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, domsugar));
\ No newline at end of file
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>984.49089.34672.33348</string> </value>
<value> <string>1000.58215.43208.28603</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1593042198.73</float>
<float>1655125229.22</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -22,75 +22,39 @@
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="domsugar.js" type="text/javascript"></script>
<script src="gadget_global.js" type="text/javascript"></script>
<script id="panel-template-header" type="text/x-handlebars-template">
<div data-role="header" class="ui-bar-inherit">
<div class="ui-controlgroup ui-controlgroup-horizontal ui-btn-left">
<script src="gadget_slapos_utils.js" type="text/javascript"></script>
<script src="gadget_slapos_panel.js" type="text/javascript"></script>
</head>
<body>
<div>
<div data-role="header">
<div class="ui-btn-left">
<div class="ui-controlgroup-controls">
<button data-i18n="Close" class="ui-btn ui-btn-icon-notext ui-icon-delete">Close</button>
<button data-i18n="Close" class="ui-btn-icon-notext ui-icon-delete">Close</button>
</div>
</div>
<div class="panel_img">
<img class="ui-title" alt="SlapOS logo" src="gadget_slapos_panel.png?format=png"/>
</div>
</div>
</script>
<script id="panel-template-warning-link" type="text/x-handlebars-template">
<li><a href="#" id="attention-point-link" class="ui-btn-icon-notext ui-icon-warning attention-point-link">Warnings ({{amount}})</a></li>
</script>
<script id="panel-template-contextual-help" type="text/x-handlebars-template">
<dt class="ui-btn-icon-left ui-icon-question" data-i18n="Help">Help</dt>
{{#each contextual_help_list}}
<dd class="document-listview">
<a class="help" target="_blank" href="{{href}}">{{title}}</a>
</dd>
{{/each}}
</script>
<script id="panel-template-body" type="text/x-handlebars-template">
<div class="ui-content">
<ul data-role="listview" class="ui-listview" data-enhanced="true">
<li class="ui-first-child"><a href="{{instance_tree_href}}" class="ui-btn ui-btn-icon-left ui-icon-home" data-i18n="Services" accesskey="l">Services</a></li>
<li><a href="{{dashboard_href}}" class="ui-btn ui-btn-icon-left ui-icon-gears" data-i18n="Dashboard" accesskey="h">Dashboard</a></li>
<li><a href="{{person_href}}" class="ui-btn ui-btn-icon-left ui-icon-user" data-i18n="Login Account" accesskey="p">Account</a></li>
<li><a href="{{support_request_href}}" class="ui-btn ui-btn-icon-left ui-icon-comments" data-i18n="Tickets" accesskey="t">Tickets</a></li>
<li><a href="{{organisation_href}}" class="ui-btn ui-btn-icon-left ui-icon-map-marker" data-i18n="Sites" accesskey="k">Sites</a></li>
<li><a href="{{project_href}}" class="ui-btn ui-btn-icon-left ui-icon-cubes" data-i18n="Projects" accesskey="w">Projects</a></li>
<li><a href="{{accounting_href}}" class="ui-btn ui-btn-icon-left ui-icon-credit-card" data-i18n="Invoices" accesskey="i">Invoices</a></li>
<li><a href="{{compute_node_href}}" class="ui-btn ui-btn-icon-left ui-icon-database" data-i18n="Servers" accesskey="c">Servers</a></li>
<li><a href="{{computer_network_href}}" class="ui-btn ui-btn-icon-left ui-icon-globe" data-i18n="Networks" accesskey="n">Networks</a></li>
<li><a href="{{language_href}}" class="ui-btn ui-btn-icon-left ui-icon-language" data-i18n="Language" accesskey="a">Language</a></li>
<li class="ui-last-child"><a href="{{logout_href}}" class="ui-btn ui-btn-icon-left ui-icon-power-off" data-i18n="Logout" accesskey="o">Logout</a></li>
</ul>
<dl></dl>
<div>
<ul></ul>
<ul class="ul-attention-point"></ul>
<hr />
<ul data-role="listview" class="ui-listview" data-enhanced="true">
<li class="ui-first-child"><a href="https://monitor.app.officejs.com/" class="ui-btn ui-btn-icon-left ui-icon-desktop" data-i18n="Access Monitor" target="_blank">Access Monitor</a></li>
<li><a href="https://handbook.rapid.space" class="ui-btn ui-btn-icon-left ui-icon-book" data-i18n="Documentation" accesskey="d" target="_blank" rel="noopener noreferrer">Documentation</a></li>
</ul>
<dl></dl>
</div>
<div class="slapos_panel_extra_menu">
<div data-gadget-url="gadget_erp5_panel_shortcut.html"
data-gadget-scope="erp5_panel_shortcut"
data-gadget-sandbox="public"></div>
<dl></dl>
<ul data-role="listview" class="ui-listview ul-attention-point" data-enhanced="true">
<li></li>
</ul>
<dl class="dl-contextual-help">
</dl>
<dl class="dl-contextual-help"></dl>
</div>
</script>
<!-- custom script -->
<script src="gadget_slapos_utils.js" type="text/javascript"></script>
<script src="gadget_slapos_panel.js" type="text/javascript"></script>
</head>
<body>
<div class="jqm-navmenu-panel"></div>
</body>
</html>
\ No newline at end of file
......@@ -234,7 +234,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superthomas</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -248,7 +248,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>996.2197.3655.23739</string> </value>
<value> <string>1001.26171.19762.42854</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -266,7 +266,7 @@
</tuple>
<state>
<tuple>
<float>1639502126.27</float>
<float>1657228115.43</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -241,7 +241,7 @@
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>superthomas</string> </value>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
......@@ -255,7 +255,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>987.59252.10760.63197</string> </value>
<value> <string>1001.36662.17855.30088</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -273,7 +273,7 @@
</tuple>
<state>
<tuple>
<float>1607070942.23</float>
<float>1657677595.88</float>
<string>UTC</string>
</tuple>
</state>
......
/*globals console, window, rJS, RSVP, loopEventListener, i18n, Handlebars $*/
/*globals console, window, rJS, RSVP, domsugar */
/*jslint indent: 2, nomen: true, maxlen: 80*/
(function (window, rJS, RSVP, Handlebars) {
(function (window, rJS, RSVP, domsugar) {
"use strict";
var gadget_klass = rJS(window),
message_source = gadget_klass.__template_element
.getElementById("message-template")
.innerHTML,
message_template = Handlebars.compile(message_source);
gadget_klass
.declareAcquiredMethod("jio_get", "jio_get")
rJS(window)
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("translateHtml", "translateHtml")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("updateHeader", "updateHeader")
......@@ -28,19 +19,21 @@
if (return_page === undefined) {
return_page = "slap_invoice_list";
}
// XXX RAFAEL Missing change state
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getElement(),
gadget.getTranslationDict(["Return to Invoice List"]),
gadget.getUrlFor({command: 'change',
options: {jio_key: "/", page: return_page, "result": ""}})
]);
})
.push(function (result) {
var payment_url = result[1],
element = result[0],
message, advice, page_title;
translation_dict = result[0],
message,
advice,
page_title;
if (options.result === "success") {
page_title = "Thank you for your Payment";
message = "Thank you for finalising the payment.";
......@@ -71,11 +64,27 @@
} else {
throw new Error("Unknown action to take: " + options.result);
}
element.innerHTML = message_template({
message_to_acknowledge: message,
advice: advice,
payment_url: payment_url
});
domsugar(gadget.element, {},
[
domsugar("p", {}, [
domsugar("center", {}, [
domsugar("strong", {text: message})
])
]),
domsugar("p", {}, [
domsugar("center", {text: advice})
]),
domsugar("p"),
domsugar("p", {}, [
domsugar("center", {}, [
domsugar("a", {
class: "ui-btn ui-first-child ui-btn-icon-center",
href: payment_url,
text: translation_dict["Return to Invoice List"]
})
])
])
]);
return page_title;
})
.push(function (page_title) {
......@@ -85,4 +94,4 @@
return gadget.updateHeader(header_dict);
});
});
}(window, rJS, RSVP, Handlebars));
\ No newline at end of file
}(window, rJS, RSVP, domsugar));
\ No newline at end of file
......@@ -236,7 +236,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>984.11864.24475.17493</string> </value>
<value> <string>1000.2322.46712.16657</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -254,7 +254,7 @@
</tuple>
<state>
<tuple>
<float>1590639279.1</float>
<float>1655131980.97</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -402,7 +402,7 @@
</item>
<item>
<key> <string>configuration_content_security_policy</string> </key>
<value> <string>default-src \'self\'; img-src \'self\' data: *.openstreetmap.org; media-src \'self\' blob:; connect-src \'self\' data: lab.node.vifib.com lab.nexedi.com; script-src \'self\' \'unsafe-eval\'; font-src \'self\'; style-src \'self\' data: \'unsafe-inline\'; frame-src \'self\' data:</string> </value>
<value> <string>default-src \'self\'; img-src \'self\' data: *.openstreetmap.org; media-src \'self\' blob:; connect-src \'self\' data: lab.node.vifib.com lab.nexedi.com; script-src \'self\'; font-src \'self\'; style-src \'self\' data: \'unsafe-inline\'; frame-src \'self\' data:</string> </value>
</item>
<item>
<key> <string>configuration_default_jio_document_page_gadget_url</string> </key>
......@@ -701,7 +701,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>999.2068.62564.17</string> </value>
<value> <string>1000.41365.61594.63982</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -719,7 +719,7 @@
</tuple>
<state>
<tuple>
<float>1652448693.65</float>
<float>1654507392.23</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -121,6 +121,8 @@ elif context.getPortalType() == "Organisation Module":
# Translate titles
for contextual_help in contextual_help_list:
# Preserve untranslated title for reference.
contextual_help['data-i18n'] = contextual_help['title']
contextual_help['title'] = context.Base_translateString(contextual_help['title'])
return json.dumps(contextual_help_list)
......@@ -94,58 +94,134 @@
<tal:block define="menu_item python: 'Tickets'; header menu_item ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Add Tickets"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Add Tickets"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tal:block define="menu_item python: 'Sites'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Classify Nodes"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Classify Nodes"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tal:block define="menu_item python: 'Projects'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Add Projects"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Add Projects"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tal:block define="menu_item python: 'Invoices'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Payment Options"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Payment Options"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
</tal:block>
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Use Panel"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Use Panel"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Associate Compute Nodes"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Associate Compute Nodes"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tal:block define="menu_item python: 'Networks'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
<!-- Ensure contextual help displays fine on the panel-->
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Add Networks"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//a[@class="help" and @data-i18n="Add Networks"]</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tal:block define="menu_item python: 'Language'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item_language" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_contextual_help" />
</tal:block>
<tr>
......
......@@ -312,6 +312,8 @@
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/suspend_user_tickets" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Servers'; header menu_item">
......@@ -344,6 +346,72 @@
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="Ticket waiting your response"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="Ticket waiting your response"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="Ticket waiting your response"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Support Request : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '2'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tal:block define="menu_item python: 'Servers'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Compute Node: ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tr>
<td colspan="3"><b> Update Allocation Scope</b></td>
</tr>
......
......@@ -438,6 +438,8 @@
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/suspend_user_tickets" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="menu_item python: 'Services'; header menu_item">
......@@ -476,6 +478,83 @@
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="Ticket waiting your response"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="Ticket waiting your response"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="Ticket waiting your response"]</td>
<td></td>
</tr>
<tal:block tal:define="header python: 'Support Request : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '2'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED NEW MESSAGE</td>
<td></td>
</tr>
<tal:block define="menu_item python: 'Services'; header menu_item">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>waitForElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
<td>assertElementPresent</td>
<td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
<td></td>
</tr>
<tal:block define="menu_action python: 'Destroy'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
......
from DateTime import DateTime
portal = context.getPortalObject()
portal_membership=portal.portal_membership
demo_user_functional = portal_membership.getAuthenticatedMember().getUserValue()
for support_request in portal.portal_catalog(
portal_type="Support Request",
simulation_state="validated",
default_destination_decision_uid=demo_user_functional.getUid()):
if support_request.getSimulationState() == 'validated':
support_request.suspend()
return 'Done.'
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_suspendUserSupportRequest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -1172,12 +1172,36 @@
<tal:block metal:define-macro="check_contextual_help">
<tr>
<td>waitForElementPresent</td>
<td>//div[@class="ui-content"]</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//div[@class="slapos_panel_extra_menu"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[@class="ui-content"]</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//div[@class="slapos_panel_extra_menu"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//dl[@class="dl-contextual-help"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//div[contains(@data-gadget-url, 'gadget_slapos_panel.html')]//dl[@class="dl-contextual-help"]</td>
<td></td>
</tr>
</tal:block>
<tal:block metal:define-macro="suspend_user_tickets">
<tr>
<td>openAndWait</td>
<td>${base_url}/ERP5Site_suspendUserSupportRequest</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
</tal:block>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment