Mercurial > p > roundup > code
view website/issues/html/issue.item.html @ 8106:47f0a4eba1b2
fix: fix key for broken translation template in admin.py
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Wed, 07 Aug 2024 21:11:13 -0400 |
| parents | 12c5ddf865b1 |
| children | 63390dcfcfe9 |
line wrap: on
line source
<tal:block metal:use-macro="templates/page/macros/icing"> <title metal:fill-slot="head_title"> <tal:block condition="context/id" i18n:translate="" >Issue <span tal:replace="context/id" i18n:name="id" />: <span tal:replace="context/title" i18n:name="title" /> - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" /></tal:block> <tal:block condition="not:context/id" i18n:translate="" >New Issue - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" /></tal:block> </title> <tal:block metal:fill-slot="body_title"> <span tal:condition="python: not (context.id or context.is_edit_ok())" tal:omit-tag="python:1" i18n:translate="">New Issue</span> <span tal:condition="python: not context.id and context.is_edit_ok()" tal:omit-tag="python:1" i18n:translate="">New Issue Editing</span> <span tal:condition="python: context.id and not context.is_edit_ok()" tal:omit-tag="python:1" i18n:translate="">Issue <tal:x replace="context/id" i18n:name="id" /></span> <span tal:condition="python: context.id and context.is_edit_ok()" tal:omit-tag="python:1" i18n:translate="">Issue<tal:x replace="context/id" i18n:name="id" /> Editing</span> </tal:block> <td class="content" metal:fill-slot="content"> <p tal:condition="python:not (context.is_view_ok() or request.user.hasRole('Anonymous'))" i18n:translate=""> You are not allowed to view this page.</p> <p tal:condition="python:not context.is_view_ok() and request.user.hasRole('Anonymous')" i18n:translate=""> Please login with your username and password.</p> <div tal:condition="context/is_view_ok"> <form method="POST" name="itemSynopsis" onSubmit="return submit_once()" enctype="multipart/form-data" tal:attributes="action context/designator"> <fieldset><legend>classification</legend> <table class="form"> <tr> <th class="required"><label for="title" i18n:translate="">Title:</label></th> <td colspan="3" tal:condition="context/title/is_edit_ok" tal:content="structure python:context.title.field(id='title', size=60)">title</td> <td colspan="3" tal:condition="not:context/title/is_edit_ok"> <span tal:content="structure context/title/plain"/> <input type="hidden" name="title" tal:attributes="value context/title"> </td> </tr> <tr> <th class="required" i18n:translate=""> <span tal:replace="structure python:db.issue_type.classhelp('id,name,description',label='Type')" />: </th> <td tal:content="structure context/type/menu">type</td> <th i18n:translate=""> <span tal:replace="structure python:db.severity.classhelp('id,name,description',label='Severity')" />: </th> <td tal:content="structure context/severity/menu">components</td> </tr> <tr> <th i18n:translate=""> <span tal:replace="structure python:db.component.classhelp('id,name,description',label='Components')" />: </th> <td tal:content="structure context/components/menu">components</td> <th i18n:translate=""> <span tal:replace="structure python:db.version.classhelp('id,name,description',label='Versions')" />: </th> <td tal:content="structure context/versions/menu">versions</td> </tr> </table> </fieldset> <fieldset><legend>process</legend> <table class="form"> <tr tal:condition="context/id"> <th i18n:translate=""> <span tal:replace="structure python:db.status.classhelp('id,name,description',label='Status')" />: </th> <td tal:content="structure context/status/menu">status</td> <th><label for="resolution" i18n:translate="">Resolution:</label></th> <td tal:content="structure python:context.resolution.menu(html_kwargs={'id':'resolution'})">resolution</td> </tr> <tr tal:condition="context/id"> <th> <label for="dependencies" i18n:translate="">Dependencies</label> <span tal:condition="context/dependencies/is_edit_ok" tal:replace="structure python:db.issue.classhelp('id,title', filter='status=0,1', property='dependencies')" /> </th> <td> <span tal:replace="structure python:context.dependencies.field(id='dependencies',showid=1,size=20)" /> <span tal:condition="context/dependencies" tal:repeat="d python:context.dependencies.sorted('creation')"> <br/>View: <a tal:attributes="href string:issue${d/id}" tal:content="d/id"></a> </span> </td> <th> <tal:block><label for="superseder" i18n:translate="">Superseder</label></tal:block>: <span tal:condition="context/superseder/is_edit_ok" tal:replace="structure python:db.issue.classhelp('id,title', filter='status=0,1', property='superseder')" /> </th> <td> <span tal:replace="structure python:context.superseder.field(id='superseder', showid=1, size=20)" /> <span tal:condition="context/superseder"> <!-- <br><span i18n:translate="">View</span>: <a tal:repeat="sup context/superseder" tal:content="python:sup['id'] + ', '*(not repeat['sup'].end)" tal:attributes="href string:issue${sup/id}; title sup/title;"></a> --> <br><span i18n:translate="">View</span>: <a tal:content="context/superseder/id" tal:attributes="href string:issue${context/superseder/id}; title context/superseder/title;"></a> </span> </td> </tr> <tr> <th><label for="assignee" i18n:translate="">Assigned To</label>:</th> <td tal:condition="context/status/is_edit_ok"> <select id="assignee" name="assignee"> <option value="-1">nobody</option> <tal:block tal:repeat="userdata python:db._db.user.filter_sql('select id,_username from _user where _roles like \'%Developer%\' order by _username')"> <option tal:attributes="value python:userdata[0]; selected python:str(userdata[0]) == context.assignee._value" tal:content="python:userdata[1]"></option> </tal:block> </select> </td> <td tal:condition="not:context/assignee/is_edit_ok"> <span tal:replace="structure context/assignee/plain" /> </td> <th><label for="nosy" i18n:translate="">Nosy List</label>: <span tal:condition="context/nosy/is_edit_ok" tal:replace="structure python:db.user.classhelp('username,realname,address', property='nosy')" /> </th> <td> <span tal:replace="structure python:context.nosy.field(id='nosy')" /> </td> </tr> <tr> <th> <span tal:replace="structure python:db.priority.classhelp('id,name,description',label='Priority')" />: </th> <td tal:content="structure context/priority/menu">priority</td> <th><label for="keywords" i18n:translate="">Keywords</label>:</th> <td tal:content="structure python:context['keywords'].menu(height=5,html_kwargs={'id': 'keywords'})">keywords</td> </tr> <tr tal:condition="context/is_edit_ok"> <th><label for="@note" i18n:translate="">Comment</label>:</th> <td colspan="3"> <textarea tal:content="request/form/@note/value | default" id="@note" name="@note" wrap="hard" rows="10" cols="72"></textarea> </td> </tr> <tr tal:condition="context/is_edit_ok"> <th><label for="file-1@content" i18n:translate="">File</label>:</th> <td> <input type="hidden" name="@link@files" value="file-1"> <input type="file" id="file-1@content" name="file-1@content" size="40"> </td> <th><label for="file-1@description" i18n:translate="">File Description</label>:</th> <td colspan=3><input type="text" class="fileDesc" id="file-1@description" name="file-1@description" size="40"></td> </tr> <tr tal:condition="context/is_edit_ok"> <td colspan=4> <textarea readonly id="DropZone" aria-labeledby="DropZone"> paste images or drag and drop files here.... </textarea> </td> </tr> </table> </fieldset> <table class="form"> <tr tal:condition="context/is_edit_ok"> <td> <input type="hidden" name="@template" value="item"> <input type="hidden" name="@required" value="title"> </td> <td colspan=3> <span tal:replace="structure context/submit">submit button</span> <a tal:condition="context/id" tal:attributes="href context/copy_url" i18n:translate="">Make a copy</a> </td> </tr> </table> </form> <!-- drag and drop code --> <script tal:attributes="nonce request/client/client_nonce"> /* multiple file drops cause issues with redefined file-X@content issues. input multiple assumes it can start numbering from 1 for each of the multiple files. However numbering here does the same leading to duplicate file-2@content. layout needs some work, alignnment of new file input's isn't great. Need a way to delete or reset file inputs so file assigned to them isn't uploaded. Clicking on button in chrome and then canceling unsets the file. But this sequence does nothing in firefox. Pasting always uses image.<type> can't name file. Need to query user during paste for name/description. */ let newInput=null; let NextInputNum = 100; /* file input 1 is hardcoded in form. It is a multiple file input control. To prevent collision, we start dynamic file controls at file-100@content. 100 is larger than we expect the number of files uploaded using file input 1.*/ let target = document.getElementById('DropZone'); target.style.display = "block"; let body = document.body; let fileInput = document.getElementById('file-1@content'); let fileDesc = document.getElementById('file-1@description'); function make_clear_fileInput_closure(input) { return function(ev) { input.value = ""; ev.preventDefault();} } function make_new_clear_button() { newClearInput=document.createElement('button'); newClearInput.textContent = "X"; newClearInput.setAttribute("aria-label", "Clear next file input."); newClearInput.setAttribute("title", "Clear next file input."); newClearInput.classList.add("clearButton"); return newClearInput; } function make_new_file_input() { newInput=document.createElement('input'); newInput.type="file"; newInput.id="file-" + NextInputNum +"@content"; newInput.name=newInput.id; return newInput; } function add_file_input () { // Only allow one change listener on newest input. fileInput.removeEventListener('change', add_file_input, false); newClearInput = fileInput.insertAdjacentElement( 'beforebegin', make_new_clear_button()); // add change handler to file clear button newClearInput.addEventListener('click', make_clear_fileInput_closure(fileInput), false); /* Insert break so next input is on new line */ br = fileInput.insertAdjacentElement('afterend', document.createElement('br')); /* create new file input to get next dragged file */ /* <input type="file" name="file-2@content"> for 2, 3, 4, ... */ fileInput = br.insertAdjacentElement('afterend', make_new_file_input()); // add change hander to newest file input fileInput.addEventListener('change', add_file_input, // create new input for more files false); /* link file-N to list of files on issue. also link to msg-1 */ addLink=document.createElement('input'); addLink.type="hidden"; addLink.id="@link@file=file-" + NextInputNum; addLink.name="@link@files" addLink.value="file-" + NextInputNum; fileInput.insertAdjacentElement('afterend', addLink); addLink=document.createElement('input'); addLink.type="hidden"; addLink.id="msg-1@link@files=file-" + NextInputNum; addLink.name="msg-1@link@files" addLink.value="file-" + NextInputNum fileInput.insertAdjacentElement('afterend', addLink); /* break line before description field to prevent wrapping multiple descriptions onto one line when zoomed out or large display.*/ br = fileDesc.insertAdjacentElement('afterend', document.createElement('br')); fileDesc=document.createElement('input'); fileDesc.type="text"; fileDesc.id="file-" + NextInputNum + "@description"; fileDesc.name=fileDesc.id fileDesc.size = 40 fileDesc.classList.add("fileDesc"); fileDesc=br.insertAdjacentElement('afterend', fileDesc); NextInputNum = NextInputNum+1; } function MarkDropZone(e, active) { active == true ? e.style.backgroundColor = "goldenrod" : e.style.backgroundColor = ""; } fileInput.addEventListener('change', add_file_input, // create new input for more files false); target.addEventListener('dragover', (e) => { e.preventDefault(); body.classList.add('dragging'); }); target.addEventListener('dragenter', (e) => { e.preventDefault(); MarkDropZone(target, true); }); target.addEventListener('dragleave', (e) => { e.preventDefault(); MarkDropZone(target, false); }); target.addEventListener('dragleave', () => { body.classList.remove('dragging'); }); target.addEventListener('drop', (e) => { body.classList.remove('dragging'); MarkDropZone(target, false); // Only allow single file drop unless // fileInput name is @file that can support // multiple file drop and file drop is multiple. if (( fileInput.name != "@file" || ! fileInput.hasAttribute('multiple')) && e.dataTransfer.files.length != 1 ) { alert("File input can only accept one file.") e.preventDefault(); return } // set file input files to the dragged files fileInput.files = e.dataTransfer.files; add_file_input(); // create new input for more files // run last otherwise firefox empties e.dataTransfer e.preventDefault(); }); target.addEventListener('mouseover', (e) => { e.preventDefault(); MarkDropZone(target, true); }); target.addEventListener('mouseout', (e) => { e.preventDefault(); MarkDropZone(target, false); }); target.addEventListener('paste', (event) => { // https://mobiarch.wordpress.com/2013/09/25/upload-image-by-copy-and-paste/ // add paste event listener to the page // https://stackoverflow.com/questions/50427513/ // html-paste-clipboard-image-to-file-input if ( event.clipboardData.files.length == 0) { // if not file data alert alert("No image found for pasting"); event.preventDefault(); return; } fileInput.files = event.clipboardData.files; /* Possible enhancement if file check fails. iterate over all items 0 ...: event.clipboardData.items.length look at all items[i].kind for 'string' and items[i].type looking for a text/plain item. If found, event.clipboardData.items[1].getAsString( callback_fcn(s)) where callback function that creates a new dataTransfer object with a file and insert the content s and assigns it to the input. https://gist.github.com/guest271314/7eac2c21911f5e40f489\33ac78e518bd */ add_file_input(); // create new input for more files // do not paste contents to dropzone event.preventDefault(); }, false); </script> <style tal:attributes="nonce request/client/client_nonce"> #FileArea button.clearButton ~ input[type=file] {display:inline-block;} #DropZone { /* don't display dropzone by default. Displayed as block by javascript. */ display:none; width: 100%; /* override textarea inset */ border-style: dashed; padding: 3ex 0; /* larger dropzone */ /* add space below inputs */ margin-block-start: 1em; /* lighter color */ background: rgba(255,255,255,0.4); } input[id$=\@content], input.fileDesc {margin-block-end: 0.5em} </style> <p tal:condition="context/id" i18n:translate=""> Created on <b><tal:x replace="python:context.creation.pretty('%Y-%m-%d %H:%M')" i18n:name="creation" /></b> by <b><tal:x replace="context/creator" i18n:name="creator" /></b>, last changed <b><tal:x replace="python:context.activity.pretty('%Y-%m-%d %H:%M')" i18n:name="activity" /></b> by <b><tal:x replace="context/actor" i18n:name="actor" /></b>. </p> <table class="files" tal:condition="context/files"> <tr><th colspan="5" class="header" i18n:translate="">Files</th></tr> <tr> <th i18n:translate="">File name</th> <th i18n:translate="">Uploaded</th> <th i18n:translate="">Description</th> <th i18n:translate="">Edit</th> <th i18n:translate="">Remove</th> </tr> <tr tal:repeat="file python:context.files.sorted('creation')"> <td> <a tal:attributes="href file/download_url" tal:content="file/name">dld link</a> </td> <td> <span tal:content="file/creator">creator's name</span>, <span tal:content="python:file.creation.pretty('%Y-%m-%d %H:%M')">creation date</span> </td> <td tal:content="file/description" /> <td><a tal:condition="file/is_edit_ok" tal:attributes="href string:file${file/id}">edit</a> </td> <td> <form style="padding:0" method="POST" tal:condition="file/is_edit_ok" tal:attributes="action string:issue${context/id}"> <input type="hidden" name="@remove@files" tal:attributes="value file/id"> <input type="hidden" name="@action" value="edit"> <input type="submit" value="remove" i18n:attributes="value"> </form> </td> </tr> </table> <table class="messages" tal:condition="context/messages"> <tr><th colspan="4" class="header" i18n:translate="">Messages</th></tr> <tal:block tal:repeat="msg context/messages"> <tr> <th><a tal:attributes="href string:msg${msg/id}" i18n:translate="">msg<tal:x replace="msg/id" i18n:name="id" /></a></th> <th i18n:translate="">Author: <tal:x replace="python:msg.author.realname.plain()" i18n:name="author" /> (<tal:x replace="msg/author"/>)</th> <th i18n:translate="">Date: <tal:x replace="python:msg.date.pretty('%Y-%m-%d %H:%M')" i18n:name="date" /></th> <th> <form style="padding:0" method="POST" tal:condition="msg/is_edit_ok" tal:attributes="action string:issue${context/id}"> <input type="hidden" name="@remove@messages" tal:attributes="value msg/id"> <input type="hidden" name="@action" value="edit"> <input type="submit" value="remove" i18n:attributes="value"> </form> </th> </tr> <tr> <td colspan="4" class="content"> <pre tal:condition="python:msg.content.is_view_ok()" tal:content="structure python:utils.localReplace(msg.content.hyperlinked())">content</pre> </td> </tr> </tal:block> </table> <tal:block tal:condition="context/id" tal:replace="structure context/history" /> </div> </td> </tal:block> <!-- SHA: ad841842c0da5f9d1a7f69a1e0c847a549b75bf2 -->
