Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP: Kiwi TCMS bug tracker. Fixes #699
- Loading branch information
Showing
12 changed files
with
540 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Copyright (c) 2019 Alexander Todorov <atodorov@MrSenko.com> | ||
|
||
# Licensed under the GPL 2.0: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html | ||
|
||
from django import forms | ||
|
||
from django.utils.translation import ugettext_lazy as _ | ||
|
||
from tcms.core.widgets import SimpleMDE | ||
from tcms.core.forms.fields import UserField | ||
from tcms.management.models import Product, Version, Build | ||
|
||
|
||
class NewBugForm(forms.Form): | ||
summary = forms.CharField() | ||
assignee = UserField(required=False) | ||
|
||
product = forms.ModelChoiceField( | ||
queryset=Product.objects.all(), | ||
empty_label=None, | ||
) | ||
|
||
version = forms.ModelChoiceField( | ||
queryset=Version.objects.none(), | ||
empty_label=None, | ||
) | ||
|
||
build = forms.ModelChoiceField( | ||
queryset=Build.objects.none(), | ||
empty_label=None, | ||
) | ||
|
||
text = forms.CharField( | ||
widget=SimpleMDE(), | ||
required=False, | ||
initial=_("""Description of problem: | ||
How often reproducible: | ||
Steps to Reproduce: | ||
1. | ||
2. | ||
3. | ||
Actual results: | ||
Expected results: | ||
Additional info: | ||
""")) | ||
|
||
def populate(self, product_id=None): | ||
if product_id: | ||
self.fields['version'].queryset = Version.objects.filter(product_id=product_id) | ||
self.fields['build'].queryset = Build.objects.filter(product_id=product_id) | ||
else: | ||
self.fields['version'].queryset = Version.objects.all() | ||
self.fields['build'].queryset = Build.objects.all() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Generated by Django 2.2.5 on 2019-09-03 20:30 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
('management', '0005_order_by_name'), | ||
('testruns', '0006_rename_test_case_run_to_test_execution'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Bug', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, | ||
primary_key=True, | ||
serialize=False, verbose_name='ID')), | ||
('summary', models.CharField(db_index=True, max_length=255)), | ||
('created_at', models.DateTimeField(auto_now_add=True, | ||
db_index=True)), | ||
('status', models.BooleanField(db_index=True, default=True)), | ||
('assignee', models.ForeignKey(on_delete=models.deletion.CASCADE, | ||
related_name='assigned_bugs', | ||
to=settings.AUTH_USER_MODEL)), | ||
('build', models.ForeignKey(on_delete=models.deletion.CASCADE, | ||
to='management.Build')), | ||
('executions', models.ManyToManyField(related_name='bugs', | ||
to='testruns.TestExecution')), | ||
('product', models.ForeignKey(on_delete=models.deletion.CASCADE, | ||
to='management.Product')), | ||
('reporter', models.ForeignKey(on_delete=models.deletion.CASCADE, | ||
related_name='repoted_bugs', | ||
to=settings.AUTH_USER_MODEL)), | ||
('tags', models.ManyToManyField(related_name='bugs', to='management.Tag')), | ||
('version', models.ForeignKey(on_delete=models.deletion.CASCADE, | ||
to='management.Version')), | ||
], | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Copyright (c) 2019 Alexander Todorov <atodorov@MrSenko.com> | ||
|
||
# Licensed under the GPL 2.0: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html | ||
|
||
from django.conf import settings | ||
from django.db import models | ||
|
||
|
||
class Bug(models.Model): | ||
summary = models.CharField(max_length=255, db_index=True) | ||
created_at = models.DateTimeField(auto_now_add=True, | ||
db_index=True) | ||
# True means bug is still open | ||
status = models.BooleanField(default=True, db_index=True) | ||
|
||
reporter = models.ForeignKey(settings.AUTH_USER_MODEL, | ||
on_delete=models.CASCADE, | ||
related_name='repoted_bugs') | ||
assignee = models.ForeignKey(settings.AUTH_USER_MODEL, | ||
on_delete=models.CASCADE, | ||
related_name='assigned_bugs') | ||
|
||
product = models.ForeignKey('management.Product', on_delete=models.CASCADE) | ||
version = models.ForeignKey('management.Version', on_delete=models.CASCADE) | ||
build = models.ForeignKey('management.Build', on_delete=models.CASCADE) | ||
|
||
executions = models.ManyToManyField('testruns.TestExecution', related_name='bugs') | ||
tags = models.ManyToManyField('management.Tag', related_name='bugs') | ||
|
||
def __str__(self): | ||
return "BUG-%d: %s " % (self.pk, self.summary) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
Used in mutable.html and clone.html | ||
*/ | ||
$(document).ready((function () { | ||
if ($('#id_version').find('option').length === 0) { | ||
populateProductVersion(); | ||
} | ||
|
||
$('#add_id_product').click(function () { | ||
return showRelatedObjectPopup(this); | ||
}); | ||
|
||
$('#add_id_version').click(function () { | ||
return showRelatedObjectPopup(this); | ||
}); | ||
|
||
document.getElementById('id_product').onchange = function () { | ||
$('#id_product').selectpicker('refresh'); | ||
populateProductVersion(); | ||
}; | ||
|
||
document.getElementById('id_version').onchange = function () { | ||
$('#id_version').selectpicker('refresh'); | ||
} | ||
})); | ||
|
||
// TODO: this entire file is mostly duplicate with testplans/js/mutable.js | ||
function populateProductVersion() { | ||
let href = $('#add_id_version')[0].href; | ||
$('#add_id_version')[0].href = href.slice(0, href.indexOf('&product')); | ||
$('#add_id_version')[0].href += `&product=${$('#id_product').val()}`; | ||
|
||
$('#id_version').find('option').remove(); | ||
|
||
update_version_select_from_product(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
{% extends "base.html" %} | ||
{% load i18n %} | ||
{% load static %} | ||
{% load comments %} | ||
{% load extra_filters %} | ||
{% load attachments_tags %} | ||
|
||
{% block title %}BUG-{{ object.pk }}: {{ object.summary }}{% endblock %} | ||
{% block body_class %}cards-pf{% endblock %} | ||
|
||
{% block contents %} | ||
<div class="container-cards-pf"> | ||
<!-- Important: if you need to nest additional .row within a .row.row-cards-pf, do *not* use .row-cards-pf on the nested .row --> | ||
<h1 class="col-md-12" style="margin-top: 0"> | ||
<span id="object_pk" | ||
data-pk="{{ object.pk }}" | ||
data-perm-remove-tag="{{ perms.bugs.delete_bugtag }}" | ||
>BUG-{{ object.pk }}: {{ object.summary }}</span> | ||
|
||
{% if object.status %} | ||
<span class="fa fa-envelope-open-o" title="{% trans 'Open' %}"></span> | ||
{% else %} | ||
<span class="fa fa-times" title="{% trans 'Closed' %}"></span> | ||
{% endif %} | ||
</h1> | ||
|
||
<div class="row row-cards-pf"> | ||
<div class="col-xs-12 col-sm-12 col-md-9"> | ||
<div class="card-pf card-pf-accented"> | ||
<div class="card-pf-body"> | ||
<div class="markdown-text"> | ||
{{ object.text|markdown2html }} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="col-xs-12 col-sm-12 col-md-3"> | ||
|
||
<div class="card-pf card-pf-accented card-pf-aggregate-status"> | ||
<h2 class="card-pf-title" style="text-align: left"> | ||
<span class="fa fa-calendar"></span>{{ object.created_at }} | ||
</h2> | ||
|
||
<h2 class="card-pf-title" style="text-align: left"> | ||
<span class="fa pficon-user"></span>{% trans 'Reporter' %}: | ||
<a href="{% url "tcms-profile" object.reporter.username %}">{{ object.reporter.username }}</a> | ||
</h2> | ||
|
||
<h2 class="card-pf-title" style="text-align: left"> | ||
<span class="fa pficon-user"></span>{% trans 'Assignee' %}: | ||
<a href="{% url "tcms-profile" object.assignee.username %}">{{ object.assignee.username }}</a> | ||
</h2> | ||
|
||
<h2 class="card-pf-title" style="text-align: left"> | ||
<span id="product_pk" | ||
data-pk="{{ object.product.pk }}" | ||
class="fa fa-shopping-cart"></span>{% trans 'Product' %}: | ||
{{ object.product }} | ||
</h2> | ||
|
||
<h2 class="card-pf-title" style="text-align: left"> | ||
<span class="fa fa-refresh"></span>{% trans 'Version' %}: | ||
{{ object.version }} | ||
</h2> | ||
|
||
<h2 class="card-pf-title" style="text-align: left"> | ||
<span class="fa fa-wrench"></span>{% trans 'Build' %}: | ||
{{ object.build }} | ||
</h2> | ||
|
||
<div class="card-pf-body"></div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="row row-cards-pf"> | ||
<div class="col-xs-12 col-sm-6 col-md-3"> | ||
<div class="card-pf card-pf-accented"> | ||
<h2 class="card-pf-title"> | ||
<span class="fa fa-tags"></span> | ||
{% trans 'Tags' %} | ||
</h2> | ||
|
||
<div class="card-pf-body"> | ||
<table class="table" id="tags"> | ||
<thead> | ||
<tr> | ||
<th>{% trans 'Name' %}</th> | ||
<th></th> | ||
</tr> | ||
</thead> | ||
|
||
{% if perms.bugs.add_bugtag %} | ||
<tfoot> | ||
<tr> | ||
<th> | ||
<div class="input-group input-group-sm mb-3"> | ||
<input type="text" class="form-control typeahead" id="id_tags"> | ||
</div> | ||
</th> | ||
<th> | ||
<a href="#tags" id="add-tag" title="{% trans 'Add' %}"> | ||
<span class="fa fa-plus"></span> | ||
</a> | ||
</th> | ||
</tr> | ||
</tfoot> | ||
{% endif %} | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="col-xs-12 col-sm-6 col-md-6"> | ||
<div class="card-pf card-pf-accented"> | ||
<h2 class="card-pf-title"> | ||
<span class="fa fa-paperclip"></span> | ||
{% trans 'Attachments' %} | ||
</h2> | ||
|
||
<div class="card-pf-body"> | ||
<table class="table" id="attachments"> | ||
<thead> | ||
<tr> | ||
<th>{% trans 'File' %}</th> | ||
<th>{% trans 'Owner' %}</th> | ||
<th>{% trans 'Date' %}</th> | ||
<th></th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{% get_attachments_for object as attachments_list %} | ||
{% for attachment in attachments_list %} | ||
<tr> | ||
<td><a href="{{ attachment.attachment_file.url }}">{{ attachment.filename }}</a></td> | ||
<td><a href="{% url "tcms-profile" attachment.creator %}">{{ attachment.creator }}</a></td> | ||
<td>{{ attachment.created }}</td> | ||
<td>{% attachment_delete_link attachment %}</td> | ||
</tr> | ||
{% empty %} | ||
<tr><td colspan="4">{% trans 'No records found' %}</td></tr> | ||
{% endfor %} | ||
</tbody> | ||
{% if perms.attachments.add_attachment %} | ||
<tfoot> | ||
<tr> | ||
<th colspan="4"> | ||
{% attachment_form object %} | ||
</th> | ||
</tr> | ||
</tfoot> | ||
{% endif %} | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
</div><!-- /row --> | ||
</div> | ||
|
||
<script src="{% static 'typeahead.js/dist/typeahead.jquery.min.js' %}"></script> | ||
|
||
<script src="{% static 'js/utils.js' %}"></script> | ||
<script src="{% static 'js/jsonrpc.js' %}"></script> | ||
{% endblock %} |
Oops, something went wrong.