Implement component deletion
This commit is contained in:
parent
8ef217f224
commit
dbbd8b4a99
@ -180,123 +180,11 @@ class ComponentForm(forms.ModelForm):
|
|||||||
manufacturer = AutocompleteForeingKeyField(api_search_url='manufacturer-list', foreign_model=parts_models.Manufacturer, required=False)
|
manufacturer = AutocompleteForeingKeyField(api_search_url='manufacturer-list', foreign_model=parts_models.Manufacturer, required=False)
|
||||||
component_type = AutocompleteForeingKeyField(api_search_url='componenttype-list', foreign_model=parts_models.ComponentType, name_field_name='class_name', required=False, image_field_name=None)
|
component_type = AutocompleteForeingKeyField(api_search_url='componenttype-list', foreign_model=parts_models.ComponentType, name_field_name='class_name', required=False, image_field_name=None)
|
||||||
package = AutocompleteForeingKeyField(api_search_url='package-list', foreign_model=parts_models.Package, required=False)
|
package = AutocompleteForeingKeyField(api_search_url='package-list', foreign_model=parts_models.Package, required=False)
|
||||||
|
pref_distri = AutocompleteForeingKeyField(api_search_url='distributor-list', foreign_model=parts_models.Distributor, required=False)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = parts_models.Component
|
model = parts_models.Component
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
class EditComponentForm(forms.Form):
|
|
||||||
name = forms.CharField(required=True)
|
|
||||||
datasheet_link = forms.CharField(max_length=300, required=False)
|
|
||||||
description = forms.CharField(required=False, widget=forms.Textarea)
|
|
||||||
|
|
||||||
# Look up these fields later. Will be autocompleted in UI
|
|
||||||
manufacturer = forms.CharField(required=False, initial='')
|
|
||||||
component_type = forms.CharField(required=False, label='Component Type', initial='')
|
|
||||||
pref_distri = forms.CharField(required=False, label='Preferred Distributor', initial='')
|
|
||||||
package = forms.CharField(required=False, initial='')
|
|
||||||
|
|
||||||
image = forms.ImageField(required=False)
|
|
||||||
|
|
||||||
def __init__(self, *args, instance=None, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
self.instance = instance
|
|
||||||
if instance:
|
|
||||||
self.fields['name'].initial = instance.name
|
|
||||||
self.fields['datasheet_link'].initial = instance.datasheet_link
|
|
||||||
if instance.component_type:
|
|
||||||
self.fields['component_type'].initial = instance.component_type.class_name
|
|
||||||
self.fields['description'].initial = instance.description
|
|
||||||
if instance.manufacturer:
|
|
||||||
self.fields['manufacturer'].initial = instance.manufacturer.name
|
|
||||||
if instance.package:
|
|
||||||
self.fields['package'].initial = instance.package.name
|
|
||||||
if instance.pref_distri:
|
|
||||||
self.fields['pref_distri'].initial = instance.pref_distri.name
|
|
||||||
self.fields['image'].initial = instance.image
|
|
||||||
|
|
||||||
def clean_component_type(self):
|
|
||||||
data = self.cleaned_data['component_type'].strip()
|
|
||||||
|
|
||||||
if len(data) == 0:
|
|
||||||
self.cleaned_data['component_type_object'] = None
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.cleaned_data['component_type_object'] = parts_models.ComponentType.objects.get(class_name=data)
|
|
||||||
except:
|
|
||||||
raise ValidationError('Invalid Component Type')
|
|
||||||
|
|
||||||
def clean_manufacturer(self):
|
|
||||||
data = self.cleaned_data['manufacturer'].strip()
|
|
||||||
|
|
||||||
if len(data) == 0:
|
|
||||||
self.cleaned_data['manufacturer_object'] = None
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self.cleaned_data['manufacturer_object'] = parts_models.Manufacturer.objects.get(name=data)
|
|
||||||
except:
|
|
||||||
raise ValidationError('Invalid Manufacturer')
|
|
||||||
|
|
||||||
def clean_pref_distri(self):
|
|
||||||
data = self.cleaned_data['pref_distri'].strip()
|
|
||||||
|
|
||||||
if len(data) == 0:
|
|
||||||
self.cleaned_data['pref_distri_object'] = None
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self.cleaned_data['pref_distri_object'] = parts_models.Distributor.objects.get(name=data)
|
|
||||||
except:
|
|
||||||
raise ValidationError('Invalid Distributor')
|
|
||||||
|
|
||||||
def clean_package(self):
|
|
||||||
data = self.cleaned_data['package'].strip()
|
|
||||||
|
|
||||||
if len(data) == 0:
|
|
||||||
self.cleaned_data['package_object'] = None
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self.cleaned_data['package_object'] = parts_models.Package.objects.get(name=data)
|
|
||||||
except:
|
|
||||||
raise ValidationError('Invalid Package')
|
|
||||||
|
|
||||||
|
|
||||||
def _save_new(self):
|
|
||||||
self.instance = parts_models.Component.objects.create(
|
|
||||||
name=self.cleaned_data['name'],
|
|
||||||
datasheet_link=self.cleaned_data['datasheet_link'],
|
|
||||||
description=self.cleaned_data['description'],
|
|
||||||
package=self.cleaned_data['package_object'],
|
|
||||||
component_type=self.cleaned_data['component_type_object'],
|
|
||||||
pref_distri=self.cleaned_data['pref_distri_object'],
|
|
||||||
manufacturer=self.cleaned_data['manufacturer_object']
|
|
||||||
)
|
|
||||||
|
|
||||||
if bool(self.cleaned_data['image']):
|
|
||||||
self.instance.image = self.cleaned_data['image']
|
|
||||||
self.instance.save()
|
|
||||||
|
|
||||||
def save(self):
|
|
||||||
if self.instance is None:
|
|
||||||
self._save_new()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.instance.name = self.cleaned_data['name']
|
|
||||||
self.instance.datasheet_link = self.cleaned_data['datasheet_link']
|
|
||||||
self.instance.description = self.cleaned_data['description']
|
|
||||||
|
|
||||||
if bool(self.cleaned_data['image']) is False:
|
|
||||||
self.instance.image = None
|
|
||||||
else:
|
|
||||||
self.instance.image = self.cleaned_data['image']
|
|
||||||
|
|
||||||
self.instance.manufacturer = self.cleaned_data['manufacturer_object']
|
|
||||||
self.instance.pref_distri = self.cleaned_data['pref_distri_object']
|
|
||||||
self.instance.package = self.cleaned_data['package_object']
|
|
||||||
self.instance.component_type = self.cleaned_data['component_type_object']
|
|
||||||
self.instance.save()
|
|
||||||
|
|
||||||
|
|
||||||
class PackageForm(forms.ModelForm):
|
class PackageForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = parts_models.Package
|
model = parts_models.Package
|
||||||
|
@ -147,7 +147,25 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
|||||||
comp_paginator = Paginator(Component.objects.all(), self.default_page_size)
|
comp_paginator = Paginator(Component.objects.all(), self.default_page_size)
|
||||||
|
|
||||||
context['components'] = comp_paginator.get_page(comp_page_num)
|
context['components'] = comp_paginator.get_page(comp_page_num)
|
||||||
|
context['comp_form'] = ComponentForm()
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
def handle_new_component_post(self, request, **kwargs):
|
||||||
|
cform = ComponentForm(data=request.POST, files=request.FILES)
|
||||||
|
if cform.is_valid():
|
||||||
|
cform.save()
|
||||||
|
|
||||||
|
context = self.get_context_data(**kwargs)
|
||||||
|
if not cform.is_valid():
|
||||||
|
context['comp_form'] = cform
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
if 'submit-edit-component' in request.POST:
|
||||||
|
return self.handle_new_component_post(request, **kwargs)
|
||||||
|
else:
|
||||||
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
class PackageView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
class PackageView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
||||||
template_name = 'parts/packages.html'
|
template_name = 'parts/packages.html'
|
||||||
@ -518,55 +536,50 @@ class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
|||||||
self.base_title = 'Component / '+self.object.name
|
self.base_title = 'Component / '+self.object.name
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['component'] = self.object
|
context['component'] = self.object
|
||||||
context['edit_form'] = EditComponentForm(instance=self.object)
|
|
||||||
|
|
||||||
context['stocks'] = Stock.objects.filter(component=self.object)
|
context['stocks'] = Stock.objects.filter(component=self.object)
|
||||||
context['comp_form'] = ComponentForm(instance=self.object)
|
context['comp_form'] = ComponentForm(instance=self.object)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def handle_submit_edit_post(self, request, **kwargs):
|
|
||||||
form_error = False
|
|
||||||
|
|
||||||
form = EditComponentForm(instance=self.object, data=request.POST, files=request.FILES)
|
|
||||||
if form.is_valid():
|
|
||||||
try:
|
|
||||||
form.save()
|
|
||||||
except IntegrityError as ie:
|
|
||||||
form.add_error('name', 'Component name, package, and manufacturer are not unique!')
|
|
||||||
form.add_error('package', 'Component name, package, and manufacturer are not unique!')
|
|
||||||
form.add_error('manufacturer', 'Component name, package, and manufacturer are not unique!')
|
|
||||||
form_error = True
|
|
||||||
self.object = self.get_object()
|
|
||||||
else:
|
|
||||||
form_error = True
|
|
||||||
|
|
||||||
context = self.get_context_data(**kwargs)
|
|
||||||
if form_error:
|
|
||||||
context['edit_form'] = form
|
|
||||||
return self.render_to_response(context)
|
|
||||||
|
|
||||||
def handle_submit_edit_component_post(self, request, **kwargs):
|
def handle_submit_edit_component_post(self, request, **kwargs):
|
||||||
context = self.get_context_data(**kwargs)
|
|
||||||
|
|
||||||
cform = ComponentForm(instance=self.object, data=request.POST, files=request.FILES)
|
cform = ComponentForm(instance=self.object, data=request.POST, files=request.FILES)
|
||||||
if cform.is_valid():
|
if cform.is_valid():
|
||||||
print('valid')
|
|
||||||
cform.save()
|
cform.save()
|
||||||
else:
|
|
||||||
print('invalid')
|
context = self.get_context_data(**kwargs)
|
||||||
context['comp_form'] = cform
|
if not cform.is_valid():
|
||||||
|
context['comp_form'] = cform
|
||||||
|
|
||||||
return self.render_to_response(context)
|
return self.render_to_response(context)
|
||||||
|
|
||||||
|
def handle_submit_delete_post(self, request, **kwargs):
|
||||||
|
delete_error = None
|
||||||
|
protected_stuff = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.object.delete()
|
||||||
|
except ProtectedError as pe:
|
||||||
|
delete_error = 'Component is protected'
|
||||||
|
protected_stuff = pe.protected_objects
|
||||||
|
except:
|
||||||
|
delete_error = 'Cannot delete component. Unknown error'
|
||||||
|
|
||||||
|
if delete_error is None:
|
||||||
|
return redirect('parts-components')
|
||||||
|
else:
|
||||||
|
context = self.get_context_data(**kwargs)
|
||||||
|
context['delete_error'] = delete_error
|
||||||
|
context['protected_stuff'] = protected_stuff
|
||||||
|
return self.render_to_response(context)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
if 'submit-edit-comp' in request.POST:
|
|
||||||
return self.handle_submit_edit_post(request, **kwargs)
|
|
||||||
if 'submit-edit-component' in request.POST:
|
if 'submit-edit-component' in request.POST:
|
||||||
return self.handle_submit_edit_component_post(request, **kwargs)
|
return self.handle_submit_edit_component_post(request, **kwargs)
|
||||||
|
elif 'submit-component-delete' in request.POST:
|
||||||
return super().post(request, *args, **kwargs)
|
return self.handle_submit_delete_post(request, **kwargs)
|
||||||
|
else:
|
||||||
|
return super().post(request, *args, **kwargs)
|
||||||
|
|
||||||
class PackageDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
class PackageDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
||||||
template_name = 'parts/packages-detail.html'
|
template_name = 'parts/packages-detail.html'
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<a class="btn btn-secondary mb-2" href="{{component.datasheet_link}}"><i class="bi bi-file-pdf-fill"></i> Datasheet</a>
|
<a class="btn btn-secondary mb-2" href="{{component.datasheet_link}}"><i class="bi bi-file-pdf-fill"></i> Datasheet</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#comp-edit-modal"><i class="bi bi-pencil-square"></i> Edit Component</button>
|
<button class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#comp-edit-modal"><i class="bi bi-pencil-square"></i> Edit Component</button>
|
||||||
|
<button class="btn btn-danger mb-2" data-bs-toggle="modal" data-bs-target="#component-delete-modal"><i class="bi bi-file-x"></i> Delete {{component.name}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col m-1">
|
<div class="col m-1">
|
||||||
@ -144,15 +145,54 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Delete modal -->
|
||||||
|
<div class="modal fade" id="component-delete-modal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-lg modal-fullscreen-lg-down">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5>{{component.name}}</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h4>Delete this Component?</h4>
|
||||||
|
{% if delete_error %}
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
{{delete_error}}
|
||||||
|
</div>
|
||||||
|
{% if protected_stuff %}
|
||||||
|
<h4>Following prevent the deletion:</h4>
|
||||||
|
<ul>
|
||||||
|
{% for elem in protected_stuff %}
|
||||||
|
<li>{{elem}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<button type="submit" class="btn btn-danger" name="submit-component-delete"><i class="bi bi-file-x"></i> Delete {{component.name}}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% include 'parts/modals/edit-component-modal.html' with heading="Edit "|add:component.name form=comp_form %}
|
{% include 'parts/modals/edit-component-modal.html' with heading="Edit "|add:component.name form=comp_form %}
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
||||||
{% block custom_scripts %}
|
{% block custom_scripts %}
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
{% if edit_form.errors %}
|
{% if comp_form.errors %}
|
||||||
bootstrap.Modal.getOrCreateInstance(document.getElementById('comp-edit-modal')).show()
|
bootstrap.Modal.getOrCreateInstance(document.getElementById('comp-edit-modal')).show()
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if delete_error %}
|
||||||
|
bootstrap.Modal.getOrCreateInstance(document.getElementById('component-delete-modal')).show();
|
||||||
|
{% endif %}
|
||||||
</script>
|
</script>
|
||||||
{% endblock custom_scripts %}
|
{% endblock custom_scripts %}
|
||||||
|
|
||||||
|
@ -5,7 +5,15 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md">
|
<div class="col-md">
|
||||||
<h2>Components</h2>
|
<h2>Components</h2>
|
||||||
<div class="list-group">
|
<form action="" method="get">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input class="form-control" name="search" type="search" placeholder="Search Component..." {% if search_string %}value="{{search_string}}"{% endif %}>
|
||||||
|
<button type="submit" class="btn btn-primary">
|
||||||
|
<i class="bi bi-search"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-success" type="button" data-bs-toggle="modal" data-bs-target="#comp-edit-modal"><i class="bi bi-plus-circle"></i> Add Component</button> </div>
|
||||||
|
</form>
|
||||||
|
<div class="list-group mb-3">
|
||||||
{% for comp in components %}
|
{% for comp in components %}
|
||||||
<a href="{% url 'parts-components-detail' uuid=comp.id %}" class="text-decoration-none">
|
<a href="{% url 'parts-components-detail' uuid=comp.id %}" class="text-decoration-none">
|
||||||
<li class="list-group-item list-group-item-action d-flex align-items-center">
|
<li class="list-group-item list-group-item-action d-flex align-items-center">
|
||||||
@ -35,4 +43,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
|
||||||
|
{% include 'parts/modals/edit-component-modal.html' with form=comp_form heading='New Component' %}
|
||||||
|
|
||||||
|
{% endblock content %}
|
||||||
|
{% block custom_scripts %}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
{% if comp_form.errors %}
|
||||||
|
bootstrap.Modal.getOrCreateInstance(document.getElementById('comp-edit-modal')).show()
|
||||||
|
{% endif %}
|
||||||
|
</script>
|
||||||
|
{% endblock custom_scripts %}
|
Loading…
Reference in New Issue
Block a user