PR-56 форма редактирования объектов

добавлена модальная форма для редактирования созданных объектов
remotes/origin/HEAD
booblegum 9 years ago
parent d293a32700
commit 29a46da7d3
  1. 8
      api/urls.py
  2. 37
      api/views.py
  3. 4
      archilance/urls.py
  4. 62
      assets/js/build/customer_profile.js
  5. 3
      assets/js/build/init_contractor_filter.js
  6. 9
      assets/js/build/init_create_worksell.js
  7. 9
      assets/js/build/init_customer_project_create.js
  8. 2030
      assets/js/build/init_modal_realty_edit.js
  9. 9
      assets/js/build/init_portfolio_create_edit.js
  10. 2
      assets/js/src/customer_profile.js
  11. 162
      assets/js/src/init_modal_realty_edit.js
  12. 5
      assets/lib/proekton-components/js/src/SelectOrCreate.js
  13. 3
      assets/lib/proekton-components/js/src/SelectedContainer.js
  14. 13
      projects/forms.py
  15. 80
      projects/templates/partials/modals/mod-realty-edit.html
  16. 12
      projects/views.py
  17. 7
      users/templates/customer_profile.html
  18. 13
      users/templates/partials/inc-objects.html
  19. 2
      webpack.config.js

@ -1,4 +1,5 @@
from rest_framework import routers
from django.conf.urls import url, include
from .views import (
AnswerViewSet,
@ -15,6 +16,7 @@ from .views import (
PortfolioViewSet,
ProjectViewSet,
RealtyViewSet,
UpdateRealty,
ReviewViewSet,
BuildingClassificationViewSet,
SpecializationViewSet,
@ -57,7 +59,7 @@ router.register(r'work-sells', WorkSellViewSet)
urlpatterns = router.urls
# urlpatterns = [
# url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
# url(r'^demo_realties/(?P<pk>\d+)/$', UpdateRealty.as_view()),
# ]
#
# urlpatterns += router.url
# urlpatterns += router.urls

@ -5,6 +5,7 @@ from rest_framework.pagination import PageNumberPagination
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import detail_route, list_route
from rest_framework.response import Response
from rest_framework import generics
from chat.filters import MessageFilterSet, NoteFilterSet, DocumentFilterSet
from chat.models import Message, Notes, Documents, NewMessage
@ -148,6 +149,42 @@ class MessageViewSet(ModelViewSet):
qs = NewMessage.objects.filter(message__in=queryset, user=self.request.user).delete()
return queryset
from projects.forms import RealtyFormNew
class UpdateRealty(generics.UpdateAPIView):
queryset = Realty.objects.all()
serializer_class = RealtySerializer
# permission_classes = (permissions.IsAuthenticated,)
def update(self, request, *args, **kwargs):
# print("put realty request -->", request.data)
# realty = self.get_object()
# print("realty.name =", realty.name)
# realty_form = RealtyFormNew(request.data, request=request, instance=realty)
# if realty_form.is_valid():
# realty_form.name = 'New name'
# realty_form.save()
realty = self.get_object()
print("realty.id = ", realty.id)
serializer = self.serializer_class(realty, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
else:
print(serializer.errors)
return Response({'success': True})
# instance = self.get_object()
# instance.name = request.data.get("name")
# instance.save()
#
# serializer = self.get_serializer(instance)
# serializer.is_valid(raise_exception=True)
# self.perform_update(serializer)
#
# return Response(serializer.data)
class RealtyViewSet(ModelViewSet):
queryset = Realty.objects.filter(is_virtual=False)

@ -10,7 +10,8 @@ from wagtail.wagtailcore import urls as wagtail_urls
from common.views import CustomRegistrationView
from wallets.views import TmpCheckOrderView, TmpPaymentAvisoView
from .views import HomeTemplateView, TestChatTemplateView, TestView
from projects.views import CustomerRealtyTrashView, CustomerRealtyDeleteView, CustomerRealtyRestoreView, SortRealtyBy
from projects.views import CustomerRealtyTrashView, CustomerRealtyDeleteView, CustomerRealtyRestoreView, SortRealtyBy, \
RealtyUpdateView
urlpatterns = [
url(r'^$', HomeTemplateView.as_view()),
@ -21,6 +22,7 @@ urlpatterns = [
url(r'^projects/', include('projects.urls')),
url(r'^object/(?P<pk>\d+)/trash/$', CustomerRealtyTrashView.as_view(), name='customer-object-trash'),
url(r'^object/(?P<pk>\d+)/delete/$', CustomerRealtyDeleteView.as_view(), name='customer-object-delete'),
url(r'^object/(?P<pk>\d+)/edit/$', RealtyUpdateView.as_view(), name='customer-object-delete'),
url(r'^object/(?P<pk>\d+)/restore/$', CustomerRealtyRestoreView.as_view(), name='customer-object-restore'),
url(r'^objects/sort/$', SortRealtyBy.as_view(), name='sort-realty-by'),
url(r'^reviews/', include('reviews.urls')),

@ -40,9 +40,8 @@
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ({
/***/ 0:
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@ -53,17 +52,52 @@
var _sort_by = __webpack_require__(17);
var _custom_check = __webpack_require__(1);
$(function () {
(0, _bootstrap_tabs.restoreTab)();
(0, _bootstrap_tabs.tabsHashInit)();
(0, _custom_check.customCheckInit)();
window.toggler = _show_hide.toggler;
window.sortRealtyBy = _sort_by.sortRealtyBy;
// on load of the page: switch to the currently selected tab
});
/***/ },
/* 1 */
/***/ function(module, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
function customCheckInit() {
function tuneCheckBoxes($boxes) {
var currentState = $boxes.find("input").prop("checked") ? 'checked' : 'not-checked';
$boxes.find("div").hide();
$boxes.find("div." + currentState).show();
}
/***/ 6:
var $boxes = $('.custom-check');
tuneCheckBoxes($boxes);
$boxes.on("click", function (e) {
var inside_checkBox = $(e.target).parent().find("input");
inside_checkBox.prop("checked", !inside_checkBox.prop("checked"));
tuneCheckBoxes($boxes);
e.preventDefault();
return false;
});
}
exports.customCheckInit = customCheckInit;
/***/ },
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */
/***/ function(module, exports) {
'use strict';
@ -107,8 +141,15 @@
exports.getCookie = getCookie;
/***/ },
/***/ 15:
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */,
/* 11 */,
/* 12 */,
/* 13 */,
/* 14 */,
/* 15 */
/***/ function(module, exports) {
"use strict";
@ -124,8 +165,7 @@
exports.toggler = toggler;
/***/ },
/***/ 16:
/* 16 */
/***/ function(module, exports) {
"use strict";
@ -160,8 +200,7 @@
exports.restoreTab = restoreTab;
/***/ },
/***/ 17:
/* 17 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
@ -194,5 +233,4 @@
exports.sortRealtyBy = sortRealtyBy;
/***/ }
/******/ });
/******/ ]);

@ -223,8 +223,9 @@
this.options = { noHeader: noHeader };
var self = this;
this.$self.hide();
this.dataPromise = obj.dataPromise;
obj.dataPromise.then(function (data) {
this.dataPromise.then(function (data) {
data = data.results ? data.results : data;
_this.dataTree = noTree ? new _NoTreeData2.default(data) : new _DataTree2.default(data);
_this.$input = _this.$self.find('input[type="hidden"]');

@ -270,8 +270,9 @@
this.options = { noHeader: noHeader };
var self = this;
this.$self.hide();
this.dataPromise = obj.dataPromise;
obj.dataPromise.then(function (data) {
this.dataPromise.then(function (data) {
data = data.results ? data.results : data;
_this.dataTree = noTree ? new _NoTreeData2.default(data) : new _DataTree2.default(data);
_this.$input = _this.$self.find('input[type="hidden"]');
@ -1831,8 +1832,10 @@
box._addToSelectedContainer(data['construction_type'].id);
} else {
console.log("Нет совпадений для ", box.type);
box.selectedContainer.$input.removeAttr('value');
}
}
//Костыль для обновлени имени модельного окна "Редктирование Объекта"
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
@ -1847,6 +1850,10 @@
}
}
}
var name = data['name'];
var $name = $('#realtyEditModal').find('input[name=name]');
if ($name.length > 0) $name.val(name);
}).catch(this._onLoadDataError.bind(self));
}
}, {

@ -315,8 +315,9 @@
this.options = { noHeader: noHeader };
var self = this;
this.$self.hide();
this.dataPromise = obj.dataPromise;
obj.dataPromise.then(function (data) {
this.dataPromise.then(function (data) {
data = data.results ? data.results : data;
_this.dataTree = noTree ? new _NoTreeData2.default(data) : new _DataTree2.default(data);
_this.$input = _this.$self.find('input[type="hidden"]');
@ -1876,8 +1877,10 @@
box._addToSelectedContainer(data['construction_type'].id);
} else {
console.log("Нет совпадений для ", box.type);
box.selectedContainer.$input.removeAttr('value');
}
}
//Костыль для обновлени имени модельного окна "Редктирование Объекта"
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
@ -1892,6 +1895,10 @@
}
}
}
var name = data['name'];
var $name = $('#realtyEditModal').find('input[name=name]');
if ($name.length > 0) $name.val(name);
}).catch(this._onLoadDataError.bind(self));
}
}, {

File diff suppressed because it is too large Load Diff

@ -225,8 +225,9 @@
this.options = { noHeader: noHeader };
var self = this;
this.$self.hide();
this.dataPromise = obj.dataPromise;
obj.dataPromise.then(function (data) {
this.dataPromise.then(function (data) {
data = data.results ? data.results : data;
_this.dataTree = noTree ? new _NoTreeData2.default(data) : new _DataTree2.default(data);
_this.$input = _this.$self.find('input[type="hidden"]');
@ -1692,8 +1693,10 @@
box._addToSelectedContainer(data['construction_type'].id);
} else {
console.log("Нет совпадений для ", box.type);
box.selectedContainer.$input.removeAttr('value');
}
}
//Костыль для обновлени имени модельного окна "Редктирование Объекта"
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
@ -1708,6 +1711,10 @@
}
}
}
var name = data['name'];
var $name = $('#realtyEditModal').find('input[name=name]');
if ($name.length > 0) $name.val(name);
}).catch(this._onLoadDataError.bind(self));
}
}, {

@ -1,10 +1,12 @@
import {toggler} from './seeds/show_hide'
import {tabsHashInit, restoreTab} from './seeds/bootstrap_tabs'
import {sortRealtyBy} from './seeds/sort_by'
import {customCheckInit} from './seeds/custom_check'
$(function () {
restoreTab();
tabsHashInit();
customCheckInit();
window.toggler = toggler;
window.sortRealtyBy = sortRealtyBy;
// on load of the page: switch to the currently selected tab

@ -0,0 +1,162 @@
import SelectedContainer from 'components/SelectedContainer';
import SelectedContainerCreate from 'components/SelectedContainerCreate';
import NoTreeSelect from 'components/NoTreeSelect';
import TreeSelect from 'components/TreeSelect';
import SingleTreeSelect from 'components/SingleTreeSelect'
import SelectOrCreate from 'components/SelectOrCreate'
import {getCookie} from './utils'
$(function () {
// function createSpecs(url) {
// // SPECIALIZATIONS
// let sb_main = new TreeSelect($('#select-box-1'), {url, visible: true, required: true});
// // sb_main.setHeader("Специальность");
// let select_container = new SelectedContainer($('#selected-spec'),
// {
// obj: sb_main,
// onlyOne: true
// });
// sb_main.connectSelectedContainer(select_container);
// let sb_1 = new TreeSelect($('#select-box-2'), {obj: sb_main});
// let sb_2 = new TreeSelect($('#select-box-3'), {obj: sb_main});
// let sb_3 = new TreeSelect($('#select-box-4'), {obj: sb_main});
// let sb_4 = new TreeSelect($('#select-box-5'), {obj: sb_main});
//
// select_container.on("add", () => {
// let $container = $('#spec-value');
// $container.html($('#selected-spec').find(".selected-element").find(".name").html());
// });
//
// sb_main.setNearbySelectBox(sb_1);
// sb_1.setNearbySelectBox(sb_2, sb_main);
// sb_2.setNearbySelectBox(sb_3, sb_1);
// sb_3.setNearbySelectBox(sb_4, sb_2);
// sb_4.setNearbySelectBox("", sb_3);
//
// }
function createBuildingClass(url) {
// BUILDING-CLASSIFICATION
sb_build_main = new TreeSelect($('#sb-building-classification'), {url, visible: true});
sb_build_main.setHeader("Классификация здания");
let sb_build_1 = new TreeSelect($('#sb-building-sub-classification'), {obj: sb_build_main});
let select_build_container = new SelectedContainer($('#selected-building-classification'),
{
obj: sb_build_main,
onlyOne: true
});
sb_build_main.connectSelectedContainer(select_build_container);
sb_build_main.setNearbySelectBox(sb_build_1);
sb_build_1.setNearbySelectBox("", sb_build_main);
}
function createConstructionType(url) {
sb_constr_main = new NoTreeSelect($('#sb-construction-type'), {url, visible: true});
sb_constr_main.setHeader("Вид строительства");
let select_constr_type = new SelectedContainer($('#selected-construction-type'), {
obj: sb_constr_main,
noTree: true,
onlyOne: true
});
sb_constr_main.connectSelectedContainer(select_constr_type);
}
function createLocations(url) {
sb_loc_main = new TreeSelect($('#sb-location-1'), {url, visible: true});
sb_loc_main.setHeader("Местоположение");
let select_loc = new SelectedContainer($('#selected-location'),
{
obj: sb_loc_main,
onlyOne: true
});
sb_loc_main.connectSelectedContainer(select_loc);
let sb_loc_1 = new TreeSelect($('#sb-location-2'), {obj: sb_loc_main});
let sb_loc_2 = new TreeSelect($('#sb-location-3'), {obj: sb_loc_main});
sb_loc_main.setNearbySelectBox(sb_loc_1);
sb_loc_1.setNearbySelectBox(sb_loc_2, sb_loc_main);
sb_loc_2.setNearbySelectBox("", sb_loc_1);
}
function createRealty(url) {
sb_realty = new SelectOrCreate($('#sb-realty'), {url, visible: false});
sb_realty.setHeader(" ");
select_realty = new SelectedContainerCreate($('#selected-realty'),
{
obj: sb_realty,
noTree: true,
onlyOne: true,
noHeader: true
});
sb_realty.connectSelectedContainer(select_realty);
sb_realty.setLinkBoxes([sb_loc_main, sb_constr_main, sb_build_main]);
select_realty.on("add", (args)=> {
$('#checkbox-sb-realty').prop("checked", true);
sb_realty.show();
let id = args[0];
sb_realty.selectedEl.id = id;
sb_realty._fillBoxes();
})
}
let sb_realty;
let select_realty;
function setRealty(id) {
console.log('setRealty id -->', id);
Promise.all(sb_realty.boxes.map((box)=>box.dataPromise)).then(()=> {
sb_realty.boxes.map((box)=>{
try {
box.clearAllNext()
} catch (TypeError){
box.clear()
}
});
sb_realty.setElementById(id);
select_realty.add(id);
});
}
function updateRealty($form, user_id) {
// console.log("form action = ", $form.attr("action"));
let formData = $form.serialize();
let id = $('input[name=realty]').val();
console.log('user_id = ', user_id);
$.ajax({
// url: $form.attr("action"),
url: `/object/${id}/edit/`,
data: formData,
// async: false,
method: 'post',
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'))
},
success: function (data) {
console.log("success -->", data);
sortRealtyBy({sortBy: 'name', user_id: user_id, state: 'active'}, '#_objects');
$('#realtyEditModal').modal('toggle');
},
error: function (xhr, ajaxOptions, thrownError) {
console.log("error -->", xhr);
}
})
}
let sb_loc_main, sb_constr_main, sb_build_main;
// createSpecs('/api/specializations_flat');
window.setRealty = setRealty;
window.updateRealty = updateRealty;
createBuildingClass('/api/building_classifications');
createConstructionType('/api/construction_type');
createLocations('/api/locations_flat');
createRealty('/api/realties/current_user')
});

@ -94,8 +94,13 @@ export default class SelectOrCreate extends AbsBaseSelect {
box._addToSelectedContainer(data['construction_type'].id)
} else {
console.log("Нет совпадений для ", box.type);
box.selectedContainer.$input.removeAttr('value');
}
}
//Костыль для обновлени имени модельного окна "Редктирование Объекта"
let name = data['name'];
let $name = $('#realtyEditModal').find('input[name=name]');
if ($name.length > 0) $name.val(name)
}
)
.catch(this._onLoadDataError.bind(self));

@ -25,8 +25,9 @@ export default class SelectedContainer {
this.options = {noHeader};
const self = this;
this.$self.hide();
this.dataPromise = obj.dataPromise;
obj.dataPromise
this.dataPromise
.then(
(data) => {
data = data.results ? data.results : data;

@ -226,7 +226,10 @@ class RealtyForm(forms.ModelForm):
}
def __init__(self, *args, **kwargs):
try:
self.request = kwargs.pop('request')
except KeyError:
pass
super().__init__(*args, **kwargs)
if not self.data.get('extra_fields'):
@ -239,16 +242,6 @@ class RealtyForm(forms.ModelForm):
class RealtyFormNew(forms.ModelForm):
# building_classification = TreeNodeChoiceField(
# BuildingClassfication.objects.exclude(name='_root'),
# label="ll", initial='',
# widget=forms.Select(attrs={
# 'class': 'selectpicker',
# 'id': 'realtyBuildingClassificationId'
# }),
# level_indicator='',
# )
class Meta:
model = Realty

@ -0,0 +1,80 @@
{% load sass_tags %}
<div class="modal fade" id="realtyEditModal" tabindex="-1">
<div class="modal-dialog" role="document" style="width: 900px">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
<h4 class="modal-title">Редактировать Объект</h4>
</div>
<div class="modal-body">
<div class="container">
<form action="" method="POST" novalidate>
<div class="row mod-align-bottom" style="display: none">
<div class="col-lg-3">
<div id="sb-realty"></div>
</div>
<div class="col-lg-3">
<div class="selected-container horizontal" id="selected-realty">
<input class="-id" type="hidden" name="realty"
value="{{ form.realty.value }}">
<input class="-name" type="hidden" name="new_realty_name" value="">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<div class="simple-field">
<div class="header">Название объекта</div>
<i class="fa fa-question-circle-o" aria-hidden="true"></i>
<span class="required ">Обязательно</span>
<input value="" name="name" class="simple-input" autocomplete="off">
</div>
</div>
</div>
<div class="row">
<div class="col-lg-3">
<div class="vertical-child" id="sb-building-classification">
</div>
<div class="vertical-child" id="sb-building-sub-classification">
</div>
<div class="selected-container" id="selected-building-classification">
<input type="hidden"
name="building_classification"
value="{{ realty_form.building_classification.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-construction-type">
</div>
<div class="selected-container" id="selected-construction-type">
<input type="hidden"
name="construction_type"
value="{{ realty_form.construction_type.value }}">
</div>
</div>
<div class="col-lg-3">
<div class="vertical-child" id="sb-location-1"></div>
<div class="vertical-child" id="sb-location-2"></div>
<div class="vertical-child" id="sb-location-3"></div>
<div class="selected-container" id="selected-location">
<input type="hidden"
name="location"
value="{{ realty_form.location.value }}">
</div>
</div>
</div>
</form>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button>
<button type="button"
onclick="updateRealty($('#realtyEditModal').find('form'), {{ customer.id }}); return null"
class="btn btn-primary -action-button">
Сохранить
</button>
</div>
</div>
</div>
</div>

@ -413,6 +413,18 @@ class SortRealtyBy(View):
return render(self.request, 'partials/inc-objects.html', self.get_context_data())
class RealtyUpdateView(BaseMixin, View):
def post(self, request, *args, **kwargs):
# print("POST = ", request.POST)
realty = get_object_or_404(Realty, pk=kwargs.get('pk'))
realty_form = RealtyFormNew(request.POST, request=request, instance=realty)
if realty_form.is_valid():
realty_form.save()
if self.request.is_ajax():
return JsonResponse({'redirect_to': '...'}, status=200)
class CustomerProjectCreateView(BaseMixin, View):
form_class = CustomerProjectEditFormNew
realty_form = RealtyFormNew

@ -6,10 +6,13 @@
<link rel='stylesheet' href='{% sass_src "sass/customer-profile.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/old_main.sass" %}'>
<link rel='stylesheet' href='{% sass_src "sass/components/custom-components.sass" %}'>
{# <link rel='stylesheet' href='{% static "css/main.css" %}'>#}
{# Для модального окна "mod-realty-edit" #}
<link rel='stylesheet' href='{% sass_src "lib/proekton-components/sass/components.sass" %}'>
{% endblock %}
{% block content %}
{% include 'partials/modals/mod-realty-edit.html' %}
<div class="container main-scope">
<div class="row main-content">
<div class="col-lg-12">
@ -39,4 +42,6 @@
{% block personal_js %}
<script src="{% static 'js/build/customer_profile.js' %}"></script>
{# Для модального окна "mod-realty-edit" #}
<script src='{% static "js/build/init_modal_realty_edit.js"%}'></script>
{% endblock %}

@ -19,7 +19,17 @@
</a>
</form>
{% else %}
<a
href="#"
onclick="setRealty({{ object.id }});return false"
{# data-contractor-id="{{ team.owner.pk }}"#}
data-object-id="{{ object.id }}"
data-is-team-offer="true"
data-toggle="modal"
data-target="#realtyEditModal">
<span class="icon-protect">Редактировать</span>
</a>
{% endif %}
</div>
@ -78,7 +88,8 @@
<tr>
<td><strong>{{ forloop.counter }}</strong></td>
<td>
<a class="cut-name" href="{% url 'projects:detail' project.pk %}">{{ project.name|truncatechars:25 }}</a>
<a class="cut-name"
href="{% url 'projects:detail' project.pk %}">{{ project.name|truncatechars:25 }}</a>
</td>
<td>
<span class="icon-calendar" style="white-space: nowrap">{{ project.created }}</span>

@ -26,6 +26,8 @@ module.exports = {
//portfolio
init_portfolio_create_edit: "./assets/js/src/init_portfolio_create_edit.js",
portfolio_create_edit: "./assets/js/src/portfolio_create_edit.js",
//modal Realty edit
init_modal_realty_edit: "./assets/js/src/init_modal_realty_edit.js",
},
output: {

Loading…
Cancel
Save