Version 10 (modified by 5年 ago) (diff) | ,
---|
Ticket 问题描述模板定义规则
按照下面的格式定义:
- 使用== 开头定义模板名字,这个名字会显示在模板选择列表里
- 使用{{{、}}}将模板内容包含起来,模板内容可以是任意符合wiki语法的文本
== 模板名字 {{{ 模板内容 }}}
补丁申请模板(html)
<!-- html template --> <style type="text/css"> tr.panel-row textarea { height: 85px; padding-right: 0.4em; } .required-field-label { color: red; } input.date-picker { width: 100px; } #propertyform table.trac-properties { table-layout: unset; } #properties table.trac-properties > tbody > tr > th.col2 { border-left: 0px; } #properties table.trac-properties > tbody > tr > td.col1 { width: 28.2%; } #properties table.trac-properties > tbody > tr > td.col2 { width: 15%; } #propertyform table select { width: 99%; } #content.ticket { width: 68em; } #properties table.trac-properties > tbody > tr > th, #properties table.trac-properties > colgroup > col.th { width: 12.5%; } #propertyform table.trac-properties td input[type="text"], #propertyform table.trac-properties td textarea { width: 99%; } #properties table.trac-properties > tbody > tr > td, #properties table.trac-properties > colgroup > col.td { width: 0%; } .textarea-toolbar { margin-top: 0.3em; margin-left: 0.2em; border: solid #d7d7d7; border-width: 1px 1px 1px 0; height: 18px; width: 52px; } .textarea-toolbar :link, .textarea-toolbar :visited { background: transparent url(raw-attachment/wiki/TicketDescriptionTemplates/toolbar.png) no-repeat; border: 1px solid #fff; border-left-color: #d7d7d7; cursor: default; display: block; float: left; width: 24px; height: 16px; } .textarea-toolbar :link:hover, .textarea-toolbar :visited:hover { ckground-color: transparent; border: 1px solid #fb2; } .textarea-toolbar a#em { background-position: 0 0 } .textarea-toolbar a#strong { background-position: 0 -16px } </style> <script type="text/javascript"> String.prototype.replaceAll = function(exp, newStr) { return this.replace(new RegExp(exp, "gm"), newStr); } String.prototype.format = function(args) { var result = this; if (arguments.length < 1) return result; var data = arguments; if (arguments.length == 1 && typeof(args) == "object") data = args; for (var key in data) { var value = data[key]; if (undefined != value) result = result.replaceAll("\\{" + key + "\\}", value); } return result; } function clearDescriptionCookie() { $.cookie("description_panel", ""); } function getDescriptionCookie() { return $.cookie("description_panel"); } function setDescriptionCookie(value) { $.cookie("description_panel", value); } function createDescriptionPanel() { function updateDescriptionForServer(event) { var found_empty_field = false; var required_elements = $(".required-field"); for (var i = 0; i < required_elements.length; i++) { if ($(required_elements.get(i)).val() == "") { found_empty_field = true; break; } } if (found_empty_field) { event.preventDefault(); alert('有必填项为空,请补充。带 * 的为必填项。'); } var data = populateDescription(); if (data != null) { setDescriptionCookie(data.panel_info); $("#field-description").val(data.description); } } if (/msie/.test(navigator.userAgent.toLowerCase())) { $("#content").prepend('<div id="browser-warning" class="system-message">检测到浏览器为 IE,由于 IE 浏览器兼容性不好,请使用 Chrome 或 Firefox 浏览器</div>'); $("#browser-warning").css("background-color", "#ffb"); $("#browser-warning").css("border", "1px solid #500"); $("input:submit[name='preview']").remove(); $("input:submit[name='submit']").remove(); } else { $("input:submit[name='preview']").click(function(event) { updateDescriptionForServer(event); }); $("input:submit[name='submit']").click(function(event) { updateDescriptionForServer(event); }); } var template = $("#panel tbody").html(); $("#panel").remove(); var description_row = $("label#field-description-help").parent().parent(); description_row.css("display", "none"); description_row.before(template); $("#field-summary").parent().attr("colspan", "5"); $("#field-reporter").parent().attr("colspan", "5"); $("#properties table th").css("vertical-align", "super"); var required_fields = [ 'field-summary', 'field-reporter', 'field-type', 'field-component', 'field-priority', 'field-severity', 'field-version', 'field-chip' ]; for (var i = 0; i < required_fields.length; i++) { var element = $("label[for='{0}']".format(required_fields[i])); if (element.length != 0) { var text = element.html().replace(':', ''); element.html('{label} <span class="required-field-label">*</span>:'.format({label: text})); } $('#{0}'.format(required_fields[i])).attr("class", "required-field"); } $(".date-picker").datepicker({ changeMonth: true, changeYear: true, onClose: function(date_text, picker) { var warning_tip = $(this).parent().find("span.empty-warning"); if (warning_tip.length != 0) warning_tip.remove(); } }); $(".date-picker").datepicker("option", "dateFormat", "yy-mm-dd"); if (window.location.href.split(window.location.host)[1] != $("#propertyform").attr("action")) { clearDescriptionCookie(); } $("#developer-resolve-date").val("[=#developer-resolve-date]"); $(".required-field").blur(function(event) { var warning_tip = $(event.target).parent().find("span.empty-warning"); if ($(event.target).val() == "") { if (warning_tip.length == 0) $(event.target).parent().append('<span class="required-field-label empty-warning">内容不能为空</span>'); } else { if (warning_tip.length != 0) warning_tip.remove(); } }); var description_panel = getDescriptionCookie(); if (description_panel != undefined && description_panel != "") { var panel_info = JSON.parse(description_panel); $(".panel-row label").each(function(index, element) { var text_element = $(element).parent().next("td").find("input:text")[0]; if (text_element == undefined) { text_element = $(element).parent().next("td").find("textarea")[0]; } if ($(text_element).attr("class") != undefined && $(text_element).attr("class").match(/date-picker/) != null) $(text_element).datepicker("setDate", panel_info[index]); else $(text_element).val(panel_info[index]); }); } function addToolbarButton(toolbar, id, title, click_fn) { var a = document.createElement("a"); a.href = "#"; a.id = id; a.title = title; a.onclick = function() { if ($(toolbar.target_textarea).prop("disabled") === false && $(toolbar.target_textarea).prop("readonly") === false) { try { click_fn() } catch (e) {} } return false; }; a.tabIndex = 400; toolbar.appendChild(a); } function encloseSelection(textarea, prefix, suffix) { textarea.focus(); var start, end, sel, scrollPos, subst; if (document.selection != undefined) { sel = document.selection.createRange().text; } else if (textarea.setSelectionRange != undefined) { start = textarea.selectionStart; end = textarea.selectionEnd; scrollPos = textarea.scrollTop; sel = textarea.value.substring(start, end); } if (sel.match(/ $/)) { sel = sel.substring(0, sel.length - 1); suffix = suffix + " "; } subst = prefix + sel + suffix; if (document.selection != undefined) { var range = document.selection.createRange().text = subst; textarea.caretPos -= suffix.length; } else if (textarea.setSelectionRange != undefined) { textarea.value = textarea.value.substring(0, start) + subst + textarea.value.substring(end); if (sel) { textarea.setSelectionRange(start + subst.length, start + subst.length); } else { textarea.setSelectionRange(start + prefix.length, start + prefix.length); } textarea.scrollTop = scrollPos; } } $("textarea.toolbar").each(function(index, element) { if ($(element).prev('div.textarea-toolbar').length == 0) { $(element).before('<div class="textarea-toolbar"></div>'); var toolbar = $(element).prev('div.textarea-toolbar').get(0); toolbar.target_textarea = element; addToolbarButton(toolbar, "strong", "插入 C 代码块", function() {encloseSelection(element, "\n{{{#!c\n", "\n}}}\n");}); addToolbarButton(toolbar, "em", "插入 C++ 代码块", function() {encloseSelection(element, "\n{{{#!cpp\n", "\n}}}\n");}); } }); } function populateDescription() { var boundary = "|------"; var panel_info = []; var description = ""; var exchange_tags = [] $(".panel-row").each(function(index, element) { var labels = $(element).find("th label"); var row_data = []; var title = $(element).attr("title"); description += "== " + title + "\n"; if (labels.length == 1) { var value = $(element).find("td").children("input:text").val(); if (value == undefined) { value = $(element).find("td").children("textarea").val(); } if (title == "出错日志") description += "{{{\n" + value + "\n}}}\n"; else description += value + "\n"; panel_info.push(value); } else { var values = $(element).find("td input:text"); for (var i = 0; i < labels.length; i++) { var label_name = $(labels.get(i)).text(); label_name = label_name.replace(/\s*\*/, ''); var input_val = $(values.get(i)).val(); var label_class = $(labels.get(i)).attr("class"); var tag = null; if (label_class != undefined) { var matched = label_class.match(/exchange-\d+/); if (matched != null) { tag = matched[0]; exchange_tags.push(tag); } } if (tag != null) description += '- <{tag}>{label_name}{input_val}</{tag}>\n'.format({tag:tag, label_name:label_name, input_val:input_val}); else description += '- {label_name}{input_val}\n'.format({label_name:label_name, input_val:input_val}); panel_info.push(input_val); } } description += boundary + "\n"; }); for (var i = 0; i < exchange_tags.length; i++) { var tag = exchange_tags[i]; var tag_pattern = new RegExp('<{tag}>.*</{tag}>'.format({tag:tag}), 'g'); var content_pattern = new RegExp('<{tag}>(.*)</{tag}>'.format({tag:tag})); var matched = description.match(tag_pattern); if (matched != null) { description = description.replace(matched[0], matched[1].match(content_pattern)[1]); description = description.replace(matched[1], matched[0].match(content_pattern)[1]); } } return {panel_info: JSON.stringify(panel_info), description: description}; } </script> <table id="panel"> <tbody> <tr title="问题描述" class="panel-row"> <th><label>问题描述 <span class="required-field-label">*</span>:</label></th> <td colspan="5"><textarea class="required-field toolbar"></textarea></td> </tr> <tr title="问题场景" class="panel-row"> <th><label>问题场景 <span class="required-field-label">*</span>:</label></th> <td colspan="5"><textarea class="required-field toolbar"></textarea></td> </tr> <tr title="复现步骤" class="panel-row"> <th><label>复现步骤 <span class="required-field-label">*</span>:</label></th> <td colspan="5"><textarea class="required-field toolbar"></textarea></td> </tr> <tr title="出错日志" class="panel-row"> <th><label>出错日志:</label></th> <td colspan="5"><textarea></textarea></td> </tr> <tr title="初步定位" class="panel-row"> <th><label>初步定位:</label></th> <td colspan="5"><textarea class="toolbar"></textarea></td> </tr> <tr title="问题处理时间段" class="panel-row"> <th><label>发现日期 <span class="required-field-label">*</span>:</label></th> <td><input type="text" id="issue-occur-date" class="date-picker required-field"></td> <th><label class="exchange-1">沟通联系人 <span class="required-field-label">*</span>:</label></th> <td><input type="text" class="required-field"></td> <th style="display: none"><label>开发人员预期解决日期:</label></th> <td style="display: none"><input type="text" id="developer-resolve-date"></td> </tr> <tr title="联系人信息" class="panel-row"> <th><label class="exchange-1">期望解决日期 <span class="required-field-label">*</span>:</label></th> <td><input type="text" id="issue-resolve-date" class="date-picker required-field"></td> <th><label>电话 <span class="required-field-label">*</span>:</label></th> <td><input type="text" class="required-field"></td> <th style="width: 30px"><label>邮箱:</label></th> <td><input type="text" style="width: 96%;"></td> </tr> </tbody> </table>
附件 (1)
- toolbar.png (1.0 KB) - added by 5年 ago.
Download all attachments as: .zip