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)
|
||||
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)
|
||||
pref_distri = AutocompleteForeingKeyField(api_search_url='distributor-list', foreign_model=parts_models.Distributor, required=False)
|
||||
class Meta:
|
||||
model = parts_models.Component
|
||||
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 Meta:
|
||||
model = parts_models.Package
|
||||
|
@ -147,8 +147,26 @@ class ComponentView(LoginRequiredMixin, BaseTemplateMixin, TemplateView):
|
||||
comp_paginator = Paginator(Component.objects.all(), self.default_page_size)
|
||||
|
||||
context['components'] = comp_paginator.get_page(comp_page_num)
|
||||
context['comp_form'] = ComponentForm()
|
||||
|
||||
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):
|
||||
template_name = 'parts/packages.html'
|
||||
base_title = 'Packages'
|
||||
@ -518,54 +536,49 @@ class ComponentDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
||||
self.base_title = 'Component / '+self.object.name
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['component'] = self.object
|
||||
context['edit_form'] = EditComponentForm(instance=self.object)
|
||||
|
||||
context['stocks'] = Stock.objects.filter(component=self.object)
|
||||
context['comp_form'] = ComponentForm(instance=self.object)
|
||||
|
||||
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):
|
||||
context = self.get_context_data(**kwargs)
|
||||
|
||||
cform = ComponentForm(instance=self.object, data=request.POST, files=request.FILES)
|
||||
if cform.is_valid():
|
||||
print('valid')
|
||||
cform.save()
|
||||
else:
|
||||
print('invalid')
|
||||
|
||||
context = self.get_context_data(**kwargs)
|
||||
if not cform.is_valid():
|
||||
context['comp_form'] = cform
|
||||
|
||||
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):
|
||||
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:
|
||||
return self.handle_submit_edit_component_post(request, **kwargs)
|
||||
|
||||
elif 'submit-component-delete' in request.POST:
|
||||
return self.handle_submit_delete_post(request, **kwargs)
|
||||
else:
|
||||
return super().post(request, *args, **kwargs)
|
||||
|
||||
class PackageDetailView(LoginRequiredMixin, BaseTemplateMixin, DetailView):
|
||||
|
@ -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>
|
||||
{% 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-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 class="col m-1">
|
||||
@ -144,15 +145,54 @@
|
||||
</div>
|
||||
</div>
|
||||
{% 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 %}
|
||||
{% endblock content %}
|
||||
|
||||
{% block custom_scripts %}
|
||||
|
||||
<script type="text/javascript">
|
||||
{% if edit_form.errors %}
|
||||
{% if comp_form.errors %}
|
||||
bootstrap.Modal.getOrCreateInstance(document.getElementById('comp-edit-modal')).show()
|
||||
{% endif %}
|
||||
{% if delete_error %}
|
||||
bootstrap.Modal.getOrCreateInstance(document.getElementById('component-delete-modal')).show();
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock custom_scripts %}
|
||||
|
||||
|
@ -5,7 +5,15 @@
|
||||
<div class="row">
|
||||
<div class="col-md">
|
||||
<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 %}
|
||||
<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">
|
||||
@ -35,4 +43,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% 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