mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #1808 from SchrodingersGat/part-page-refactor
Move "attachments" and "notes" to "Part Detail" page
This commit is contained in:
commit
2295008944
@ -837,6 +837,12 @@ input[type="submit"] {
|
||||
pointer-events: none; /* Prevent this div from blocking links underneath */
|
||||
}
|
||||
|
||||
.notes {
|
||||
border-radius: 5px;
|
||||
background-color: #fafafa;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
display: none;
|
||||
border-radius: 5px;
|
||||
@ -853,6 +859,11 @@ input[type="submit"] {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.btn-small {
|
||||
padding: 3px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.btn-remove {
|
||||
padding: 3px;
|
||||
padding-left: 5px;
|
||||
|
@ -1,86 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='attachments' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Attachments" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% include "attachment_table.html" with attachments=part.part_attachments %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-part-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
part: {{ part.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/part/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
var url = `/api/part/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-part-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
reloadAttachmentTable();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm(
|
||||
'{% url "api-part-attachment-list" %}',
|
||||
{
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
{% endblock %}
|
@ -1,6 +1,7 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
|
||||
{% block menubar %}
|
||||
@ -135,11 +136,38 @@
|
||||
{% endif %}
|
||||
{% if part.responsible %}
|
||||
<tr>
|
||||
<td><span class='fas fa-user'>d</span></td>
|
||||
<td><span class='fas fa-user'></span></td>
|
||||
<td><strong>{% trans "Responsible User" %}</strong></td>
|
||||
<td>{{ part.responsible }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
<tr><td colspan="3"></td></tr>
|
||||
|
||||
<tr>
|
||||
<td><span class='fas fa-sticky-note'></span></td>
|
||||
<td>
|
||||
<strong>{% trans "Notes" %}</strong>
|
||||
</td>
|
||||
<td>
|
||||
<div class='btn-group float-right'>
|
||||
<button type='button' id='edit-notes' title='{% trans "Edit Notes" %}' class='btn btn-small btn-default'>
|
||||
<span class='fas fa-edit'>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='3'>
|
||||
{% if part.notes %}
|
||||
<div class='notes'>
|
||||
{{ part.notes | markdownify }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
@ -240,23 +268,35 @@
|
||||
|
||||
{% block post_content_panel %}
|
||||
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>
|
||||
{% trans "Part Parameters" %}
|
||||
</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='param-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
{% if roles.part.add %}
|
||||
<button title='{% trans "Add new parameter" %}' class='btn btn-success' id='param-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
<div class='row'>
|
||||
<div class='col-sm-6'>
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Parameters" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
<div id='param-button-toolbar'>
|
||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||
{% if roles.part.add %}
|
||||
<button title='{% trans "Add new parameter" %}' class='btn btn-success' id='param-create'>
|
||||
<span class='fas fa-plus-circle'></span> {% trans "New Parameter" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<table id='parameter-table' class='table table-condensed table-striped' data-toolbar="#param-button-toolbar"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-sm-6'>
|
||||
<div class='panel panel-default panel-inventree'>
|
||||
<div class='panel-heading'>
|
||||
<h4>{% trans "Attachments" %}</h4>
|
||||
</div>
|
||||
<div class='panel-content'>
|
||||
{% include "attachment_table.html" %}
|
||||
</div>
|
||||
</div>
|
||||
<table id='parameter-table' class='table table-condensed table-striped' data-toolbar="#param-button-toolbar"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -269,6 +309,18 @@
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
$('#edit-notes').click(function() {
|
||||
constructForm('{% url "api-part-detail" part.pk %}', {
|
||||
fields: {
|
||||
notes: {
|
||||
multiline: true,
|
||||
}
|
||||
},
|
||||
title: '{% trans "Edit Part Notes" %}',
|
||||
reload: true,
|
||||
});
|
||||
});
|
||||
|
||||
$(".slidey").change(function() {
|
||||
var field = $(this).attr('fieldname');
|
||||
|
||||
@ -337,4 +389,68 @@
|
||||
});
|
||||
});
|
||||
|
||||
loadAttachmentTable(
|
||||
'{% url "api-part-attachment-list" %}',
|
||||
{
|
||||
filters: {
|
||||
part: {{ part.pk }},
|
||||
},
|
||||
onEdit: function(pk) {
|
||||
var url = `/api/part/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
fields: {
|
||||
comment: {},
|
||||
},
|
||||
title: '{% trans "Edit Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
},
|
||||
onDelete: function(pk) {
|
||||
var url = `/api/part/attachment/${pk}/`;
|
||||
|
||||
constructForm(url, {
|
||||
method: 'DELETE',
|
||||
confirmMessage: '{% trans "Confirm Delete Operation" %}',
|
||||
title: '{% trans "Delete Attachment" %}',
|
||||
onSuccess: reloadAttachmentTable,
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
enableDragAndDrop(
|
||||
'#attachment-dropzone',
|
||||
'{% url "api-part-attachment-list" %}',
|
||||
{
|
||||
data: {
|
||||
part: {{ part.id }},
|
||||
},
|
||||
label: 'attachment',
|
||||
success: function(data, status, xhr) {
|
||||
reloadAttachmentTable();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$("#new-attachment").click(function() {
|
||||
|
||||
constructForm(
|
||||
'{% url "api-part-attachment-list" %}',
|
||||
{
|
||||
method: 'POST',
|
||||
fields: {
|
||||
attachment: {},
|
||||
comment: {},
|
||||
part: {
|
||||
value: {{ part.pk }},
|
||||
hidden: true,
|
||||
}
|
||||
},
|
||||
onSuccess: reloadAttachmentTable,
|
||||
title: '{% trans "Add Attachment" %}',
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
{% endblock %}
|
||||
|
@ -109,16 +109,4 @@
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class='list-group-item {% if tab == "attachments" %}active{% endif %}' title='{% trans "Attachments" %}'>
|
||||
<a href='{% url "part-attachments" part.id %}'>
|
||||
<span class='menu-tab-icon fas fa-paperclip sidebar-icon'></span>
|
||||
{% trans "Attachments" %}
|
||||
</a>
|
||||
</li>
|
||||
<li class='list-group-item {% if tab == "notes" %}active{% endif %}' title='{% trans "Part Notes" %}'>
|
||||
<a href='{% url "part-notes" part.id %}'>
|
||||
<span class='menu-tab-icon fas fa-clipboard sidebar-icon'></span>
|
||||
{% trans "Notes" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -1,57 +0,0 @@
|
||||
{% extends "part/part_base.html" %}
|
||||
{% load static %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% load i18n %}
|
||||
{% load markdownify %}
|
||||
|
||||
{% block menubar %}
|
||||
{% include 'part/navbar.html' with tab='notes' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block heading %}
|
||||
{% trans "Part Notes" %}
|
||||
{% if roles.part.change and not editing %}
|
||||
<button title='{% trans "Edit notes" %}' class='btn btn-default' id='edit-notes'><span class='fas fa-edit'></span></button>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block details %}
|
||||
|
||||
{% if editing %}
|
||||
<form method='POST'>
|
||||
{% csrf_token %}
|
||||
|
||||
{{ form }}
|
||||
<hr>
|
||||
|
||||
<button type="submit" class='btn btn-default'>{% trans "Save" %}</button>
|
||||
|
||||
</form>
|
||||
|
||||
{{ form.media }}
|
||||
|
||||
{% else %}
|
||||
|
||||
<div class='panel panel-default'>
|
||||
{% if part.notes %}
|
||||
<div class='panel-content'>
|
||||
{{ part.notes | markdownify }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block js_ready %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if editing %}
|
||||
{% else %}
|
||||
$("#edit-notes").click(function() {
|
||||
location.href = "{% url 'part-notes' part.id %}?edit=1";
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -61,8 +61,6 @@ part_detail_urls = [
|
||||
url(r'^tests/', views.PartDetail.as_view(template_name='part/part_tests.html'), name='part-test-templates'),
|
||||
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
|
||||
url(r'^related-parts/?', views.PartDetail.as_view(template_name='part/related.html'), name='part-related'),
|
||||
url(r'^attachments/?', views.PartDetail.as_view(template_name='part/attachments.html'), name='part-attachments'),
|
||||
url(r'^notes/?', views.PartNotes.as_view(), name='part-notes'),
|
||||
|
||||
url(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'),
|
||||
|
||||
|
@ -13,7 +13,7 @@ from django.shortcuts import get_object_or_404
|
||||
from django.shortcuts import HttpResponseRedirect
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.views.generic import DetailView, ListView, UpdateView
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.forms.models import model_to_dict
|
||||
from django.forms import HiddenInput, CheckboxInput
|
||||
from django.conf import settings
|
||||
@ -747,40 +747,6 @@ class PartImportAjax(FileManagementAjaxView, PartImport):
|
||||
return PartImport.validate(self, self.steps.current, form, **kwargs)
|
||||
|
||||
|
||||
class PartNotes(UpdateView):
|
||||
""" View for editing the 'notes' field of a Part object.
|
||||
Presents a live markdown editor.
|
||||
"""
|
||||
|
||||
context_object_name = 'part'
|
||||
# form_class = part_forms.EditNotesForm
|
||||
template_name = 'part/notes.html'
|
||||
model = Part
|
||||
|
||||
role_required = 'part.change'
|
||||
|
||||
fields = ['notes']
|
||||
|
||||
def get_success_url(self):
|
||||
""" Return the success URL for this form """
|
||||
|
||||
return reverse('part-notes', kwargs={'pk': self.get_object().id})
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
|
||||
part = self.get_object()
|
||||
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
context['editing'] = str2bool(self.request.GET.get('edit', ''))
|
||||
|
||||
ctx = part.get_context_data(self.request)
|
||||
|
||||
context.update(ctx)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class PartDetail(InvenTreeRoleMixin, DetailView):
|
||||
""" Detail view for Part object
|
||||
"""
|
||||
|
@ -353,12 +353,16 @@ function constructFormBody(fields, options) {
|
||||
// Override existing query filters (if provided!)
|
||||
fields[field].filters = Object.assign(fields[field].filters || {}, field_options.filters);
|
||||
|
||||
// TODO: Refactor the following code with Object.assign (see above)
|
||||
|
||||
// Secondary modal options
|
||||
fields[field].secondary = field_options.secondary;
|
||||
|
||||
// Edit callback
|
||||
fields[field].onEdit = field_options.onEdit;
|
||||
|
||||
fields[field].multiline = field_options.multiline;
|
||||
|
||||
// Custom help_text
|
||||
if (field_options.help_text) {
|
||||
fields[field].help_text = field_options.help_text;
|
||||
@ -1483,7 +1487,11 @@ function constructInputOptions(name, classes, type, parameters) {
|
||||
opts.push(`placeholder='${parameters.placeholder}'`);
|
||||
}
|
||||
|
||||
return `<input ${opts.join(' ')}>`;
|
||||
if (parameters.multiline) {
|
||||
return `<textarea ${opts.join(' ')}></textarea>`;
|
||||
} else {
|
||||
return `<input ${opts.join(' ')}>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user