This is an automated email from the ASF dual-hosted git repository.
brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git
The following commit(s) were added to refs/heads/master by this push:
new d5753a87f [#8577] notes can be added to a project in the new projects
section
d5753a87f is described below
commit d5753a87ffe9b48b0ddd29a0eb2b9bd55432d821
Author: Guillermo Cruz <[email protected]>
AuthorDate: Thu Apr 24 11:08:32 2025 -0600
[#8577] notes can be added to a project in the new projects section
---
Allura/allura/controllers/site_admin.py | 12 +++++
.../allura/templates/site_admin_new_projects.html | 58 ++++++++++++++++++++++
Allura/allura/tests/functional/test_site_admin.py | 12 +++--
3 files changed, 79 insertions(+), 3 deletions(-)
diff --git a/Allura/allura/controllers/site_admin.py
b/Allura/allura/controllers/site_admin.py
index a4af8ecad..28e678a4b 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -213,6 +213,18 @@ def new_projects(self, **kwargs):
'window_end': end_dt,
}
+ @expose('json:')
+ @require_post()
+ def save_project_note(self, **kwargs):
+ shortname = kwargs.get('shortname')
+ note = kwargs.get('note')
+ nbhd = M.Neighborhood.query.get(name='Projects')
+ c.project = M.Project.query.get(shortname=shortname,
neighborhood_id=nbhd._id)
+ if c.project:
+ c.project.set_tool_data('notes', note=note)
+ return {'status': 'ok', 'message': 'Project note updated'}
+ return {'status': 'error', 'message': 'Project note not updated'}
+
@expose('jinja:allura:templates/site_admin_reclone_repo.html')
@without_trailing_slash
@validate(dict(prefix=validators.NotEmpty(),
diff --git a/Allura/allura/templates/site_admin_new_projects.html
b/Allura/allura/templates/site_admin_new_projects.html
index 413b43720..8970ff2e3 100644
--- a/Allura/allura/templates/site_admin_new_projects.html
+++ b/Allura/allura/templates/site_admin_new_projects.html
@@ -71,6 +71,16 @@
<td><small>{{ p.external_homepage|urlize(22) }}</small></td>
<td>{% for a in p.admins() %}<small><a href="/nf/admin/user/{{
a.username }}">{{ a.username }}</a></small> {% endfor %}</td>
</tr>
+ <tr class="tablesorter-childRow">
+ <td colspan="8" class="child-row">
+ {% set note = p.get_tool_data('notes', 'note') %}
+ <a class="add-note" title="click to add a not for this project"
data-project="{{ p.shortname }}" href="#"><i class="fa fa-edit"></i> {% if note
%}edit note{% else %}add note{%endif %}</a>
+ <br>
+ {% if note %}
+ <strong>Notes:</strong> <span class="project-note">{{ note
}}</span>
+ {% endif %}
+ </td>
+ </tr>
{% endfor %}
</table>
{{ _paging() }}
@@ -110,6 +120,11 @@
background-position: 100% 50%;
background-color: #6bb3fd;
}
+ td.child-row{ text-align:center}
+ .note-buttons{
+ display: flex;
+ justify-content: center;
+ }
</style>
{% endblock %}
@@ -124,5 +139,48 @@
sortRestart : false
});
});
+ $('.add-note').each(function(el){
+ var el = $(this);
+ el.on('click', function(evt){
+ evt.preventDefault();
+ var project_shortname = el.data('project');
+ var form_exists = el.closest('tr').find('td:first').find('form');
+ var notes = el.closest('tr').find('td:first').find('.project-note')
+ if (form_exists.length > 0) {
+ return;
+ }
+ var form = $('<form></form>')
+ var textarea = $('<textarea class="note" rows="5"
cols="100"></textarea>');
+ var submit_btn = $('<button type="submit" class="button blue
right">Submit</button>');
+ var cancel_btn = $('<button class="" >Cancel</button>');
+ var div = $('<div class="note-buttons"></div>')
+ if (notes){
+ textarea.val(notes.text());
+ }
+ form.append(textarea)
+ div.append(submit_btn);
+ div.append(cancel_btn);
+ form.append(div);
+ el.closest('tr').find('td:first').append(form)
+ form.on('submit', function(evt){
+ evt.preventDefault();
+ var url = "{{ request.path.replace('new_projects',
'save_project_note')}}";
+ var data = {'_csrf_token': $.cookie('_csrf_token'), 'note':
textarea.val(), 'shortname': project_shortname}
+ $.post(url,data).done(function(response){
+ flash(response.message, 'success');
+ form.remove();
+ var td = el.closest('tr').find('td:first');
+ td.html('<p><strong>Notes:</strong>' + textarea.val() +
'</p>');
+ el.remove();
+ }).fail(function (response){
+ flash(response.message, 'error');
+ })
+ })
+ cancel_btn.on('click', function(evt){
+ evt.preventDefault();
+ form.remove();
+ })
+ })
+ })
} );</script>
{% endblock %}
diff --git a/Allura/allura/tests/functional/test_site_admin.py
b/Allura/allura/tests/functional/test_site_admin.py
index d9767e8fd..dc9bda86b 100644
--- a/Allura/allura/tests/functional/test_site_admin.py
+++ b/Allura/allura/tests/functional/test_site_admin.py
@@ -90,13 +90,13 @@ def test_new_projects_deleted_projects(self):
ThreadLocalODMSession.flush_all()
r = self.app.get('/nf/admin/new_projects', extra_environ=dict(
username='root'))
- assert len(r.html.find('table').find_all('tr')) == count - 1
+ assert len(r.html.find('table').find_all('tr')) == count - 2
def test_new_projects_daterange_filtering(self):
r = self.app.get('/nf/admin/new_projects', extra_environ=dict(
username='root'))
count = len(r.html.find('table').find_all('tr'))
- assert count == 7
+ assert count == 1 + (6 * 2) # header, 6 projects with 2 rows each
filtr = r.forms[0]
filtr['start-dt'] = '2000/01/01 10:10:10'
@@ -179,7 +179,13 @@ def test_task_doc(self):
r = self.app.get('/nf/admin/task_manager/task_doc', params=dict(
task_name='allura.tests.functional.test_site_admin.test_task'))
assert json.loads(r.text)['doc'] == 'test_task doc string'
-
+
+ def test_project_note(self):
+ note_content = 'this is a test note for project'
+ r = self.app.post('/nf/admin/save_project_note',
params=dict(shortname='test', note=note_content), status=200)
+ project = M.Project.query.get(shortname='test')
+ assert note_content == project.get_tool_data('notes', 'note')
+
class TestSiteAdminNotifications(TestController):