From f576ecceb2920deb0f5cd0799963638c01e43213 Mon Sep 17 00:00:00 2001 From: booblegum Date: Tue, 31 Jan 2017 22:04:45 +0300 Subject: [PATCH] first work version, amen --- api/urls.py | 10 +- api/views.py | 42 +- archilance/urls.py | 2 +- assets/css/extra.css | 34 +- assets/css/main.css | 226 +- assets/img/icons/icon_arbitration.png | Bin 0 -> 60958 bytes assets/img/icons/icon_arrow_gray.png | Bin 0 -> 1074 bytes assets/img/icons/icon_books.png | Bin 0 -> 8500 bytes assets/img/icons/icon_check.png | Bin 0 -> 5252 bytes assets/img/icons/icon_coins_gray.png | Bin 0 -> 29029 bytes assets/img/icons/icon_coins_green.png | Bin 0 -> 21233 bytes assets/img/icons/icon_coins_red.png | Bin 0 -> 15872 bytes assets/img/icons/icon_complete_stage.png | Bin 0 -> 2282 bytes assets/img/icons/icon_credit_card.png | Bin 0 -> 86055 bytes assets/img/icons/icon_credit_card_gray.png | Bin 0 -> 26517 bytes assets/img/icons/icon_hands_gray.png | Bin 0 -> 3576 bytes assets/img/icons/icon_pen_black.png | Bin 0 -> 4523 bytes assets/img/icons/icon_print.png | Bin 0 -> 4480 bytes assets/img/icons/icon_protect.png | Bin 0 -> 1107 bytes assets/js/build/chat_contractor_oop.js | 2773 +++++++++++++++++ assets/js/build/chat_customer_oop.js | 2584 +++++++++++++++ assets/js/build/contractor_filter.js | 28 +- assets/js/build/create_project.js | 161 +- assets/js/build/create_worksell.js | 48 +- assets/js/build/custom_components.js | 8 +- assets/js/build/customer_profile.js | 100 +- assets/js/build/debugUtilsInit.js | 79 + assets/js/build/home_page.js | 4 +- assets/js/build/init_contractor_filter.js | 68 +- assets/js/build/init_create_worksell.js | 95 +- .../js/build/init_customer_project_create.js | 101 +- assets/js/build/init_modal_realty_edit.js | 99 +- assets/js/build/init_portfolio_create_edit.js | 87 +- assets/js/build/init_worksell_filter.js | 68 +- assets/js/build/portfolio_create_edit.js | 40 +- assets/js/build/project_filter.js | 23 +- assets/js/build/registration.js | 4 +- assets/js/build/user_profile_edit.js | 16 +- assets/js/build/worksell_filter.js | 28 +- assets/js/src/chat/BINDS.js | 445 +++ .../src/chat/ChatContractorPageController.js | 1 + .../js/src/chat/ChatCustomerPageController.js | 1 + assets/js/src/chat/DocumentsControllers.js | 67 + assets/js/src/chat/MessagesControllers.js | 61 + assets/js/src/chat/Stages.js | 340 ++ .../js/src/chat/StagesContractorController.js | 446 +++ .../js/src/chat/StagesCustomerController.js | 545 ++++ assets/js/src/chat/archiveProjects.js | 84 + assets/js/src/chat/chats.js | 145 + assets/js/src/chat/documents.js | 157 + .../chat/formats/receive_message_formats.py | 9 + .../src/chat/formats/send_message_formats.js | 36 + assets/js/src/chat/loaders.js | 28 + assets/js/src/chat/messageCounters.js | 43 + assets/js/src/chat/notes.js | 77 + assets/js/src/chat/parts.js | 27 + .../buttons/bntCompleteStage_tmpl.html | 8 + .../templates/buttons/btnSendReview_tmpl.html | 6 + .../links/document_attach_file_tmpl.html | 12 + .../templates/links/document_link_tmpl.html | 7 + .../js/src/chat/templates/message_tmpl.html | 7 + assets/js/src/chat/templates/note_tmpl.html | 6 + .../js/src/chat/templates/reserved_tmpl.html | 5 + .../chat/templates/stage_approved_tmpl.html | 29 + assets/js/src/chat/templates/stage_tmpl.html | 29 + .../chat/templates/work_in_process_tmpl.html | 10 + assets/js/src/chat/utils_debug.js | 6 + assets/js/src/chat/wsChatConnect.js | 114 + assets/js/src/chat_contractor_oop.js | 63 + assets/js/src/chat_customer_oop.js | 47 + assets/js/src/debugUtilsInit.js | 5 + assets/js/src/init_customer_project_create.js | 6 +- assets/js/src/seeds/read_more.js | 6 - assets/js/{ => trash}/chat.js | 183 +- assets/js/{ => trash}/chat_contractor.js | 132 +- assets/js/{ => trash}/chat_customer.js | 7 +- chat/chat.py | 52 +- chat/migrations/0015_message_is_system.py | 20 + chat/models.py | 3 + chat/serializers.py | 1 + chat/static/sass/chat_add.sass | 325 ++ chat/templates/chat_contractor.html | 630 ++-- chat/templates/chat_customer.html | 510 +-- chat/templates/inc-contact-card.html | 5 +- .../partials/inc-attach-documents.html | 50 + chat/templates/partials/inc-order-card.html | 47 + chat/templates/partials/inc-team-card.html | 61 + .../partials/inc-websocket-connect.htm | 156 + chat/templates/reverse_stage_modal.html | 86 +- chat/templates/review_add_modal.html | 28 +- chat/views.py | 14 +- package.json | 12 +- projects/apps.py | 2 +- .../migrations/0054_auto_20170131_1609.py | 20 + projects/models.py | 5 +- projects/serializers.py | 32 +- projects/signals.py | 2 +- projects/templates/project_detail.html | 7 +- reviews/apps.py | 2 +- reviews/signals.py | 7 +- templates/partials/_base.html | 73 +- templates/partials/base.html | 75 +- users/apps.py | 2 +- users/migrations/0026_auto_20170131_1609.py | 100 + users/static/sass/customer-profile.sass | 2 +- users/templates/contractor_office.html | 8 +- users/templates/contractor_profile.html | 4 +- users/templates/partials/inc-objects.html | 2 +- users/templatetags/user_tags.py | 2 +- users/views.py | 2 +- wallets/apps.py | 2 +- wallets/signals.py | 2 + wallets/views.py | 11 +- webpack.config.js | 29 +- 114 files changed, 10821 insertions(+), 1498 deletions(-) create mode 100644 assets/img/icons/icon_arbitration.png create mode 100644 assets/img/icons/icon_arrow_gray.png create mode 100644 assets/img/icons/icon_books.png create mode 100644 assets/img/icons/icon_check.png create mode 100644 assets/img/icons/icon_coins_gray.png create mode 100644 assets/img/icons/icon_coins_green.png create mode 100644 assets/img/icons/icon_coins_red.png create mode 100644 assets/img/icons/icon_complete_stage.png create mode 100644 assets/img/icons/icon_credit_card.png create mode 100644 assets/img/icons/icon_credit_card_gray.png create mode 100644 assets/img/icons/icon_hands_gray.png create mode 100644 assets/img/icons/icon_pen_black.png create mode 100644 assets/img/icons/icon_print.png create mode 100644 assets/img/icons/icon_protect.png create mode 100644 assets/js/build/chat_contractor_oop.js create mode 100644 assets/js/build/chat_customer_oop.js create mode 100644 assets/js/build/debugUtilsInit.js create mode 100644 assets/js/src/chat/BINDS.js create mode 100644 assets/js/src/chat/ChatContractorPageController.js create mode 100644 assets/js/src/chat/ChatCustomerPageController.js create mode 100644 assets/js/src/chat/DocumentsControllers.js create mode 100644 assets/js/src/chat/MessagesControllers.js create mode 100644 assets/js/src/chat/Stages.js create mode 100644 assets/js/src/chat/StagesContractorController.js create mode 100644 assets/js/src/chat/StagesCustomerController.js create mode 100644 assets/js/src/chat/archiveProjects.js create mode 100644 assets/js/src/chat/chats.js create mode 100644 assets/js/src/chat/documents.js create mode 100644 assets/js/src/chat/formats/receive_message_formats.py create mode 100644 assets/js/src/chat/formats/send_message_formats.js create mode 100644 assets/js/src/chat/loaders.js create mode 100644 assets/js/src/chat/messageCounters.js create mode 100644 assets/js/src/chat/notes.js create mode 100644 assets/js/src/chat/parts.js create mode 100644 assets/js/src/chat/templates/buttons/bntCompleteStage_tmpl.html create mode 100644 assets/js/src/chat/templates/buttons/btnSendReview_tmpl.html create mode 100644 assets/js/src/chat/templates/links/document_attach_file_tmpl.html create mode 100644 assets/js/src/chat/templates/links/document_link_tmpl.html create mode 100644 assets/js/src/chat/templates/message_tmpl.html create mode 100644 assets/js/src/chat/templates/note_tmpl.html create mode 100644 assets/js/src/chat/templates/reserved_tmpl.html create mode 100644 assets/js/src/chat/templates/stage_approved_tmpl.html create mode 100644 assets/js/src/chat/templates/stage_tmpl.html create mode 100644 assets/js/src/chat/templates/work_in_process_tmpl.html create mode 100644 assets/js/src/chat/utils_debug.js create mode 100644 assets/js/src/chat/wsChatConnect.js create mode 100644 assets/js/src/chat_contractor_oop.js create mode 100644 assets/js/src/chat_customer_oop.js create mode 100644 assets/js/src/debugUtilsInit.js rename assets/js/{ => trash}/chat.js (88%) rename assets/js/{ => trash}/chat_contractor.js (85%) rename assets/js/{ => trash}/chat_customer.js (99%) create mode 100644 chat/migrations/0015_message_is_system.py create mode 100644 chat/static/sass/chat_add.sass create mode 100644 chat/templates/partials/inc-attach-documents.html create mode 100644 chat/templates/partials/inc-order-card.html create mode 100644 chat/templates/partials/inc-team-card.html create mode 100644 chat/templates/partials/inc-websocket-connect.htm create mode 100644 projects/migrations/0054_auto_20170131_1609.py create mode 100644 users/migrations/0026_auto_20170131_1609.py diff --git a/api/urls.py b/api/urls.py index ecce484..89e3656 100755 --- a/api/urls.py +++ b/api/urls.py @@ -23,6 +23,7 @@ from .views import ( SpecializationViewSetFlat, ConstructionTypeViewSet, StageViewSet, + StageUpdateViewSet, TeamViewSet, UserViewSet, WorkSellPhotoViewSet, @@ -58,8 +59,9 @@ router.register(r'work-sells', WorkSellViewSet) urlpatterns = router.urls -# urlpatterns = [ -# url(r'^demo_realties/(?P\d+)/$', UpdateRealty.as_view()), -# ] +urlpatterns = [ + url(r'^update_stages/$', StageUpdateViewSet.as_view()), + # url(r'^orders/(?P\d+)/$', OrderViewSet.as_view({'delete'})), +] -# urlpatterns += router.urls \ No newline at end of file +urlpatterns += router.urls \ No newline at end of file diff --git a/api/views.py b/api/views.py index a6b3db5..5d9e311 100755 --- a/api/views.py +++ b/api/views.py @@ -1,11 +1,13 @@ from django.conf import settings from django.db.models import Q, F +from django.http import Http404 from rest_framework import permissions 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 rest_framework import status from chat.filters import MessageFilterSet, NoteFilterSet, DocumentFilterSet from chat.models import Message, Notes, Documents, NewMessage @@ -22,7 +24,7 @@ from projects.models import (Project, Realty, Stage, Portfolio, PortfolioPhoto, from projects.serializers import ( ProjectSerializer, RealtySerializer, StageSerializer, PortfolioSerializer, PortfolioPhotoSerializer, AnswerSerializer, OrderSerializer, BuildingClassificationSerializeFlat, - ConstructionTypeSerializer) + ConstructionTypeSerializer, StageListSerializer) from reviews.filters import ReviewFilterSet from reviews.models import Review from reviews.serializers import ReviewSerializer @@ -59,6 +61,31 @@ class StageViewSet(ModelViewSet): permission_classes = (permissions.IsAuthenticatedOrReadOnly,) +class StageUpdateViewSet(generics.UpdateAPIView): + # def __init__(self, *args, **kwargs): + # many = kwargs.pop('many', True) + # super().__init__(many=many, *args, **kwargs) + model = Stage + queryset = model.objects.all() + serializer_class = StageSerializer + + def put(self, request, *args, **kwargs): + # print("put request = ", request.data) + print(request.data) + result = request.data + print("result = ", result) + # ids = [obj["id"] for obj in result] + # queryset = self.model.objects.filter(pk__in=ids) + # print("count = ", queryset.count()) + serializer = self.serializer_class(data=result, many=True) + serializer.is_valid() + serializer.save() + # print("serializer = ", serializer) + return Response(serializer.data, status=status.HTTP_200_OK) + # print("errors = ", serializer.errors) + # return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + class ReviewViewSet(ModelViewSet): queryset = Review.objects.all() serializer_class = ReviewSerializer @@ -231,6 +258,19 @@ class OrderViewSet(ModelViewSet): filter_class = OrderFilterSet permission_classes = (permissions.IsAuthenticatedOrReadOnly,) + def destroy(self, request, *args, **kwargs): + print("destroy request = ", request, 'args = ', args, 'kwargs = ', kwargs) + try: + instance = self.get_object() + project = instance.project + project.state = 'deleted' + project.save() + # self.perform_destroy(instance) + print('inst = ', instance) + except Http404: + pass + return Response(status=status.HTTP_204_NO_CONTENT) + class SpecializationViewSet(ModelViewSet): try: # TODO: dirty diff --git a/archilance/urls.py b/archilance/urls.py index 0028bca..9745da0 100644 --- a/archilance/urls.py +++ b/archilance/urls.py @@ -22,7 +22,7 @@ urlpatterns = [ url(r'^projects/', include('projects.urls')), url(r'^object/(?P\d+)/trash/$', CustomerRealtyTrashView.as_view(), name='customer-object-trash'), url(r'^object/(?P\d+)/delete/$', CustomerRealtyDeleteView.as_view(), name='customer-object-delete'), - url(r'^object/(?P\d+)/edit/$', RealtyUpdateView.as_view(), name='customer-object-delete'), + url(r'^object/(?P\d+)/edit/$', RealtyUpdateView.as_view(), name='customer-object-edit'), url(r'^object/(?P\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')), diff --git a/assets/css/extra.css b/assets/css/extra.css index f2b4ec5..d9d2a3b 100644 --- a/assets/css/extra.css +++ b/assets/css/extra.css @@ -72,18 +72,6 @@ margin: 0; } -.stepssBlock ul li.reserved::before { - background: rgba(0, 0, 0, 0) url("../img/reserved2.png") no-repeat scroll center center / cover; - height: 16px; - width: 17px; -} - -.stepssBlock ul li.unreserved::before { - background: rgba(0, 0, 0, 0) url("../img/reserved.png") no-repeat scroll center center / cover; - height: 14px; - width: 13px; -} - .chat-textarea { width: 100%; height: 110px; @@ -135,7 +123,7 @@ } .documentsChat > p { - font-size: 20px; + font-size: 16px; } #message-chat-order-space, #message-chat-team-space { @@ -229,6 +217,26 @@ background-color: #ebebeb; } +.count-order { + display: inline-block; + margin-left: 5px; + margin-right: 5px; + width: 20px; + height: 20px; + border-radius: 100%; + line-height: 20px; + text-align: center; + font-size: 10px; + font-family: 'Arial-MT-Regular', sans-serif; + /*position: absolute;*/ + /*top: 14px;*/ + cursor: pointer; + -webkit-transition: all 0.3s ease-out; + -moz-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; + background-color: #ebebeb; +} + li a:active .count-tab, li a:hover .count-tab { background-color: #FF0027; color: white; diff --git a/assets/css/main.css b/assets/css/main.css index 4bbeb2f..5b1dfdc 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -501,15 +501,6 @@ a, a:hover, a:focus, a:active { float: right !important; } -.triangle1 { - position: absolute; - border: 30px solid transparent; - border-top: 17px solid white; - top: 0; - left: 50%; - margin-left: -30px; -} - footer { width: 100%; position: relative; @@ -1964,8 +1955,8 @@ footer:after { font-family: 'pfbeausanspro-reg', sans-serif; position: relative; text-align: left; - padding: 22px 61px 22px 21px; - height: 94px; + padding: 20px 61px 20px 21px; + /*height: 94px;*/ } .profileTabs2 ul .active a:after { @@ -2423,6 +2414,15 @@ footer:after { margin: 32px 0 50px 4px; } +.triangle1 { + position: absolute; + border: 30px solid transparent; + border-top: 17px solid white; + top: 0; + left: 50%; + margin-left: -30px; +} + .triangle2 { position: absolute; border: 30px solid transparent; @@ -3321,12 +3321,12 @@ footer:after { .textCommChat { width: 84%; - float: left; - margin: 11px 0 30px 0; + /*float: left;*/ + margin: 6px 0; font-size: 14px; font-family: 'Arial-MT-Regular', sans-serif; color: #3c1a06; - line-height: 25px; + line-height: 18px; } .greenNCC { @@ -3384,7 +3384,7 @@ footer:after { float: right; border-radius: 40px; font-family: 'pfdintextcomppro-regular', sans-serif; - letter-spacing: 2px; + letter-spacing: 1px; color: #373737; font-size: 15px; border: 1px solid #BEBEBE; @@ -3429,8 +3429,9 @@ footer:after { } .textAreaBlock2 a, .textAreaBlock2 a:link, .textAreaBlock2 a:visited { - border: 1px solid #bebebe; - border-radius: 40px; + border: 1px solid #f1f1f1; + background-color: #f1f1f1; + /*border-radius: 40px;*/ color: #373737; display: inline-block; font-family: "pfdintextcomppro-regular",sans-serif; @@ -3479,6 +3480,8 @@ footer:after { .wrMessages { padding: 0; background-color: #F7F7F7; + border-right: 1px solid #DADADA; + /*border-left: 1px solid #DADADA;*/ } .messageBlock { @@ -3738,18 +3741,18 @@ footer:after { margin: 0 0 0 30px; } -.documentsChat a, .documentsChat a:link, .documentsChat a:visited { - color: #5a5a5a; - border-radius: 40px; - border: 1px solid #BEBEBE; - font-family: Arial, Verdana, Helvetica, sans-serif; - font-size: 12px; - font-style: italic; - padding: 10px 21px 10px 32px; - background: url('../img/btnDoc.png') no-repeat 10px 6px; - float: left; - margin: 19px 0 -10px 0; -} +/*.documentsChat a, .documentsChat a:link, .documentsChat a:visited {*/ + /*color: #5a5a5a;*/ + /*border-radius: 40px;*/ + /*border: 1px solid #BEBEBE;*/ + /*font-family: Arial, Verdana, Helvetica, sans-serif;*/ + /*font-size: 12px;*/ + /*font-style: italic;*/ + /*padding: 10px 21px 10px 32px;*/ + /*background: url('../img/btnDoc.png') no-repeat 10px 6px;*/ + /*float: left;*/ + /*margin: 19px 0 -10px 0;*/ +/*}*/ .wrChat1 .textAreaBlock2 { border: none; @@ -3811,12 +3814,13 @@ footer:after { .titleOB { width: 100%; - float: left; + /*float: left;*/ font-family: 'Arial-MT-Regular', sans-serif; font-size: 18px; color: #2c2c2c; - margin: 0 0 0 0; + margin: 0; line-height: 20px; + padding-right: 20px; } .pOB { @@ -3828,6 +3832,12 @@ footer:after { margin: 10px 0 10px 0; } +.pDB { + font-family: 'Arial-MT-Regular', sans-serif; + font-size: 12px; + color: #5d5d5d; +} + .pOB span { font-family: Arial, Verdana, Helvetica, sans-serif; font-weight: bold; @@ -3899,11 +3909,11 @@ footer:after { transition: all 0.3s ease-out; } -.orderBlock:hover .dimovChat { - -webkit-transform: rotate(90deg); - -moz-transform: rotate(90deg); - transform: rotate(90deg); -} +/*.orderBlock:hover .dimovChat {*/ + /*-webkit-transform: rotate(90deg);*/ + /*-moz-transform: rotate(90deg);*/ + /*transform: rotate(90deg);*/ +/*}*/ .orAct .dimovChat { -webkit-transform: rotate(90deg); @@ -3911,9 +3921,9 @@ footer:after { transform: rotate(90deg); } -.orderBlock:hover .hideOBB { - display: block; -} +/*.orderBlock:hover .hideOBB {*/ + /*display: block;*/ +/*}*/ .orAct .hideOBB { display: block !important; @@ -3921,6 +3931,8 @@ footer:after { .wrstepschat { float: left; + /*border-right: 1px solid #DADADA;*/ + border-left: 1px solid #DADADA; padding: 0; } @@ -3932,6 +3944,36 @@ footer:after { margin: 26px 15px 20px 15px; color: black; } +.remove-margin{ + margin-right: -15px; + margin-left: -15px; + position: relative; +} +.tab-content .header-wrapper { + /*display: inline-block;*/ + font-size: 24px; + font-family: 'pfbeausanspro-reg', sans-serif; + padding: 26px 0px; + width: 100%; + color: black; + background-color: #F3F3F3; + text-align: center; +} + +.tab-content .header-wrapper .header{ + background-color: white; + display: inline-block; + width: 100%; +} + +.triangle-header { + position: absolute; + border: 30px solid transparent; + border-top: 17px solid white; + top: 60px; + left: 50%; + margin-left: -30px; +} .stepssBlock { width: 100%; @@ -3941,12 +3983,12 @@ footer:after { border-bottom: 1px solid black; z-index: 9; position: relative; - margin-bottom: -1px; + /*margin-bottom: -1px;*/ } .titleStepss { width: 100%; - float: left; + /*float: left;*/ font-size: 18px; font-family: 'Arial-MT-Regular', sans-serif; margin: 0 0 15px 0; @@ -3955,7 +3997,7 @@ footer:after { .textStepss { width: 100%; - float: left; + /*float: left;*/ font-size: 14px; line-height: 17px; font-family: 'Arial-MT-Regular', sans-serif; @@ -3968,7 +4010,7 @@ footer:after { border-top: 1px solid transparent; border-bottom: 1px solid transparent; padding: 15px; - margin-bottom: -15px; + /*margin-bottom: -15px;*/ background-color: white; position: relative; -webkit-transition: all 0.3s ease-out; @@ -4058,39 +4100,39 @@ footer:after { margin-top: 15px; } -.stepssBlock ul { - float: left; - margin: 10px 0 0 30px; -} +/*.stepssBlock ul {*/ + /*float: left;*/ + /*margin: 10px 0 0 30px;*/ +/*}*/ -.stepssBlock ul li { - font-size: 12px; - color: #525252; - font-family: 'Arial-MT-Regular', sans-serif; - margin-bottom: 8px; - position: relative; -} +/*.stepssBlock ul li {*/ + /*font-size: 12px;*/ + /*color: #525252;*/ + /*font-family: 'Arial-MT-Regular', sans-serif;*/ + /*margin-bottom: 8px;*/ + /*position: relative;*/ +/*}*/ -.stepssBlock ul li:before { - content: ''; - position: absolute; - left: -30px; - top: 2px; -} +/*.stepssBlock ul li:before {*/ + /*content: '';*/ + /*position: absolute;*/ + /*left: -30px;*/ + /*top: 2px;*/ +/*}*/ -.stepssBlock ul li:first-child:before { - width: 13px; - height: 14px; - background: url('../img/reserved.png') no-repeat center; - background-size: cover; -} +/*.stepssBlock ul li:first-child:before {*/ + /*width: 13px;*/ + /*height: 14px;*/ + /*background: url('../img/reserved.png') no-repeat center;*/ + /*background-size: cover;*/ +/*}*/ -.stepssBlock ul li:last-child:before { - width: 17px; - height: 16px; - background: url('../img/reserved2.png') no-repeat center; - background-size: cover; -} +/*.stepssBlock ul li:last-child:before {*/ + /*width: 17px;*/ + /*height: 16px;*/ + /*background: url('../img/reserved2.png') no-repeat center;*/ + /*background-size: cover;*/ +/*}*/ .infoProfile .dropdown-menu { @@ -4477,12 +4519,12 @@ footer:after { color: #009DD9; } -label { - width: 23px; - height: 23px; - display: block; - position: relative; -} +/*label {*/ + /*width: 23px;*/ + /*height: 23px;*/ + /*display: block;*/ + /*position: relative;*/ +/*}*/ /*input[type="checkbox"] + span {*/ /*position: absolute;*/ @@ -5752,13 +5794,13 @@ input[type="radio"]:checked + span { #order-stages .checkbox label{ margin-top: 0; } -#order-stages > div { - display: table; - width: 100%; - padding-bottom: 14px; - border-bottom: 1px solid #2c2c2c; - margin-bottom: 14px; -} +/*#order-stages > div {*/ + /*!*display: table;*!*/ + /*!*width: 100%;*!*/ + /*padding-bottom: 14px;*/ + /*border-bottom: 1px solid #2c2c2c;*/ + /*margin-bottom: 14px;*/ +/*}*/ #order-stages > div:nth-last-child(2), #order-stages > div:last-child{ border: none; } @@ -5975,19 +6017,19 @@ a.linkS2[data-target="#withdraw-money"]{ display: table; max-height: 845px; overflow-y: scroll; - border-right: 1px solid #DADADA; - border-left: 1px solid #DADADA; - padding-bottom: 300px; + /*border-right: 1px solid #DADADA;*/ + /*border-left: 1px solid #DADADA;*/ + /*padding-bottom: 300px;*/ } #message-chat-space { height: 312px; display: block; overflow: auto; } -#contact-chat-form{ - position: absolute; - bottom: 0; -} +/*#contact-chat-form{*/ + /*position: absolute;*/ + /*bottom: 0;*/ +/*}*/ .dropdown-menu > li > a{ white-space: normal; } diff --git a/assets/img/icons/icon_arbitration.png b/assets/img/icons/icon_arbitration.png new file mode 100644 index 0000000000000000000000000000000000000000..801cdf59018fc0d9a820cccc02f610f062425eac GIT binary patch literal 60958 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 bB0!3kIav(|1S~n2(1EswfqIFm)tmnZmqW8~ literal 0 HcmV?d00001 diff --git a/assets/img/icons/icon_arrow_gray.png b/assets/img/icons/icon_arrow_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd29c77258aea6932fbed4350a7eb5459383ec9 GIT binary patch literal 1074 zcmV-21kL-2P)>OkqKg@qovD=bJWt0Eq}?8UHz#zGr= zNb!(U1Ql5iE?9$Yb1@V|5SkvODj13hg;KN-%|9n5GtR%?^w7>Q8+9$#2g3~W``-KB z``(*3z&&khYRVZ51{(ojZf@>Y9D84azP`Tqyj~)yLui=>c5)eW_2!Y$}e(Ll2UZvA%763w_(0?QF`~7bvxVpMh{v|S6 zTU$Tx@9+O^baeFH+1c4Q6RCBanVG@-{JeD@2n0TCX=!-`0ES_h?{z^Cdc0omR{%gM z1*H^%AZ#8T9X;#r?$%8rs|VB5(}+f+$Y!%lBocX4Utj;F+wFed(9i%gh+!Bo48wXh z@1|rN$369UJg<(AkH-M$p-||b3WkS=;rIJ7I5~ABkR4PA|N~O=N9)!c; z7rni`5qm#s2{cW!DpFMys;WX!6lj_TP1B(3Iw+;kbsdr<{hZI|KXCxS`1p8RPfyPm zwPOeX)oK-@C_3g&V_;x_RTQN)o6Vw7 zC_vYBuq+Ev6n`ofi{CCREbIWFwcpF+&15noTU%RJZ~$<0b#;-m zvoprwaDWg3r_+gIvACE{r(eY5@hdZ+-3b6#mVL*Rt5hoO?CE{g z%Ch{MAP6tx@%RjuaxgBrcrUs?-FG7d`fKW=mUtC+9>ex8WH8SX*1$H4Gz12q6r^ z-1(2-c^mg$P4XRu<%Y`SFlK=n!07*qoM6N<$g7z)w9{>OV literal 0 HcmV?d00001 diff --git a/assets/img/icons/icon_books.png b/assets/img/icons/icon_books.png new file mode 100644 index 0000000000000000000000000000000000000000..4d2221c059fb00c8de567db68b2cd11e09d6dc11 GIT binary patch literal 8500 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­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 VLEn{`U(`O>O>j@40u~_5Ukbin_724a{Ltc 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 Gl=xqG&B6Ep literal 0 HcmV?d00001 diff --git a/assets/img/icons/icon_complete_stage.png b/assets/img/icons/icon_complete_stage.png new file mode 100644 index 0000000000000000000000000000000000000000..89e073f75642c9d924ec6972cc806135dc8c1f16 GIT binary patch literal 2282 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⋙3B2RLj<~;eJZ^vwx=AOJD%8+^bdNW;| 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 CjWa(0 literal 0 HcmV?d00001 diff --git a/assets/img/icons/icon_credit_card_gray.png b/assets/img/icons/icon_credit_card_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..57a9faf3a706c3c4e9a23115900051a67edd12ae GIT binary patch literal 26517 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 literal 0 HcmV?d00001 diff --git a/assets/img/icons/icon_pen_black.png b/assets/img/icons/icon_pen_black.png new file mode 100644 index 0000000000000000000000000000000000000000..3d902ead0aaecda91b39910a4b6f34c7474133bb GIT binary patch literal 4523 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 literal 0 HcmV?d00001 diff --git a/assets/img/icons/icon_print.png b/assets/img/icons/icon_print.png new file mode 100644 index 0000000000000000000000000000000000000000..42648fb98a1a0880f24cad4f1731dd47218fa176 GIT binary patch literal 4480 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 SPeLpJ0000$S zK~zY`rPW(#lvfl5;BTU~K~rl9@q#j7ViAfcZANL7ictwM1p88~4`DzE1RGxz27Hk~ zLq!p_Qi9@(1Vt+NqC+%zfx$`4WsFkOQpA`9(}boP92GASFMZH|m^5Aj-B0JT*82B< z&RKgivG@qJm^=~iqzPbhP=ghii7WqC^ke*h<q6km$4_*Z# zA*{h{e2)2VgcTMRibkXA>gvX2vSY^%$BrG--`^iBJ;k5s$8ZS8vk7a~tWi->p{AzB zv}w~a>)qYm7A;yN6bgZd4<9;s@SwA2&q^c`V?G)}Bc`;pv?wkvmYbV9F0=0LZmU9ABL?V%3`XmP1J$v>{Wo4y!Jg%{^(e>-sZQZ(6BoZ++G^Dk)HN)xY z=?R8^=b#T`ere8}IbhYQRpRlu%F0SGb?Q|6_U%(&Uq1#1SFU7?)|Z1G=;-Lk02VJ^ zEEEb!Bobb}9B-Vqwl=V2$&$=kXJ=+pP#R|xEP!~d2*cSrAwDU zSy|cZ)cX2@qj-#-96U!CG&VM7h|y>i9654ijNpkACnORH;c(c>l`Fx~qep}7F1!f5 zpM>-0&u7S+Hf=I<=1k4a%^DgSz=H=5?A^N;#9}d%C%>+Q7cN`~Xf4?Vr5l6EWYVES zhd^Flo&yICfGu0LNTpJ$s;ZC)^&w{6=t z`}gn9%;(LUr?s_JI2;C%NJLjx7yN>@|5mBL@a53Z&}V~#gMsCgm6aJ88PVC?qfpr8OWH8lnA_c`i< z_x?6f_!i$66clK0Z&z4YI1bR;+ba@@xOeX!{EE{bs{E(Xap%q*6%`d@>>CJ{mzM{E zZHP~#oxH*!{Bh&P4Qtn~4K6||l~P(->gLUx-rV%z?27-P#`gl9n4eCkXCFR%SZ;2v zjT<+*fB!yQ!_OFf8#xq<#opQZ_Uze{gDR9~EuX>hSS", orderId, projectId, recipentId); + this.data = {}; //JSON + this.stages = []; + this.stages_reserved = []; + this.stages_work = []; + this.STAGE_STATUSES = { + 'not_agreed': this.buildStartStage.bind(self), + 'send_approve': this.buildSendApproveStage.bind(self), + 'agreed': this.buildAgreedStage.bind(self), + 'in_process': this.buildProcessStage.bind(self), + 'completed': this.buildProcessStage.bind(self), + 'closed': this.buildProcessStage.bind(self) + }; + this.btnCompleteTmpl = (0, _loaders.loadTemplate)('bntCompleteStage_tmpl'); + this.btnSendReviewTmpl = (0, _loaders.loadTemplate)('btnSendReview_tmpl'); + this.$orderStagesContainer = $('#order-stages'); + this.$orderStagesContainer.html(''); + this.buttons = { + btnApprove: $('#btnApprove'), // "Согласовать" + btnChange: $('#btnChange'), // "Отправить на внесение изменений" + btnsToArchive: $('.js-btnToArchive'), // "Отказаться от заказа" + btnsArbitration: $('.js-btnArbitration'), // "Обратиться в арбитраж" + btnSendReview: $('#order-review-add') // "Оставить отзыв" + }; + this.stages_elements = { + $approve: $('#conditions-approve'), //1. Согласование условия + $reserve: $('#reserveSpace'), //2. Резервирование (Отобразить) + $works: $('#completeWork') //3. Выполненная работа + }; + this.init(); + } + + _createClass(StagesController, [{ + key: 'init', + value: function init() { + var self = this; + + this.dataPromise = this.getOrderData({ orderId: this.orderId }); + this.dataPromise.then(self._onLoadData.bind(self)).catch(self._onLoadDataError.bind(self)); + } + }, { + key: 'getOrderData', + value: function getOrderData(_ref) { + var orderId = _ref.orderId; + + var self = this; + return Promise.resolve($.ajax({ + url: '/api/orders/' + orderId + '/', + dataType: 'json', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + } + })); + } + }, { + key: 'redraw', + value: function redraw() { + /** + * Полностью перерисовываем страницу Заказа + */ + console.log("Redraw contractor stages"); + // $("#orderBlock" + this.orderId).trigger('click'); + this.init(); + } + }, { + key: 'buildStartStage', + value: function buildStartStage() { + /** + * Стадия: "Проект Предложен"(нет этапов) + */ + // Выделить цифру 1. красным + // $('#conditions-approve').find('.select') + this.stages_elements.$approve.show(); + this.stages_elements.$reserve.show(); + this.stages_elements.$works.show(); + this.$orderStagesContainer.parent().hide(); + this.buttons.btnsToArchive.first().hide(); + this.$orderStagesContainer.show(); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.hide(); + this.buttons.btnsArbitration.hide(); + this.stages_elements.$approve.find('.js-help-text').show(); + this.stages_elements.$reserve.find('.stages-paid').html(""); + this.stages_elements.$works.find('.js-help-text').show(); + this.stages_elements.$works.find('#stagesWork').html(""); + if (this.secureOrder) { + this.stages_elements.$reserve.find('.js-help-text').show(); + } else { + this.stages_elements.$reserve.find('.js-help-text').hide(); + // this.stages_elements.$reserve.find('.js-help-text').html('Резервирование не предусмотрено, безопасная сделака не активна'); + } + } // Нет Этапов / "Не согласован" + + // buildNotAgreedStage() { + // console.log("Stage: not_agreed"); + // // this._renderStage('stage_tmpl'); + // this.buttons.btnApprove.hide(); + // this.buttons.btnChange.hide(); + // this.buttons.btnToArchive.hide(); + // this.buttons.btnArbitration.hide(); + // } // Статус "Не согласован" + + }, { + key: 'buildSendApproveStage', + value: function buildSendApproveStage() { + console.log("Stage: send_approve"); + this._renderStage('stage_approved_tmpl', true); + this.$orderStagesContainer.parent().show(); + this.buttons.btnApprove.show(); + this.buttons.btnChange.show(); + this.buttons.btnsToArchive.first().show(); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + } // Статус "На согласовании" + + }, { + key: 'buildAgreedStage', + value: function buildAgreedStage() { + console.log('Stage: agreed'); + this.$orderStagesContainer.parent().show(); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.hide(); + this.buttons.btnsToArchive.hide(); + this.buttons.btnsArbitration.first().hide(); + this.buttons.btnsArbitration.last().show(); + this._renderStage('stage_approved_tmpl', true); + this.stages_elements.$approve.find('.js-help-text').hide(); + this.stages_elements.$reserve.show(); + if (this.secureOrder) { + this._renderStageReserved('reserved_tmpl'); + this.stages_elements.$reserve.find('.js-help-text').show(); + } else { + this.stages_elements.$reserve.find('.stages-paid').html(""); + this.stages_elements.$reserve.find('.js-help-text').hide(); + } + } // Статус "Согласован" + + }, { + key: 'buildProcessStage', + value: function buildProcessStage() { + console.log('Stage: in_process'); + this.buildAgreedStage(); + this.stages_elements.$reserve.find('.js-help-text').hide(); + this.stages_elements.$works.show(); + if (this.secureOrder) { + this._renderStageInWork('work_in_process_tmpl'); + } else { + this.stages_elements.$reserve.find('.stages-paid').html(""); + } + } // Статус "В процессе"/"Завершен"/"Закрыт" + + }, { + key: '_buildPage', + value: function _buildPage() { + // console.log("Build PAge"); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + if (this.data.stages.length == 0) { + this.buildStartStage(); + } else { + var stageStatus = this.data.stages[0].status; + // console.log('stageStatus = ', stageStatus); + this.STAGE_STATUSES[stageStatus](); + } + this._bindEvents(); + } + }, { + key: '_renderStage', + value: function _renderStage(template_name) { + var disable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var i = 0; + // console.log("this.data.stages = ", this.data.stages); + this.$orderStagesContainer.html(""); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.data.stages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var stage_data = _step.value; + + i++; + // console.log('stage_data = ', stage_data); + var stage = new _Stages.StageForm(this.$orderStagesContainer, { + orderId: this.orderId, stage_num: i, stage_status: STATUSES[stage_data.status], + type: 'update', template_name: template_name, data: stage_data + }); + if (disable) stage.disable(); + this.stages.push(stage); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + } + }, { + key: '_renderStageReserved', + value: function _renderStageReserved(template_name) { + /** + * Отрисовываем блок "Резервирование" + */ + // console.log("_renderStageReserved"); + var $container = this.stages_elements.$reserve.find('.stages-paid'); + $container.html(""); + this.stages_reserved = []; + // console.log("this.data.stages = ", this.data.stages); + // Нет незарезервированных Этапов + // let has_not_reserved_stages = false; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.data.stages[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var stage_data = _step2.value; + + // if (stage_data.status == 'agreed') has_not_reserved_stages = true; + var stage = new _Stages.StageReserved($container, { + template_name: template_name, data: stage_data + }); + this.stages_reserved.push(stage); + } + // if (!has_not_reserved_stages) { + // this.buttons.btnReserve.hide(); + // this.stages_elements.$reserve.find('.js-help-text').hide(); + // } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + } + }, { + key: '_renderStageInWork', + value: function _renderStageInWork(template_name) { + /** + * Отрисовываем блок "Выволнение работы", включая "Выполненныа работа" и "Оставить отзыв" + */ + var $container = this.stages_elements.$works.find('#stagesWork'); + $container.html(""); + var all_closed = this.data.stages.every(function (el) { + return el.status == 'closed'; + }); + if (all_closed) { + this.stages_elements.$works.find('.titleStepss').html('3. Выполненная работа'); + this.stages_elements.$works.find('.js-btnArbitration').hide(); + this.stages_elements.$works.find('.js-help-text').hide(); + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.data.stages[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var stage_data = _step3.value; + + var stage = new _Stages.StageInWork($container, { + template_name: template_name, data: stage_data + }); + this.stages_work.push(stage); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + console.log("has_user_review = ", this.data.has_user_review); + if (!this.data.has_user_review) { + var btnReviewOpenModel = $(this.btnSendReviewTmpl()); + btnReviewOpenModel.unbind().on('click', this._onBtnReviewOpenModal.bind(this)); + // Если кнопка "Оставить отзыв" еще не добавлена - добавляем + if (!this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.append(btnReviewOpenModel); + } else { + if (this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.find('#send-review').remove(); + } + } else { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.data.stages[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _stage_data = _step4.value; + + if (_stage_data.status == 'closed' || _stage_data.status == 'agreed') continue; + var note_text = _stage_data.status == 'completed' ? '...НА УТВЕРЖДЕНИИ У ЗАКАЗЧИКА' : ''; + var _stage = new _Stages.StageInWork($container, { + template_name: template_name, data: _stage_data, note_text: note_text + }); + if (_stage_data.status == 'in_process') { + var $btn = $(this.btnCompleteTmpl({ stage: _stage_data, text: 'Завершить этап' })); + $container.html(); + $container.append($btn); + $btn.on('click', this._onBtnComplete.bind(this, _stage)); + } + this.stages_work.push(_stage); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + } + } + }, { + key: '_onLoadData', + value: function _onLoadData(json) { + this.data = json; + this._buildPage(); + } + }, { + key: '_bindEvents', + value: function _bindEvents() { + var self = this; + this.buttons.btnApprove.unbind().on("click", this._onBtnAccept.bind(self)); + this.buttons.btnChange.unbind().on("click", this._onBtnChange.bind(self)); + this.buttons.btnsToArchive.unbind().on("click", this._onBtnAToArchive.bind(self)); + this.buttons.btnsArbitration.unbind().on("click", this._onBtnArbitration.bind(self)); + this.buttons.btnSendReview.unbind().on("click", this._onBtnSendReview.bind(self)); + $("#reserve-stage-modal").find('#stage-num').unbind().on('change', function (event) { + // console.log("select stage cost = ", self.stages[this.value - 1].data.cost); + $("#reserve-stage-modal").find('#stage-cost').html(self.stages[this.value - 1].data.cost); + }); + } + + // BINDS + + }, { + key: '_onBtnAccept', + value: function _onBtnAccept(event) { + event.preventDefault(); + var self = this; + Promise.all(this.stages.map(function (el) { + return el.sendAjax_accept(self.secureOrder); + })).then(function () { + console.log('Этапы согласованы'); + self.redraw(); + + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0423\u0441\u043B\u043E\u0432\u0438\u044F \u0437\u0430\u043A\u0430\u0437\u0430 ' + self.orderName + ' \u043F\u0440\u0438\u043D\u044F\u0442\u044B'; + console.log("Send-WS Условия приняты"); + socket.send_stages_approve(message); + //TODO: раскомментировать дурацкое окно + // $('#popupOk').modal('show'); + // }) + }); + } // "Согласовать" + + }, { + key: '_onBtnChange', + value: function _onBtnChange(event) { + event.preventDefault(); + var self = this; + Promise.all(this.stages.map(function (el) { + return el.sendAjax_change(); + })).then(function () { + self.redraw(); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0417\u0430\u043A\u0430\u0437 ' + self.orderName + ' \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D \u0434\u043B\u044F \u0432\u043D\u0435\u0441\u0435\u043D\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439'; + console.log("Send-WS Внести изменения"); + socket.send_stages_approve(message); + }); + } // "Отправить на внесение изменений" + + // TODO: test it + + }, { + key: '_onBtnAToArchive', + value: function _onBtnAToArchive(event) { + event.preventDefault(); + console.error("Отказаться от заказа. Не протестировано!!"); + // TODO: Не только удалять заказ, но и делать его копию со статусом "Открыто" + $.ajax({ + // async: false, + url: '/api/orders/' + this.orderId + '/', + type: 'DELETE', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json' + }).done(function (json) { + console.log('delete complete'); + window.location.href = window.location.href.replace(getHash(), ""); + }).fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + }); + } // "Отказаться от заказа" + + }, { + key: '_onBtnComplete', + value: function _onBtnComplete(stage, event) { + event.preventDefault(); + var self = this; + // let stageId = $(event.target).data('stage-id'); + // console.log('Complete stage id = ', stage.data.id); + stage.sendAjax_complete().then(function (json) { + self.redraw(); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u042D\u0442\u0430\u043F ' + json.name + ' \u0437\u0430\u043A\u0440\u044B\u0442'; + console.log("Send-WS Закрытие этапа"); + socket.send_stages_approve(message); + }).catch(function (xhr) { + console.log("При закрытии этапа произошла ошибка -->", xhr); + }); + } // "Закрыть этап" + + }, { + key: '_onBtnReviewOpenModal', + value: function _onBtnReviewOpenModal(event) { + event.preventDefault(); + $('#review-add').modal('show'); + } // Открыть модальное окно "Оставить отзыв" + + }, { + key: '_onBtnSendReview', + value: function _onBtnSendReview(event) { + event.preventDefault(); + var self = this; + $('#projectReviewId').val(this.projectId); + $('#targetCustomerId').val(this.recipentId); + // $('#fromContractorId').val('....current user'); + var formData = $("#review-adds-form").serialize(); + // console.log('Оставить отзыв formdata -->', formData); + $.ajax({ + url: '/api/reviews/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: formData, + dataType: 'json', + success: function success(json) { + console.log('Отзыв успешно отправлен, json -->', json); + // $('#review-add').modal('hide'); + // self.stages_elements.$works.find('.js-btnSendReview').hide(); + $('#review-add').modal('hide'); + self.redraw(); + + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u041E\u0442\u0437\u044B\u0432 \u043D\u0430 \u0437\u0430\u043A\u0430\u0437 ' + self.orderName + ' \u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D'; + console.log("Send-WS Оставить отзыв"); + socket.send_stages_approve(message); + // $("a[href='#tab2']").trigger('click'); + window.location = '/chat/#order'; + location.reload(); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + } // "Оставить отзыв" + + + }, { + key: '_onBtnArbitration', + value: function _onBtnArbitration(event) { + event.preventDefault(); + $("#arbitration-add").modal('show'); + } // "Обратиться в арбитраж" + + }, { + key: '_onLoadDataError', + value: function _onLoadDataError(error) { + console.log("Error loading data -->", error); + } + }]); + + return StagesController; + }(); + + exports.StagesController = StagesController; + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + if (cookie.substring(0, name.length + 1) == name + '=') { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + function humanFileSize(bytes, si) { + var thresh = si ? 1000 : 1024; + + if (Math.abs(bytes) < thresh) return bytes + ' B'; + + var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + + var u = -1; + + do { + bytes /= thresh; + ++u; + } while (Math.abs(bytes) >= thresh && u < units.length - 1); + + return bytes.toFixed(1) + ' ' + units[u]; + } + + exports.humanFileSize = humanFileSize; + exports.getCookie = getCookie; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.loadTemplate = undefined; + + var _stage_tmpl = __webpack_require__(5); + + var _stage_tmpl2 = _interopRequireDefault(_stage_tmpl); + + var _stage_approved_tmpl = __webpack_require__(6); + + var _stage_approved_tmpl2 = _interopRequireDefault(_stage_approved_tmpl); + + var _reserved_tmpl = __webpack_require__(7); + + var _reserved_tmpl2 = _interopRequireDefault(_reserved_tmpl); + + var _message_tmpl = __webpack_require__(8); + + var _message_tmpl2 = _interopRequireDefault(_message_tmpl); + + var _work_in_process_tmpl = __webpack_require__(9); + + var _work_in_process_tmpl2 = _interopRequireDefault(_work_in_process_tmpl); + + var _bntCompleteStage_tmpl = __webpack_require__(10); + + var _bntCompleteStage_tmpl2 = _interopRequireDefault(_bntCompleteStage_tmpl); + + var _btnSendReview_tmpl = __webpack_require__(11); + + var _btnSendReview_tmpl2 = _interopRequireDefault(_btnSendReview_tmpl); + + var _document_attach_file_tmpl = __webpack_require__(12); + + var _document_attach_file_tmpl2 = _interopRequireDefault(_document_attach_file_tmpl); + + var _note_tmpl = __webpack_require__(13); + + var _note_tmpl2 = _interopRequireDefault(_note_tmpl); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function loadTemplate(template_name) { + var templates = { + stage_tmpl: _stage_tmpl2.default, + stage_approved_tmpl: _stage_approved_tmpl2.default, + reserved_tmpl: _reserved_tmpl2.default, + message_tmpl: _message_tmpl2.default, + work_in_process_tmpl: _work_in_process_tmpl2.default, + bntCompleteStage_tmpl: _bntCompleteStage_tmpl2.default, + btnSendReview_tmpl: _btnSendReview_tmpl2.default, + document_attach_file_tmpl: _document_attach_file_tmpl2.default, + note_tmpl: _note_tmpl2.default + }; + + if (!templates[template_name]) throw new Error('Template ' + template_name + ' does not exist'); + return templates[template_name]; + } + + exports.loadTemplate = loadTemplate; + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return '\n

\n

\u042D\u0422\u0410\u041F ' + this.stage_num + '

\n
\n \n \n

\n \n \n

\n \n

\n \n \n \n \n

\n \n \n

\n
\n
'; + }; + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
\n
\n
\n \u042D\u0422\u0410\u041F " + this.stage_num + "\n
\n
\n " + this.stage_status + "\n
\n
\n
\n\n
\n " + this.stage.name + "\n
\n \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u044D\u0442\u0430\u043F\u0430\n
\n " + this.stage.result + "\n
\n \u0426\u0435\u043D\u0430\n
\n " + this.stage.cost + " \u20BD\n
\n \u0421\u0440\u043E\u043A\n
\n \u0434\u043E " + this.stage.term + "\n
\n\n
"; + }; + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n\n
  • \u0421\u0443\u043C\u043C\u0430 \u0437\u0430 \u044D\u0442\u0430\u043F " + this.stage.pos + "\n
    " + this.reserved_name + "
    \n
  • "; + }; + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
    \n
    \n

    " + this.senderName + "

    " + this.message.created + "\n
    \n

    " + this.message.text + "

    \n
    "; + }; + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
    \n \u0412 \u0440\u0430\u0431\u043E\u0442\u0435: " + this.stage.name + "
    \n \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u044D\u0442\u0430\u043F\u0430: " + this.stage.result + "
    \n \u0421\u0440\u043E\u043A \u0441\u0434\u0430\u0447\u0438: " + this.stage.term + "
    \n " + this.stage.cost + " \u0440\n
    \n " + this.note_text + "\n
    \n
    "; + }; + +/***/ }, +/* 10 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
    "; + }; + +/***/ }, +/* 11 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return ""; + }; + +/***/ }, +/* 12 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
  • \n " + this.text + "\n
    \n
  • \n\n"; + }; + +/***/ }, +/* 13 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "
    \n
  • \n " + this.text + "\n
  • \n
    \n
    \n"; + }; + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.StageInWork = exports.StageReserved = exports.StageForm = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _loaders = __webpack_require__(4); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + // new-stages-form + // update-stages-form + // remove-stages-form + + var StageForm = function () { + function StageForm($container, _ref) + // kwargs - auto generate from name_attributes + { + var orderId = _ref.orderId, + stage_num = _ref.stage_num, + stage_status = _ref.stage_status, + _ref$type = _ref.type, + type = _ref$type === undefined ? 'new' : _ref$type, + _ref$formNamePostfix = _ref.formNamePostfix, + formNamePostfix = _ref$formNamePostfix === undefined ? '-stages-form' : _ref$formNamePostfix, + template_name = _ref.template_name, + _ref$data = _ref.data, + data = _ref$data === undefined ? {} : _ref$data; + var kwargs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { + stage_num: stage_num, + stage_status: stage_status, + form_name: type + formNamePostfix, + orderId: orderId, + stage: data + }; + + _classCallCheck(this, StageForm); + + // console.log('Stage form template_name = ', template_name); + this.orderId = orderId; + this._type = type; + this.$container = $container; + this.self_tmpl = (0, _loaders.loadTemplate)(template_name); + this.data = data; + this.$form = undefined; + this.stageId = type != 'new' ? data.id : undefined; + this.create(kwargs); + } + + _createClass(StageForm, [{ + key: 'create', + value: function create(kwargs) { + /** + * Добавление шаблона-формы Этапа на страницу + */ + var el = $(this.self_tmpl(kwargs)); + this.$container.append(el); + this.$form = el.find('form'); + // console.log("form --> ", this.$form); + if (this.$form.length) this.$form.find('input[name=cost]').mask('000000000'); + } + }, { + key: 'remove', + value: function remove() { + /** + * Удаление, при уменьшении кол-ва этапов + * return true - удаляем из [] stages + */ + if (this.type == 'new') { + this.$form.parent().remove(); + return true; + } + this.type = 'remove'; + // this.$form.removeClass('update-stages-form').addClass('remove-stages-form'); + return false; + } + }, { + key: 'restore', + value: function restore() { + /** + * Восстановление, при увеличении кол-ва этапов + */ + if (this.type == 'new') throw new Error("Попытка восстановить элемент с type='new'"); + this.type = 'update'; + // this.$form.removeClass('remove-stages-form').addClass('update-stages-form'); + } + }, { + key: 'disable', + value: function disable() { + this.$form.find('input').attr('readonly', true); + } + }, { + key: 'enable', + value: function enable() { + this.$form.find('input').attr('readonly', false); + } + }, { + key: 'hide', + value: function hide() { + this.$form.parent().hide(); + } + }, { + key: 'show', + value: function show() { + this.$form.parent().show(); + } + }, { + key: 'is_valid', + value: function is_valid() { + var self = this; + var mesage = 'Это поле обязательно'; + var valid = true; + //Очищаем старые ошибки + this.$form.find('.error').html(""); + // Отображаем новые + this.$form.find(":input:not([type=hidden])").each(function (i, v) { + if (!$(v).val()) { + self.$form.find('.error-' + $(v).attr("name")).html(mesage).css('color', 'red'); + valid = false; + } + }); + return valid; + } + }, { + key: 'sendAjax_approve', + value: function sendAjax_approve() { + /** + * Отправка Этапа "на согласование" + */ + var self = this; + // console.log("Send AJAX Approve"); + if (this.type == 'new') { + // console.log('new stages approve'); + return Promise.resolve($.ajax({ + // async: false, + url: '/api/stages/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: this.$form.serialize(), + dataType: 'json' + }).done(function (json) { + self.type = 'update'; + self.disable(); + self.$form.find('.error').html(""); + // console.log("json -->", json); + self.stageId = json.id; + // console.log(json); + }).fail(function (xhr, errorMsg, error) { + console.log("ERROR, xhr", xhr); + $.each(xhr.responseJSON, function (i, v) { + self.$form.find('.error-' + i).html(v).css('color', 'red'); + // console.log(self.$form); + // console.log(v); + // console.log(i); + }); + })); + } else if (this.type == 'update') { + this.$form.find('input[name=status]').val('send_approve'); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PUT', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: this.$form.serialize(), + dataType: 'json' + }).done(function (json) { + self.$form.find('.error').html(""); + self.disable(); + }).fail(function (xhr, errorMsg, error) { + $.each(xhr.responseJSON, function (i, v) { + self.$form.find('.error-' + i).html(v).css('color', 'red'); + console.log(v); + console.log(i); + }); + })); + } else if (this.type == 'remove') { + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'DELETE', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + dataType: 'json' + }).done(function (json) {}).fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + })); + } + } + }, { + key: 'sendAjax_accept', + value: function sendAjax_accept(secureOrder) { + /** + * "Согласовать" Этапы (Исполнителем) + */ + console.log("secureOrder = ", secureOrder); + console.log("set new status =", secureOrder ? 'agreed' : 'in_process'); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + //TODO: слать только изменения + data: { + status: secureOrder ? 'agreed' : 'in_process' + }, + dataType: 'json' + })); + } + }, { + key: 'sendAjax_change', + value: function sendAjax_change() { + /** + * Отправка Этапа "Внести изменения" + */ + var self = this; + // this.$form.find('input[name=status]').val('not_agreed'); + // console.log("ajax Change form -->", this.$form); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + //TODO: слать только изменения + data: { status: 'not_agreed' }, + dataType: 'json' + }).done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + self.enable(); + }).fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + }, { + key: 'type', + set: function set(newType) { + this.$form.removeClass(this._type + '-stages-form').addClass(newType + '-stages-form'); + if (newType == 'remove') this.hide(); + if (newType == 'update') this.show(); + this._type = newType; + }, + get: function get() { + return this._type; + } + }]); + + return StageForm; + }(); + + var StageReserved = function () { + function StageReserved($container, _ref2) { + var _ref2$template_name = _ref2.template_name, + template_name = _ref2$template_name === undefined ? 'reserved_tmpl' : _ref2$template_name, + data = _ref2.data; + var kwargs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { + reserved_cls: '', + reserved_name: '', + stage: data + }; + + _classCallCheck(this, StageReserved); + + // Вывод текста резервирования в зависимости от статуса этапа + var reserved_names = { + agreed: 'Не зарезервирована', + in_process: 'Зарезервирована', + completed: 'Зарезервирована', + closed: 'Переведена исполнителю' + }; + // Вывод текста резервирования в зависимости от статуса этапа + var reserved_classes = { + agreed: 'unreserved', + in_process: 'reserved', + completed: 'reserved', + closed: 'closed' + }; + kwargs.reserved_cls = reserved_classes[data.status]; + kwargs.reserved_name = reserved_names[data.status]; + this.data = data; + this.self_tmpl = (0, _loaders.loadTemplate)(template_name); + this.$container = $container; + this.create(kwargs); + } + + _createClass(StageReserved, [{ + key: 'create', + value: function create(kwargs) { + /** + * Добавление шаблона "Резервирование" Этапа на страницу + */ + this.$self = $(this.self_tmpl(kwargs)); + this.$container.append(this.$self); + // console.log("form --> ", this.$form); + // this.$form.find('input[name=cost]').mask('000000000'); + } + }]); + + return StageReserved; + }(); + + var StageInWork = function () { + function StageInWork($container, _ref3) { + var _ref3$template_name = _ref3.template_name, + template_name = _ref3$template_name === undefined ? 'work_in_process_tmpl' : _ref3$template_name, + _ref3$note_text = _ref3.note_text, + note_text = _ref3$note_text === undefined ? '' : _ref3$note_text, + data = _ref3.data; + var kwargs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { stage: data, note_text: note_text }; + + _classCallCheck(this, StageInWork); + + this.stageId = data.id; + this.data = data; + this.self_tmpl = (0, _loaders.loadTemplate)(template_name); + this.$container = $container; + this.create(kwargs); + } + + _createClass(StageInWork, [{ + key: 'create', + value: function create(kwargs) { + /** + * Добавление шаблона "Выполнение работы" Этапа на страницу + */ + this.$self = $(this.self_tmpl(kwargs)); + this.$container.append(this.$self); + } + }, { + key: 'hide', + value: function hide() { + this.$self.hide(); + } + }, { + key: 'sendAjax_complete', + value: function sendAjax_complete() { + /** + * Отправка Этапа "Закрыть этап" + */ + var self = this; + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: { status: 'completed' }, + dataType: 'json' + }).done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + // self.enable(); + }).fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + }, { + key: 'sendAjax_close', + value: function sendAjax_close() { + /** + * Отправка Этапа "Закрыть этап" + */ + var self = this; + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + //TODO: слать только изменения + data: { status: 'closed' }, + dataType: 'json' + }).done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + // self.enable(); + }).fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + }]); + + return StageInWork; + }(); + + exports.StageForm = StageForm; + exports.StageReserved = StageReserved; + exports.StageInWork = StageInWork; + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.MessagesController = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _utils = __webpack_require__(3); + + var _loaders = __webpack_require__(4); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var MessagesController = function () { + function MessagesController(orderId) { + _classCallCheck(this, MessagesController); + + console.log('Create MessagesController'); + var self = this; + this.orderId = orderId; + this.$inbox = $('#message-chat-order-space'); + this.$inbox.html(""); + this.messageTemplate = (0, _loaders.loadTemplate)('message_tmpl'); + this.dataPromise = this.getMessagesData(); + this.dataPromise.then(self._onLoadData.bind(self)); + } + + _createClass(MessagesController, [{ + key: 'getMessagesData', + value: function getMessagesData() { + var self = this; + return Promise.resolve($.ajax({ + url: '/api/message', + type: 'GET', + data: { 'order': self.orderId, 'team__isnull': 'true' }, + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + success: function success(json) { + console.log('Success Messages'); + } + })); + } + }, { + key: '_onLoadData', + value: function _onLoadData(json) { + var self = this; + // console.log('mesages json = ', json); + // console.log('$inbox = ', this.$inbox); + // console.log("messages render start"); + self.$inbox.html(""); + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + if (v.is_system) { + senderName = 'Системное'; + className = 'systemChat'; + } + var message = $(self.messageTemplate({ className: className, senderName: senderName, message: v })); + self.$inbox.append(message); + }); + // console.log("messages render complete"); + self.$inbox.scrollTop(self.$inbox.prop("scrollHeight")); + } + }]); + + return MessagesController; + }(); + + exports.MessagesController = MessagesController; + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.DocumentsController = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _utils = __webpack_require__(3); + + var _loaders = __webpack_require__(4); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var DocumentsController = function () { + function DocumentsController(orderId) { + _classCallCheck(this, DocumentsController); + + console.log('Create MessagesController'); + var self = this; + this.orderId = orderId; + this.$container = $('#documentOrderSpace'); + this.$container.html(""); + + this.messageTemplate = (0, _loaders.loadTemplate)('document_attach_file_tmpl'); + this.dataPromise = this.getMessagesData(); + this.dataPromise.then(self._onLoadData.bind(self)); + } + + _createClass(DocumentsController, [{ + key: 'getMessagesData', + value: function getMessagesData() { + var self = this; + return Promise.resolve($.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'order': self.orderId, + 'is_delete': false, + 'is_send': true + }, + dataType: 'json', + // success: function (json) { + // + // }, + error: function error(e) { + console.log(e); + } + })); + } + }, { + key: 'addDocument', + value: function addDocument(json) {} + }, { + key: '_onLoadData', + value: function _onLoadData(json) { + var self = this; + // console.log('mesages json = ', json); + // console.log('$inbox = ', this.$inbox); + // console.log("messages render start"); + this.$container.html(""); + $.each(json.results, function (i, v) { + var document = $(self.messageTemplate({ + href: '/chat/download/\' + ' + v.file, + text: v.file, + document_id: v.id + })); + self.$container.append(document); + }); + // console.log("messages render complete"); + // self.$inbox.scrollTop(self.$inbox.prop("scrollHeight")); + } + }]); + + return DocumentsController; + }(); + + exports.DocumentsController = DocumentsController; + +/***/ }, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.bindDeleteContact = exports.bindTeams = exports.bindGetUserMessages = exports.bindUserContacts = exports.bindOnTabs = exports.bindArbitrationSend = exports.bindOrders = undefined; + + var _utils = __webpack_require__(3); + + var _messageCounters = __webpack_require__(18); + + var _loaders = __webpack_require__(4); + + function dialog(message, yesCallback, notCallback) { + $("#dialog_delete .modal-title").html(message); + $("#dialog_delete").modal('show'); + $("#btnYes").click(function (e) { + e.preventDefault(); + yesCallback(); + $("#dialog_delete").modal('hide'); + }); + $("#btnNot").click(function (e) { + e.preventDefault(); + notCallback(); + $("#dialog_delete").modal('hide'); + }); + } + + function bindOrders() { + $('.order-block').on('click', function (event) { + event.preventDefault(); + var $this = $(this); + (0, _messageCounters.onClickCardWithCount)($this); + $('.order-block').each(function (i, v) { + $(v).removeClass('orAct'); + }); + $this.addClass('orAct'); + var orderId = $this.data('id'); + var projectId = $this.data('project-id'); + var recipentId = $this.data('recipent-id'); + var orderName = $this.data('order-name'); + var secureOrder = $(this).data('secure-deal'); + secureOrder = Boolean(secureOrder); + window.location.hash = 'order' + orderId; + + $("#chat-order-add #orderId").val(orderId); + $("#add-form-order-note #orderNote").val(orderId); + $("#orderArbitrationId").val(orderId); + $("#projectReviewId").val(projectId); + $("#reserve-button").attr('data-order-id', orderId); + + $("#chat-order-add #recipentId").val(recipentId); + window.chatController.create(orderId, projectId, recipentId, orderName, secureOrder); + }); + $('.order-block .dimovChat').on('click', function (event) { + event.preventDefault(); + event.stopPropagation(); + // console.log('click on tr'); + }); + } + + function bindTeams() { + $('.team-block').on('click', function () { + (0, _messageCounters.onClickCardWithCount)($(this)); + $('.team-order-block, .team-block').each(function () { + $(this).removeClass('orAct'); + }); + $(this).addClass('orAct'); + + var teamIds = ''; + $.each($(this).find('.team-chat-user'), function (i, v) { + teamIds += $(this).attr('data-id') + ";"; + }); + $("#team-chat-form #teamIds").val(teamIds); + + var inbox = document.getElementById('message-chat-team-space'); + inbox.innerHTML = ''; + + var docList = document.getElementById('documentTeamSpace'); + docList.innerHTML = ''; + + var teamId = $(this).attr('data-team-id'); + location.hash = '#myteam' + teamId; + + // var newCount = parseInt($("#count-tab-team").text()); + // var currNewCount = parseInt($(".team-count-" + teamId).text()); + // var resCount = newCount - currNewCount; + // $("#count-tab-team").text(resCount); + $(".team-count-" + teamId).text(0); + + $("#team-chat-form #teamId").val(teamId); + $("#add-form-team-note #teamNote").val(teamId); + $("#team-chat-form #recipentTeamId").val(""); + $("#team-chat-form #orderTeamId").val(""); + $("#add-form-team-note #orderNote").val(""); + + $.ajax({ + url: '/api/message', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { 'team': teamId, 'order__isnull': 'true' }, + dataType: 'json', + success: function success(json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
    ' + '

    ' + senderName + '

    ' + v.created + '
    ' + '

    ' + v.text + '

    '; + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'team': teamId, + 'is_delete': false, + 'is_send': true + }, + dataType: 'json', + success: function success(json) { + $.each(json.results, function (i, v) { + docList.innerHTML += '
  • ' + v.file + '
  • '; + }); + }, + error: function error(e) { + console.log(e); + } + }); + + $.ajax({ + url: '/api/note/', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { 'team': teamId }, + dataType: 'json', + success: function success(json) { + console.log(json.results); + var noteHtmlInbox = ''; + var note_tmpl = (0, _loaders.loadTemplate)('note_tmpl'); + $.each(json.results, function (i, v) { + noteHtmlInbox += note_tmpl({ text: v.text }); + }); + $(".team-notes-block").html(noteHtmlInbox); + } + }); + }); + } + + function bindArbitrationSend() { + // TODO: Test it + $('#order-arbitration-add').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + var formData = $("#arbitration-add-form").serialize(); + $.ajax({ + url: '/projects/arbitration/create/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: formData, + dataType: 'json', + success: function success(json) { + console.log(json); + $("#arbitration-add").modal('hide'); + $.jGrowl("Обращение в арбитраж добавлено", { + life: 4000 + }); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }); + } + + function bindOnTabs() { + /** + * Биндит обработчики на Закладки + */ + $('a[data-toggle="tab"]').unbind().on('show.bs.tab', function (e) { + console.log("TAB!"); + var activeTab = $(this).attr('href').substring(1); + var liveHash = URI(location.href).hash(); + + switch (activeTab) { + case 'tab1': + setTimeout(function () { + if (liveHash.indexOf("#user") != -1) { + var userHashId = liveHash.replace("#user", ""); + $("#userBlock" + userHashId).trigger('click'); + } else { + $(".user-block").first().trigger('click'); + } + }, 100); + break; + + case 'tab2': + // console.log("tab2"); + setTimeout(function () { + if (liveHash.indexOf("#order") != -1) { + var ordHashId = liveHash.replace("#order", ""); + $("#orderBlock" + ordHashId).trigger('click'); + } else { + $(".order-block").first().trigger('click'); + } + }, 100); + break; + + case 'tab3': + setTimeout(function () { + console.log("on active TAB team"); + if (liveHash.indexOf("#teamorder") != -1) { + var teamHashId = liveHash.replace("#teamorder", ""); + $("#teamOrderBlock" + teamHashId).trigger('click'); + } else if (liveHash.indexOf("#myteam") != -1) { + var teamHashId = liveHash.replace("#myteam", ""); + $("#teamMyBlock" + teamHashId).trigger('click'); + } else { + var firstTeamBlock = $(".team-block").first(); + var firstTeamOrder = $(".team-order-block").first(); + if (firstTeamOrder.length == 1) { + firstTeamOrder.trigger('click'); + } else if (firstTeamBlock.length == 1) { + firstTeamBlock.trigger('click'); + } + } + }, 100); + + } + }); + } + + function bindUserContacts() { + $(".conMess").click('on', function (e) { + e.preventDefault(); + e.stopPropagation(); + + var userId = $(this).attr('data-id'); + $.ajax({ + url: '/api/users/' + userId + '/', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + success: function success(data) { + var outTable = ''; + if (data.username) { + outTable += 'Ник' + data.username + ''; + } + + if (data.fio) { + outTable += 'Ф.И.О' + data.fio + ''; + } + if (data.skype) { + outTable += 'Skype' + data.skype + ''; + } + + if (data.website) { + outTable += 'Сайт' + data.website + ''; + } + + if (data.phone) { + outTable += 'Телефон' + data.phone + ''; + } + + $("#contact-info table").html(outTable); + $("#contact-info").modal('show'); + // console.log(data); + }, + error: function error(e, jqxhr) { + console.log(e); + } + }); + }); + } + + function bindGetUserMessages() { + $('.user-block').on('click', function () { + (0, _messageCounters.onClickCardWithCount)($(this)); + // var newCount = parseInt($("#count-tab-contact").text()); + var contactId = $(this).attr('data-id'); + location.hash = '#user' + contactId; + $("#contact-chat-form #recipentContactId").val(contactId); + $("#add-form-contractor-note #recipentNoteContractor").val(contactId); + + $('.user-block').each(function () { + $(this).removeClass('mesAct'); + }); + + $(this).addClass('mesAct'); + var inbox = document.getElementById('message-chat-space'); + var sumSenderRecipent = parseInt(userId) + parseInt(contactId); + + $("#message-chat-space").removeClass().addClass("contact-space" + sumSenderRecipent); + // var currNewCount = parseInt($(".contact-count-" + sumSenderRecipent).text()); + // var resCount = newCount - currNewCount; + // $("#count-tab-contact").text(resCount); + $(".contact-count-" + sumSenderRecipent).text(0); + var docList = document.getElementById('documentSpace'); + inbox.innerHTML = ''; + docList.innerHTML = ''; + + $.ajax({ + url: '/api/message', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId + }, + dataType: 'json', + success: function success(json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id == contactId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
    ' + '

    ' + senderName + '

    ' + v.created + '
    ' + '

    ' + v.text + '

    '; + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId, + 'is_delete': false, + 'is_send': true + }, + dataType: 'json', + + success: function success(json) { + console.log(json); + + $.each(json.results, function (i, v) { + docList.innerHTML += '
  • ' + v.file + '
  • '; + }); + }, + error: function error(e) { + console.log(e); + } + }); + + $.ajax({ + url: '/api/note/', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId + }, + dataType: 'json', + success: function success(json) { + console.log(json.results); + var noteHtmlInbox = ''; + var note_tmpl = (0, _loaders.loadTemplate)('note_tmpl'); + $.each(json.results, function (i, v) { + noteHtmlInbox += note_tmpl({ text: v.text }); + }); + $(".contractor-notes-block").html(noteHtmlInbox); + } + }); + }); + } + + function bindDeleteContact() { + $('.deleteMess').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + + var senderId = userId; + var recipentId = $(this).attr('data-recipent-id'); + var _this = $(this); + + dialog("Вы действительно хотите удалить сообщения этого пользователя?", function () { + $.ajax({ + url: '/chat/messages_delete/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { 'sender_id': senderId, 'recipent_id': recipentId }, + dataType: 'json', + success: function success(json) { + + if (json.status == 'ok') { + _this.parent().remove(); + $("#message-chat-space").html(""); + } + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }.bind(null, senderId, recipentId, _this), function () {}); + }); + } + + exports.bindOrders = bindOrders; + exports.bindArbitrationSend = bindArbitrationSend; + exports.bindOnTabs = bindOnTabs; + exports.bindUserContacts = bindUserContacts; + exports.bindGetUserMessages = bindGetUserMessages; + exports.bindTeams = bindTeams; + exports.bindDeleteContact = bindDeleteContact; + +/***/ }, +/* 18 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function recalculateTabsCounter() { + // let tabs = [$('#count-tab-contact'), $('#count-tab-order'), $('#count-tab-team')] + var tabs = [$('#tab1'), $('#tab2'), $('#tab3')]; + var total_messages_count = 0; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = tabs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var tab = _step.value; + + var count_sum = Array.from(tab.find('.js-count').map(function (i, el) { + return parseInt($(el).html()); + })).reduce(function (a, b) { + return a + b; + }, 0); + var $tab_counter = $('a[href="#' + tab.attr('id') + '"]').find('.count-tab'); + $tab_counter.html(count_sum); + total_messages_count += count_sum; + // console.log($tab_counter, 'new value -->', count_sum); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var $header_counter = $('.js-all-messages'); + $header_counter.html(total_messages_count); + } + + function countPlus(message, place) { + /** + * Увеличиваем счетчик соответствующий сообщению(message) + */ + // console.log("MESSAGE = ", message); + var $container = void 0; + if (message.answer_type == "add_message_contact") { + $container = $('.contact-count-' + message.sender_id); + } else if (message.answer_type == "add_message_order") { + $container = $('#count-order-' + message.order_id); + } else if (message.answer_type == "add_message_team") { + $container = $('#count-team-' + message.team_id); + } + // console.log("container = ", $container); + $container.html(parseInt($container.html()) + 1); + recalculateTabsCounter(); + } + + function onClickCardWithCount($card) { + /** + * При нажатии на карточку со счетчиком новых сообщений + */ + // console.log('Обнулем счетчик ', $card); + $card.find('.js-count').html(0); + recalculateTabsCounter(); + } + + exports.countPlus = countPlus; + exports.onClickCardWithCount = onClickCardWithCount; + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.bindRemoveDocuments = exports.uploadDocumentsTeamInit = exports.uploadDocumentsOrderInit = exports.uploadDocumentsContactInit = undefined; + + var _utils = __webpack_require__(3); + + function uploadDocumentsContactInit() { + $("#upload-document-contact").bind('fileuploadsubmit', function (e, data) { + data.formData = { + sender: $("#contact-chat-form #senderContactId").val(), + recipent: $("#contact-chat-form #recipentContactId").val() + }; + }); + + $('#upload-document-contact').fileupload({ + url: '/chat/create/', + crossDomain: false, + beforeSend: function beforeSend(xhr, settings) { + console.log("Upload form data -->", this.formData); + $('#progress .progress-bar').css('width', '0%'); + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + done: function done(e, data) { + $.each(data.result.files, function (index, file) { + var htmlImg = ''; + var document_send = $(htmlImg).appendTo("#document-send-contact"); + }); + }, + fail: function fail(e) { + console.log(e); + }, + progressall: function progressall(e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .progress-bar').css('width', progress + '%'); + } + }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled'); + } + + function uploadDocumentsOrderInit() { + $("#upload-document-order").bind('fileuploadsubmit', function (e, data) { + data.formData = { + sender: $("#chat-order-add #senderId").val(), + recipent: $("#chat-order-add #recipentId").val(), + order: $("#chat-order-add #orderId").val() + }; + console.log(data.formData); + }); + + $('#upload-document-order').fileupload({ + url: '/chat/create/', + crossDomain: false, + beforeSend: function beforeSend(xhr, settings) { + $('#progress .progress-bar').css('width', '0%'); + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + done: function done(e, data) { + $.each(data.result.files, function (index, file) { + var htmlImg = ''; + var document_send = $(htmlImg).appendTo("#document-send-order"); + }); + }, + fail: function fail(e) { + console.log(e); + }, + progressall: function progressall(e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .progress-bar').css('width', progress + '%'); + } + }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled'); + } + + function uploadDocumentsTeamInit() { + $("#upload-document-team").bind('fileuploadsubmit', function (e, data) { + data.formData = { + sender: $("#team-chat-form #senderTeamId").val(), + recipent: $("#team-chat-form #recipentTeamId").val(), + order: $("#team-chat-form #orderTeamId").val(), + team: $("#team-chat-form #teamId").val() + }; + console.log(data.formData); + }); + + $('#upload-document-team').fileupload({ + url: '/chat/create/', + crossDomain: false, + beforeSend: function beforeSend(xhr, settings) { + $('#progress .progress-bar').css('width', '0%'); + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + done: function done(e, data) { + $.each(data.result.files, function (index, file) { + var currentValue = $("#documentSendIds").val(); + currentValue += file.id + ';'; + $("#documentSendIds").val(currentValue); + var htmlImg = ''; + var document_send = $(htmlImg).appendTo("#document-send"); + }); + }, + fail: function fail(e) { + console.log(e); + }, + progressall: function progressall(e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .progress-bar').css('width', progress + '%'); + } + }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled'); + } + + function bindRemoveDocuments() { + $('.tab-content').on('click', '.remove-document', function (e) { + e.preventDefault(); + var dataId = $(this).attr('data-id'); + var _this = $(this); + $.ajax({ + url: '/api/documents/' + dataId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { is_delete: true }, + dataType: 'json', + success: function success(json) { + _this.parent().remove(); + console.log(json); + }, + error: function error(e, jqxhr) { + console.log(jqxhr); + } + }); + }); + } + + exports.uploadDocumentsContactInit = uploadDocumentsContactInit; + exports.uploadDocumentsOrderInit = uploadDocumentsOrderInit; + exports.uploadDocumentsTeamInit = uploadDocumentsTeamInit; + exports.bindRemoveDocuments = bindRemoveDocuments; + +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.bindTeamNotes = exports.bindOrderNotes = exports.bindContractorNotes = undefined; + + var _loaders = __webpack_require__(4); + + var note_tmpl = (0, _loaders.loadTemplate)('note_tmpl'); + + function bindContractorNotes() { + $('#add-note-contractor').on('click', function (e) { + e.preventDefault(); + $.ajax({ + url: '/api/note/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: $("#add-form-contractor-note").serialize(), + dataType: 'json', + success: function success(json) { + console.log(json); + $("#add-form-contractor-note #chat2").val(""); + var li = note_tmpl({ text: json.text }); + $(li).appendTo(".contractor-notes-block"); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }); + } + + function bindOrderNotes() { + $('#add-note-button').on('click', function (e) { + e.preventDefault(); + $.ajax({ + url: '/api/note/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: $("#add-form-order-note").serialize(), + dataType: 'json', + success: function success(json) { + // $("
  • " + json.text + "
  • ").appendTo(".order-notes-block"); + var li = note_tmpl({ text: json.text }); + $(li).appendTo(".order-notes-block"); + $("#add-form-order-note #chat2").val(""); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }); + } + + function bindTeamNotes() { + $('#add-team-note-button').on('click', function (e) { + e.preventDefault(); + $.ajax({ + url: '/api/note/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: $("#add-form-team-note").serialize(), + dataType: 'json', + success: function success(json) { + $("
  • " + json.text + "
  • ").appendTo(".team-notes-block"); + $("#add-form-team-note #chat2").val(""); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }); + } + + exports.bindContractorNotes = bindContractorNotes; + exports.bindOrderNotes = bindOrderNotes; + exports.bindTeamNotes = bindTeamNotes; + +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.restoreTabFromHash = undefined; + + var _utils = __webpack_require__(3); + + function restoreTabFromHash() { + var currentHash = URI(location.href).hash(); + if (currentHash.indexOf("#order") == 0) { + $("a[href='#tab2']").trigger('click'); + // console.log("click on ", "#orderBlock" + currentHash.replace("#order", "")); + var obj_id = currentHash.replace("#order", ""); + console.log("obj_id = ", obj_id); + if (obj_id) { + $("#orderBlock" + currentHash.replace("#order", "")).trigger('click'); + } else { + $('.order-block').first().trigger('click'); + } + } else if (currentHash.indexOf("#user") == 0) { + $("a[href='#tab1']").trigger('click'); + } else if (currentHash.indexOf("#teamorder") == 0 || currentHash.indexOf("#myteam") == 0) { + $("a[href='#tab3']").trigger('click'); + } else { + $("a[href='#tab1']").trigger('click'); + } + } + + exports.restoreTabFromHash = restoreTabFromHash; + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.bindArchiveProjects = undefined; + + var _utils = __webpack_require__(3); + + function bindArchiveProjects() { + // Нажимаем на кнопку архивные сообщения + $("#trashed-button").on('click', function (e) { + e.preventDefault(); + var state = $(this).attr('data-show'); + var trashedOrderHtml = ""; + + if (state == 'true') { + $(this).attr('data-show', 'false'); + $(this).text("Скрыть архивные заказы"); + + $("#archive-space").show(); + $("#show-archive-label").show(); + } else { + $(this).attr('data-show', 'true'); + $(this).text("Показать архивные заказы"); + $("#archive-space").hide(); + $("#show-archive-label").hide(); + } + }); + + // Нажимаем на заказ в архмвных заказах + $(".messageBlock").on('click', '.trashedOrderBlock', function () { + var $this = $(this); + $("#chat-order-add").css("display", "none"); + $('.order-block, .trashedOrderBlock').each(function () { + $(this).removeClass('orAct'); + }); + $this.addClass('orAct'); + // var inbox = document.getElementById('message-chat-order-space'); + // var docList = document.getElementById('documentOrderSpace'); + // inbox.innerHTML = ''; + // docList.innerHTML = ''; + + + var orderId = $this.data('id'); + // let projectId = $this.data('project-id'); + // let recipentId = $this.data('recipent-id'); + // let orderName = $this.data('order-name'); + location.hash = '#order' + orderId; + // console.log(orderId); + window.chatController.create(orderId); + // $.ajax({ + // url: '/api/message', + // type: 'GET', + // beforeSend: function (xhr) { + // xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + // }, + // data: {'order': orderId, 'team__isnull': 'true'}, + // dataType: 'json', + // success: function (json) { + // $.each(json.results, function (i, v) { + // var senderName = 'Вы'; + // var className = 'youChat'; + // + // if (v.sender.id !== userId) { + // senderName = v.sender.username; + // className = ''; + // } + // + // inbox.innerHTML += '
    ' + + // '

    ' + senderName + '

    ' + v.created + '
    ' + + // '

    ' + v.text + '

    '; + // + // }); + // var height = inbox.scrollHeight; + // inbox.scrollTop = height; + // } + // }); + + // $("#order-stages").html(""); + // $("#completeWork").hide(); + // $("#add-form-order-note").hide(); + // $("#reserveSpace").hide(); + }); + } + + exports.bindArchiveProjects = bindArchiveProjects; + +/***/ }, +/* 23 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function chatContactsInit() { + /** + * Bind на кнопку "Отправить" в Закладке "Личные контакты" + */ + $('#contact-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat").val(); + var recipentId = $("#recipentContactId").val(); + var senderId = $("#senderContactId").val(); + var sendLinks = $("#document-send-contact a"); + + if (chatMessage || sendLinks.length > 0) { + $("#contact-chat-form .errorEmptyMessage").hide(); + + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + '' + $(this).text() + '' + '
  • '; + }); + console.log("sendLinkIds = ", sendLinkIds); + socket.send_message({ + "format_type": "add_message_contact", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles + } + } + }); + $("#chat").val(""); + $("#document-send-contact").html(""); + } else { + $("#contact-chat-form .errorEmptyMessage").show(); + } + }); + } + + function chatOrdersInit() { + /** + * Bind на кнопку "Отправить" в Закладке "Исполнители/Заказчики" + */ + $('#order-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat-order-add #chat").val(); + var recipentId = $("#chat-order-add #recipentId").val(); + var senderId = $("#chat-order-add #senderId").val(); + var orderId = $("#chat-order-add #orderId").val(); + var sendLinks = $("#document-send-order a"); + if (chatMessage || sendLinks.length > 0) { + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + '' + $(this).text() + '' + '
  • '; + }); + socket.send_message({ + "format_type": "add_message_order", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "order_id": orderId, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles + } + } + + }); + $("#chat-order-add #chat").val(""); + $("#document-send-order").html(""); + } else { + $("#chat-order-add .errorEmptyMessage").show(); + } + }); + } + + function chatTeamsInit() { + $("#add-team-chat-message").on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#team-chat-form #chatText").val(); + // var recipentId = $("#team-chat-form #recipentTeamId").val(); + var senderId = $("#team-chat-form #senderTeamId").val(); + var teamId = $("#team-chat-form #teamId").val(); + // var orderId = $("#team-chat-form #orderTeamId").val(); + var documentSendIds = $("#documentSendIds").val(); + var teamIds = $("#team-chat-form #teamIds").val(); + var sendLinks = $("#document-send a"); + if (chatMessage || sendLinks.length > 0) { + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + '' + $(this).text() + '' + '
  • '; + }); + socket.send_message({ + "format_type": "add_message_team", + "data": { + "sender_id": senderId, + // "recipent_id": recipentId, + "chat_message": chatMessage, + "team_id": teamId, + "team_ids": teamIds, + // "order_id": orderId, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles + } + } + }); + + $("#team-chat-form #chatText").val(""); + $("#document-send").html(""); + $("#documentSendIds").val(""); + } else { + $("#team-chat-form .errorEmptyMessage").show(); + } + }); + } + + exports.chatContactsInit = chatContactsInit; + exports.chatOrdersInit = chatOrdersInit; + exports.chatTeamsInit = chatTeamsInit; + +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.connect = undefined; + + var _loaders = __webpack_require__(4); + + var _messageCounters = __webpack_require__(18); + + function getUserPlace() { + /** + * Определяем в какой закладке Чата пользователь + */ + var hash = location.hash; + var tab = void 0, + id = void 0; + + var _arr = ["user", "order", "myteam"]; + for (var _i = 0; _i < _arr.length; _i++) { + var str = _arr[_i]; + if (hash.indexOf('#' + str) != -1) { + tab = str; + id = hash.replace('#' + str, ''); + } + } + return { tab: tab, id: id }; + } + + function checkMessageInPlace(message, place) { + /** + * Проверяем, направлено ли входящее сообщение на текущую вкладку пользователя + */ + // message.answer_type=place.tab + var eq = ['add_message_contact=user', 'add_message_order=order', 'add_message_team=myteam', 'approve_stages=order']; + console.log([message.answer_type, place.tab].join('=')); + console.log(message.order_id, '==', place.id, message.order_id == place.id); + if (eq.indexOf([message.answer_type, place.tab].join('=')) != -1 && (message.order_id == place.id || message.recipent_id == place.id || message.sender_id == place.id || message.team_id == place.id)) { + + return true; + } + return false; + } + + function connect() { + wsConnect.then(function (_socket) { + socket = _socket; + // Onmessage in Chat page + socket.addEventListener("message", function (event) { + var data = JSON.parse(event.data); + print.ws_print("new message on Chat page"); + console.log(", message =", data); + + var user_place = getUserPlace(); + // console.log("User place ", place.tab, place.id); + + if (checkMessageInPlace(data, user_place)) { + console.log("Сообщение принято открытым чатом"); + var chat_container_selectors = { + "user": "#message-chat-space", + "order": "#message-chat-order-space", + "myteam": "#message-chat-team-space" + }; + var documents_container_seletors = { + "user": "#documentSpace", + "order": "#documentOrderSpace", + "myteam": "#documentTeamSpace" + }; + var $chat_container = $(chat_container_selectors[user_place.tab]); + var $documents_container = $(documents_container_seletors[user_place.tab]); + var classMessage = 'youChat'; + var senderName = 'Вы'; + if (data.sender_id != userId) { + senderName = data.sender_name; + classMessage = ''; + } + if (data.is_system) { + senderName = 'Системное'; + classMessage = 'systemChat'; + } + + var chat_message = (0, _loaders.loadTemplate)('message_tmpl')({ + className: classMessage, + senderName: senderName, + message: { created: data.msg_time, text: data.msg } + }); + $chat_container.append(chat_message); + $chat_container.scrollTop($chat_container.prop("scrollHeight")); + + $documents_container.append(data.docs_attach); + + if (data.answer_type == 'approve_stages') { + window.chatController.statesController.redraw(); + } + } else { + console.log("Сообщение учтено счетчиком"); + (0, _messageCounters.countPlus)(data, user_place); + } + }); + + socket.addEventListener("close", function () { + console.error("Connection Lost"); + connect(); + }); + + socket.send_message = function (messageData) { + console.log('send message -->', messageData); + socket.send(JSON.stringify(messageData)); + }; + + socket.send_stages_approve = function (messageData) { + // TODO: Пометить сообщения как "системные" + socket.send(JSON.stringify(messageData)); + }; + }); + wsConnect.catch(function (reason) { + console.error("Server is not available", reason); + }); + } + + exports.connect = connect; + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/assets/js/build/chat_customer_oop.js b/assets/js/build/chat_customer_oop.js new file mode 100644 index 0000000..4d49282 --- /dev/null +++ b/assets/js/build/chat_customer_oop.js @@ -0,0 +1,2584 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _ChatCustomerPageController = __webpack_require__(25); + + var _BINDS = __webpack_require__(17); + + var _parts = __webpack_require__(21); + + var _chats = __webpack_require__(23); + + var _wsChatConnect = __webpack_require__(24); + + var _archiveProjects = __webpack_require__(22); + + window.connect = _wsChatConnect.connect; + window.socket = undefined; + + $(function () { + $('body').on('focus', ".term-picker", function () { + $(this).datepicker({ + minDate: 0 + }); + }); + + (0, _BINDS.bindArbitrationSend)(); + window.onhashchange = function (e) { + // console.log("Change Hash!!! ", 'a[data-toggle="tab"][href="#' + location.hash.slice(1) + '"]'); + $('a[data-toggle="tab"][href="#' + location.hash.slice(1) + '"]').trigger("click"); + }; + + window.chatController = new _ChatCustomerPageController.ChatPageController(); + (0, _BINDS.bindOrders)(); + (0, _BINDS.bindOnTabs)(); + (0, _parts.restoreTabFromHash)(); + (0, _BINDS.bindUserContacts)(); + (0, _BINDS.bindGetUserMessages)(); + (0, _archiveProjects.bindArchiveProjects)(); + (0, _BINDS.bindDeleteContact)(); + + //Chats + (0, _chats.chatContactsInit)(); + (0, _chats.chatOrdersInit)(); + }); + +/***/ }, +/* 1 */, +/* 2 */, +/* 3 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + if (cookie.substring(0, name.length + 1) == name + '=') { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + function humanFileSize(bytes, si) { + var thresh = si ? 1000 : 1024; + + if (Math.abs(bytes) < thresh) return bytes + ' B'; + + var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + + var u = -1; + + do { + bytes /= thresh; + ++u; + } while (Math.abs(bytes) >= thresh && u < units.length - 1); + + return bytes.toFixed(1) + ' ' + units[u]; + } + + exports.humanFileSize = humanFileSize; + exports.getCookie = getCookie; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.loadTemplate = undefined; + + var _stage_tmpl = __webpack_require__(5); + + var _stage_tmpl2 = _interopRequireDefault(_stage_tmpl); + + var _stage_approved_tmpl = __webpack_require__(6); + + var _stage_approved_tmpl2 = _interopRequireDefault(_stage_approved_tmpl); + + var _reserved_tmpl = __webpack_require__(7); + + var _reserved_tmpl2 = _interopRequireDefault(_reserved_tmpl); + + var _message_tmpl = __webpack_require__(8); + + var _message_tmpl2 = _interopRequireDefault(_message_tmpl); + + var _work_in_process_tmpl = __webpack_require__(9); + + var _work_in_process_tmpl2 = _interopRequireDefault(_work_in_process_tmpl); + + var _bntCompleteStage_tmpl = __webpack_require__(10); + + var _bntCompleteStage_tmpl2 = _interopRequireDefault(_bntCompleteStage_tmpl); + + var _btnSendReview_tmpl = __webpack_require__(11); + + var _btnSendReview_tmpl2 = _interopRequireDefault(_btnSendReview_tmpl); + + var _document_attach_file_tmpl = __webpack_require__(12); + + var _document_attach_file_tmpl2 = _interopRequireDefault(_document_attach_file_tmpl); + + var _note_tmpl = __webpack_require__(13); + + var _note_tmpl2 = _interopRequireDefault(_note_tmpl); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + function loadTemplate(template_name) { + var templates = { + stage_tmpl: _stage_tmpl2.default, + stage_approved_tmpl: _stage_approved_tmpl2.default, + reserved_tmpl: _reserved_tmpl2.default, + message_tmpl: _message_tmpl2.default, + work_in_process_tmpl: _work_in_process_tmpl2.default, + bntCompleteStage_tmpl: _bntCompleteStage_tmpl2.default, + btnSendReview_tmpl: _btnSendReview_tmpl2.default, + document_attach_file_tmpl: _document_attach_file_tmpl2.default, + note_tmpl: _note_tmpl2.default + }; + + if (!templates[template_name]) throw new Error('Template ' + template_name + ' does not exist'); + return templates[template_name]; + } + + exports.loadTemplate = loadTemplate; + +/***/ }, +/* 5 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return '\n
    \n

    \u042D\u0422\u0410\u041F ' + this.stage_num + '

    \n
    \n \n \n

    \n \n \n

    \n \n

    \n \n \n \n \n

    \n \n \n

    \n
    \n
    '; + }; + +/***/ }, +/* 6 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
    \n
    \n
    \n \u042D\u0422\u0410\u041F " + this.stage_num + "\n
    \n
    \n " + this.stage_status + "\n
    \n
    \n
    \n\n
    \n " + this.stage.name + "\n
    \n \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u044D\u0442\u0430\u043F\u0430\n
    \n " + this.stage.result + "\n
    \n \u0426\u0435\u043D\u0430\n
    \n " + this.stage.cost + " \u20BD\n
    \n \u0421\u0440\u043E\u043A\n
    \n \u0434\u043E " + this.stage.term + "\n
    \n\n
    "; + }; + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n\n
  • \u0421\u0443\u043C\u043C\u0430 \u0437\u0430 \u044D\u0442\u0430\u043F " + this.stage.pos + "\n
    " + this.reserved_name + "
    \n
  • "; + }; + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
    \n
    \n

    " + this.senderName + "

    " + this.message.created + "\n
    \n

    " + this.message.text + "

    \n
    "; + }; + +/***/ }, +/* 9 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
    \n \u0412 \u0440\u0430\u0431\u043E\u0442\u0435: " + this.stage.name + "
    \n \u0420\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u044D\u0442\u0430\u043F\u0430: " + this.stage.result + "
    \n \u0421\u0440\u043E\u043A \u0441\u0434\u0430\u0447\u0438: " + this.stage.term + "
    \n " + this.stage.cost + " \u0440\n
    \n " + this.note_text + "\n
    \n
    "; + }; + +/***/ }, +/* 10 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n"; + }; + +/***/ }, +/* 11 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return ""; + }; + +/***/ }, +/* 12 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "\n
  • \n " + this.text + "\n
    \n
  • \n\n"; + }; + +/***/ }, +/* 13 */ +/***/ function(module, exports) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + exports.default = function (ctx) { + return _template.call(ctx, ctx); + }; + + function _template() { + return "
    \n
  • \n " + this.text + "\n
  • \n
    \n
    \n"; + }; + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.StageInWork = exports.StageReserved = exports.StageForm = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _loaders = __webpack_require__(4); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + // new-stages-form + // update-stages-form + // remove-stages-form + + var StageForm = function () { + function StageForm($container, _ref) + // kwargs - auto generate from name_attributes + { + var orderId = _ref.orderId, + stage_num = _ref.stage_num, + stage_status = _ref.stage_status, + _ref$type = _ref.type, + type = _ref$type === undefined ? 'new' : _ref$type, + _ref$formNamePostfix = _ref.formNamePostfix, + formNamePostfix = _ref$formNamePostfix === undefined ? '-stages-form' : _ref$formNamePostfix, + template_name = _ref.template_name, + _ref$data = _ref.data, + data = _ref$data === undefined ? {} : _ref$data; + var kwargs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { + stage_num: stage_num, + stage_status: stage_status, + form_name: type + formNamePostfix, + orderId: orderId, + stage: data + }; + + _classCallCheck(this, StageForm); + + // console.log('Stage form template_name = ', template_name); + this.orderId = orderId; + this._type = type; + this.$container = $container; + this.self_tmpl = (0, _loaders.loadTemplate)(template_name); + this.data = data; + this.$form = undefined; + this.stageId = type != 'new' ? data.id : undefined; + this.create(kwargs); + } + + _createClass(StageForm, [{ + key: 'create', + value: function create(kwargs) { + /** + * Добавление шаблона-формы Этапа на страницу + */ + var el = $(this.self_tmpl(kwargs)); + this.$container.append(el); + this.$form = el.find('form'); + // console.log("form --> ", this.$form); + if (this.$form.length) this.$form.find('input[name=cost]').mask('000000000'); + } + }, { + key: 'remove', + value: function remove() { + /** + * Удаление, при уменьшении кол-ва этапов + * return true - удаляем из [] stages + */ + if (this.type == 'new') { + this.$form.parent().remove(); + return true; + } + this.type = 'remove'; + // this.$form.removeClass('update-stages-form').addClass('remove-stages-form'); + return false; + } + }, { + key: 'restore', + value: function restore() { + /** + * Восстановление, при увеличении кол-ва этапов + */ + if (this.type == 'new') throw new Error("Попытка восстановить элемент с type='new'"); + this.type = 'update'; + // this.$form.removeClass('remove-stages-form').addClass('update-stages-form'); + } + }, { + key: 'disable', + value: function disable() { + this.$form.find('input').attr('readonly', true); + } + }, { + key: 'enable', + value: function enable() { + this.$form.find('input').attr('readonly', false); + } + }, { + key: 'hide', + value: function hide() { + this.$form.parent().hide(); + } + }, { + key: 'show', + value: function show() { + this.$form.parent().show(); + } + }, { + key: 'is_valid', + value: function is_valid() { + var self = this; + var mesage = 'Это поле обязательно'; + var valid = true; + //Очищаем старые ошибки + this.$form.find('.error').html(""); + // Отображаем новые + this.$form.find(":input:not([type=hidden])").each(function (i, v) { + if (!$(v).val()) { + self.$form.find('.error-' + $(v).attr("name")).html(mesage).css('color', 'red'); + valid = false; + } + }); + return valid; + } + }, { + key: 'sendAjax_approve', + value: function sendAjax_approve() { + /** + * Отправка Этапа "на согласование" + */ + var self = this; + // console.log("Send AJAX Approve"); + if (this.type == 'new') { + // console.log('new stages approve'); + return Promise.resolve($.ajax({ + // async: false, + url: '/api/stages/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: this.$form.serialize(), + dataType: 'json' + }).done(function (json) { + self.type = 'update'; + self.disable(); + self.$form.find('.error').html(""); + // console.log("json -->", json); + self.stageId = json.id; + // console.log(json); + }).fail(function (xhr, errorMsg, error) { + console.log("ERROR, xhr", xhr); + $.each(xhr.responseJSON, function (i, v) { + self.$form.find('.error-' + i).html(v).css('color', 'red'); + // console.log(self.$form); + // console.log(v); + // console.log(i); + }); + })); + } else if (this.type == 'update') { + this.$form.find('input[name=status]').val('send_approve'); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PUT', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: this.$form.serialize(), + dataType: 'json' + }).done(function (json) { + self.$form.find('.error').html(""); + self.disable(); + }).fail(function (xhr, errorMsg, error) { + $.each(xhr.responseJSON, function (i, v) { + self.$form.find('.error-' + i).html(v).css('color', 'red'); + console.log(v); + console.log(i); + }); + })); + } else if (this.type == 'remove') { + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'DELETE', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + dataType: 'json' + }).done(function (json) {}).fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + })); + } + } + }, { + key: 'sendAjax_accept', + value: function sendAjax_accept(secureOrder) { + /** + * "Согласовать" Этапы (Исполнителем) + */ + console.log("secureOrder = ", secureOrder); + console.log("set new status =", secureOrder ? 'agreed' : 'in_process'); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + //TODO: слать только изменения + data: { + status: secureOrder ? 'agreed' : 'in_process' + }, + dataType: 'json' + })); + } + }, { + key: 'sendAjax_change', + value: function sendAjax_change() { + /** + * Отправка Этапа "Внести изменения" + */ + var self = this; + // this.$form.find('input[name=status]').val('not_agreed'); + // console.log("ajax Change form -->", this.$form); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + //TODO: слать только изменения + data: { status: 'not_agreed' }, + dataType: 'json' + }).done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + self.enable(); + }).fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + }, { + key: 'type', + set: function set(newType) { + this.$form.removeClass(this._type + '-stages-form').addClass(newType + '-stages-form'); + if (newType == 'remove') this.hide(); + if (newType == 'update') this.show(); + this._type = newType; + }, + get: function get() { + return this._type; + } + }]); + + return StageForm; + }(); + + var StageReserved = function () { + function StageReserved($container, _ref2) { + var _ref2$template_name = _ref2.template_name, + template_name = _ref2$template_name === undefined ? 'reserved_tmpl' : _ref2$template_name, + data = _ref2.data; + var kwargs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { + reserved_cls: '', + reserved_name: '', + stage: data + }; + + _classCallCheck(this, StageReserved); + + // Вывод текста резервирования в зависимости от статуса этапа + var reserved_names = { + agreed: 'Не зарезервирована', + in_process: 'Зарезервирована', + completed: 'Зарезервирована', + closed: 'Переведена исполнителю' + }; + // Вывод текста резервирования в зависимости от статуса этапа + var reserved_classes = { + agreed: 'unreserved', + in_process: 'reserved', + completed: 'reserved', + closed: 'closed' + }; + kwargs.reserved_cls = reserved_classes[data.status]; + kwargs.reserved_name = reserved_names[data.status]; + this.data = data; + this.self_tmpl = (0, _loaders.loadTemplate)(template_name); + this.$container = $container; + this.create(kwargs); + } + + _createClass(StageReserved, [{ + key: 'create', + value: function create(kwargs) { + /** + * Добавление шаблона "Резервирование" Этапа на страницу + */ + this.$self = $(this.self_tmpl(kwargs)); + this.$container.append(this.$self); + // console.log("form --> ", this.$form); + // this.$form.find('input[name=cost]').mask('000000000'); + } + }]); + + return StageReserved; + }(); + + var StageInWork = function () { + function StageInWork($container, _ref3) { + var _ref3$template_name = _ref3.template_name, + template_name = _ref3$template_name === undefined ? 'work_in_process_tmpl' : _ref3$template_name, + _ref3$note_text = _ref3.note_text, + note_text = _ref3$note_text === undefined ? '' : _ref3$note_text, + data = _ref3.data; + var kwargs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : { stage: data, note_text: note_text }; + + _classCallCheck(this, StageInWork); + + this.stageId = data.id; + this.data = data; + this.self_tmpl = (0, _loaders.loadTemplate)(template_name); + this.$container = $container; + this.create(kwargs); + } + + _createClass(StageInWork, [{ + key: 'create', + value: function create(kwargs) { + /** + * Добавление шаблона "Выполнение работы" Этапа на страницу + */ + this.$self = $(this.self_tmpl(kwargs)); + this.$container.append(this.$self); + } + }, { + key: 'hide', + value: function hide() { + this.$self.hide(); + } + }, { + key: 'sendAjax_complete', + value: function sendAjax_complete() { + /** + * Отправка Этапа "Закрыть этап" + */ + var self = this; + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + data: { status: 'completed' }, + dataType: 'json' + }).done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + // self.enable(); + }).fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + }, { + key: 'sendAjax_close', + value: function sendAjax_close() { + /** + * Отправка Этапа "Закрыть этап" + */ + var self = this; + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + //TODO: слать только изменения + data: { status: 'closed' }, + dataType: 'json' + }).done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + // self.enable(); + }).fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + }]); + + return StageInWork; + }(); + + exports.StageForm = StageForm; + exports.StageReserved = StageReserved; + exports.StageInWork = StageInWork; + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.MessagesController = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _utils = __webpack_require__(3); + + var _loaders = __webpack_require__(4); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var MessagesController = function () { + function MessagesController(orderId) { + _classCallCheck(this, MessagesController); + + console.log('Create MessagesController'); + var self = this; + this.orderId = orderId; + this.$inbox = $('#message-chat-order-space'); + this.$inbox.html(""); + this.messageTemplate = (0, _loaders.loadTemplate)('message_tmpl'); + this.dataPromise = this.getMessagesData(); + this.dataPromise.then(self._onLoadData.bind(self)); + } + + _createClass(MessagesController, [{ + key: 'getMessagesData', + value: function getMessagesData() { + var self = this; + return Promise.resolve($.ajax({ + url: '/api/message', + type: 'GET', + data: { 'order': self.orderId, 'team__isnull': 'true' }, + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + success: function success(json) { + console.log('Success Messages'); + } + })); + } + }, { + key: '_onLoadData', + value: function _onLoadData(json) { + var self = this; + // console.log('mesages json = ', json); + // console.log('$inbox = ', this.$inbox); + // console.log("messages render start"); + self.$inbox.html(""); + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + if (v.is_system) { + senderName = 'Системное'; + className = 'systemChat'; + } + var message = $(self.messageTemplate({ className: className, senderName: senderName, message: v })); + self.$inbox.append(message); + }); + // console.log("messages render complete"); + self.$inbox.scrollTop(self.$inbox.prop("scrollHeight")); + } + }]); + + return MessagesController; + }(); + + exports.MessagesController = MessagesController; + +/***/ }, +/* 16 */, +/* 17 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.bindDeleteContact = exports.bindTeams = exports.bindGetUserMessages = exports.bindUserContacts = exports.bindOnTabs = exports.bindArbitrationSend = exports.bindOrders = undefined; + + var _utils = __webpack_require__(3); + + var _messageCounters = __webpack_require__(18); + + var _loaders = __webpack_require__(4); + + function dialog(message, yesCallback, notCallback) { + $("#dialog_delete .modal-title").html(message); + $("#dialog_delete").modal('show'); + $("#btnYes").click(function (e) { + e.preventDefault(); + yesCallback(); + $("#dialog_delete").modal('hide'); + }); + $("#btnNot").click(function (e) { + e.preventDefault(); + notCallback(); + $("#dialog_delete").modal('hide'); + }); + } + + function bindOrders() { + $('.order-block').on('click', function (event) { + event.preventDefault(); + var $this = $(this); + (0, _messageCounters.onClickCardWithCount)($this); + $('.order-block').each(function (i, v) { + $(v).removeClass('orAct'); + }); + $this.addClass('orAct'); + var orderId = $this.data('id'); + var projectId = $this.data('project-id'); + var recipentId = $this.data('recipent-id'); + var orderName = $this.data('order-name'); + var secureOrder = $(this).data('secure-deal'); + secureOrder = Boolean(secureOrder); + window.location.hash = 'order' + orderId; + + $("#chat-order-add #orderId").val(orderId); + $("#add-form-order-note #orderNote").val(orderId); + $("#orderArbitrationId").val(orderId); + $("#projectReviewId").val(projectId); + $("#reserve-button").attr('data-order-id', orderId); + + $("#chat-order-add #recipentId").val(recipentId); + window.chatController.create(orderId, projectId, recipentId, orderName, secureOrder); + }); + $('.order-block .dimovChat').on('click', function (event) { + event.preventDefault(); + event.stopPropagation(); + // console.log('click on tr'); + }); + } + + function bindTeams() { + $('.team-block').on('click', function () { + (0, _messageCounters.onClickCardWithCount)($(this)); + $('.team-order-block, .team-block').each(function () { + $(this).removeClass('orAct'); + }); + $(this).addClass('orAct'); + + var teamIds = ''; + $.each($(this).find('.team-chat-user'), function (i, v) { + teamIds += $(this).attr('data-id') + ";"; + }); + $("#team-chat-form #teamIds").val(teamIds); + + var inbox = document.getElementById('message-chat-team-space'); + inbox.innerHTML = ''; + + var docList = document.getElementById('documentTeamSpace'); + docList.innerHTML = ''; + + var teamId = $(this).attr('data-team-id'); + location.hash = '#myteam' + teamId; + + // var newCount = parseInt($("#count-tab-team").text()); + // var currNewCount = parseInt($(".team-count-" + teamId).text()); + // var resCount = newCount - currNewCount; + // $("#count-tab-team").text(resCount); + $(".team-count-" + teamId).text(0); + + $("#team-chat-form #teamId").val(teamId); + $("#add-form-team-note #teamNote").val(teamId); + $("#team-chat-form #recipentTeamId").val(""); + $("#team-chat-form #orderTeamId").val(""); + $("#add-form-team-note #orderNote").val(""); + + $.ajax({ + url: '/api/message', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { 'team': teamId, 'order__isnull': 'true' }, + dataType: 'json', + success: function success(json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
    ' + '

    ' + senderName + '

    ' + v.created + '
    ' + '

    ' + v.text + '

    '; + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'team': teamId, + 'is_delete': false, + 'is_send': true + }, + dataType: 'json', + success: function success(json) { + $.each(json.results, function (i, v) { + docList.innerHTML += '
  • ' + v.file + '
  • '; + }); + }, + error: function error(e) { + console.log(e); + } + }); + + $.ajax({ + url: '/api/note/', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { 'team': teamId }, + dataType: 'json', + success: function success(json) { + console.log(json.results); + var noteHtmlInbox = ''; + var note_tmpl = (0, _loaders.loadTemplate)('note_tmpl'); + $.each(json.results, function (i, v) { + noteHtmlInbox += note_tmpl({ text: v.text }); + }); + $(".team-notes-block").html(noteHtmlInbox); + } + }); + }); + } + + function bindArbitrationSend() { + // TODO: Test it + $('#order-arbitration-add').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + var formData = $("#arbitration-add-form").serialize(); + $.ajax({ + url: '/projects/arbitration/create/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: formData, + dataType: 'json', + success: function success(json) { + console.log(json); + $("#arbitration-add").modal('hide'); + $.jGrowl("Обращение в арбитраж добавлено", { + life: 4000 + }); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }); + } + + function bindOnTabs() { + /** + * Биндит обработчики на Закладки + */ + $('a[data-toggle="tab"]').unbind().on('show.bs.tab', function (e) { + console.log("TAB!"); + var activeTab = $(this).attr('href').substring(1); + var liveHash = URI(location.href).hash(); + + switch (activeTab) { + case 'tab1': + setTimeout(function () { + if (liveHash.indexOf("#user") != -1) { + var userHashId = liveHash.replace("#user", ""); + $("#userBlock" + userHashId).trigger('click'); + } else { + $(".user-block").first().trigger('click'); + } + }, 100); + break; + + case 'tab2': + // console.log("tab2"); + setTimeout(function () { + if (liveHash.indexOf("#order") != -1) { + var ordHashId = liveHash.replace("#order", ""); + $("#orderBlock" + ordHashId).trigger('click'); + } else { + $(".order-block").first().trigger('click'); + } + }, 100); + break; + + case 'tab3': + setTimeout(function () { + console.log("on active TAB team"); + if (liveHash.indexOf("#teamorder") != -1) { + var teamHashId = liveHash.replace("#teamorder", ""); + $("#teamOrderBlock" + teamHashId).trigger('click'); + } else if (liveHash.indexOf("#myteam") != -1) { + var teamHashId = liveHash.replace("#myteam", ""); + $("#teamMyBlock" + teamHashId).trigger('click'); + } else { + var firstTeamBlock = $(".team-block").first(); + var firstTeamOrder = $(".team-order-block").first(); + if (firstTeamOrder.length == 1) { + firstTeamOrder.trigger('click'); + } else if (firstTeamBlock.length == 1) { + firstTeamBlock.trigger('click'); + } + } + }, 100); + + } + }); + } + + function bindUserContacts() { + $(".conMess").click('on', function (e) { + e.preventDefault(); + e.stopPropagation(); + + var userId = $(this).attr('data-id'); + $.ajax({ + url: '/api/users/' + userId + '/', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json', + success: function success(data) { + var outTable = ''; + if (data.username) { + outTable += 'Ник' + data.username + ''; + } + + if (data.fio) { + outTable += 'Ф.И.О' + data.fio + ''; + } + if (data.skype) { + outTable += 'Skype' + data.skype + ''; + } + + if (data.website) { + outTable += 'Сайт' + data.website + ''; + } + + if (data.phone) { + outTable += 'Телефон' + data.phone + ''; + } + + $("#contact-info table").html(outTable); + $("#contact-info").modal('show'); + // console.log(data); + }, + error: function error(e, jqxhr) { + console.log(e); + } + }); + }); + } + + function bindGetUserMessages() { + $('.user-block').on('click', function () { + (0, _messageCounters.onClickCardWithCount)($(this)); + // var newCount = parseInt($("#count-tab-contact").text()); + var contactId = $(this).attr('data-id'); + location.hash = '#user' + contactId; + $("#contact-chat-form #recipentContactId").val(contactId); + $("#add-form-contractor-note #recipentNoteContractor").val(contactId); + + $('.user-block').each(function () { + $(this).removeClass('mesAct'); + }); + + $(this).addClass('mesAct'); + var inbox = document.getElementById('message-chat-space'); + var sumSenderRecipent = parseInt(userId) + parseInt(contactId); + + $("#message-chat-space").removeClass().addClass("contact-space" + sumSenderRecipent); + // var currNewCount = parseInt($(".contact-count-" + sumSenderRecipent).text()); + // var resCount = newCount - currNewCount; + // $("#count-tab-contact").text(resCount); + $(".contact-count-" + sumSenderRecipent).text(0); + var docList = document.getElementById('documentSpace'); + inbox.innerHTML = ''; + docList.innerHTML = ''; + + $.ajax({ + url: '/api/message', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId + }, + dataType: 'json', + success: function success(json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id == contactId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
    ' + '

    ' + senderName + '

    ' + v.created + '
    ' + '

    ' + v.text + '

    '; + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId, + 'is_delete': false, + 'is_send': true + }, + dataType: 'json', + + success: function success(json) { + console.log(json); + + $.each(json.results, function (i, v) { + docList.innerHTML += '
  • ' + v.file + '
  • '; + }); + }, + error: function error(e) { + console.log(e); + } + }); + + $.ajax({ + url: '/api/note/', + type: 'GET', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId + }, + dataType: 'json', + success: function success(json) { + console.log(json.results); + var noteHtmlInbox = ''; + var note_tmpl = (0, _loaders.loadTemplate)('note_tmpl'); + $.each(json.results, function (i, v) { + noteHtmlInbox += note_tmpl({ text: v.text }); + }); + $(".contractor-notes-block").html(noteHtmlInbox); + } + }); + }); + } + + function bindDeleteContact() { + $('.deleteMess').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + + var senderId = userId; + var recipentId = $(this).attr('data-recipent-id'); + var _this = $(this); + + dialog("Вы действительно хотите удалить сообщения этого пользователя?", function () { + $.ajax({ + url: '/chat/messages_delete/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { 'sender_id': senderId, 'recipent_id': recipentId }, + dataType: 'json', + success: function success(json) { + + if (json.status == 'ok') { + _this.parent().remove(); + $("#message-chat-space").html(""); + } + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + }.bind(null, senderId, recipentId, _this), function () {}); + }); + } + + exports.bindOrders = bindOrders; + exports.bindArbitrationSend = bindArbitrationSend; + exports.bindOnTabs = bindOnTabs; + exports.bindUserContacts = bindUserContacts; + exports.bindGetUserMessages = bindGetUserMessages; + exports.bindTeams = bindTeams; + exports.bindDeleteContact = bindDeleteContact; + +/***/ }, +/* 18 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function recalculateTabsCounter() { + // let tabs = [$('#count-tab-contact'), $('#count-tab-order'), $('#count-tab-team')] + var tabs = [$('#tab1'), $('#tab2'), $('#tab3')]; + var total_messages_count = 0; + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = tabs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var tab = _step.value; + + var count_sum = Array.from(tab.find('.js-count').map(function (i, el) { + return parseInt($(el).html()); + })).reduce(function (a, b) { + return a + b; + }, 0); + var $tab_counter = $('a[href="#' + tab.attr('id') + '"]').find('.count-tab'); + $tab_counter.html(count_sum); + total_messages_count += count_sum; + // console.log($tab_counter, 'new value -->', count_sum); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + var $header_counter = $('.js-all-messages'); + $header_counter.html(total_messages_count); + } + + function countPlus(message, place) { + /** + * Увеличиваем счетчик соответствующий сообщению(message) + */ + // console.log("MESSAGE = ", message); + var $container = void 0; + if (message.answer_type == "add_message_contact") { + $container = $('.contact-count-' + message.sender_id); + } else if (message.answer_type == "add_message_order") { + $container = $('#count-order-' + message.order_id); + } else if (message.answer_type == "add_message_team") { + $container = $('#count-team-' + message.team_id); + } + // console.log("container = ", $container); + $container.html(parseInt($container.html()) + 1); + recalculateTabsCounter(); + } + + function onClickCardWithCount($card) { + /** + * При нажатии на карточку со счетчиком новых сообщений + */ + // console.log('Обнулем счетчик ', $card); + $card.find('.js-count').html(0); + recalculateTabsCounter(); + } + + exports.countPlus = countPlus; + exports.onClickCardWithCount = onClickCardWithCount; + +/***/ }, +/* 19 */, +/* 20 */, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + "use strict"; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.restoreTabFromHash = undefined; + + var _utils = __webpack_require__(3); + + function restoreTabFromHash() { + var currentHash = URI(location.href).hash(); + if (currentHash.indexOf("#order") == 0) { + $("a[href='#tab2']").trigger('click'); + // console.log("click on ", "#orderBlock" + currentHash.replace("#order", "")); + var obj_id = currentHash.replace("#order", ""); + console.log("obj_id = ", obj_id); + if (obj_id) { + $("#orderBlock" + currentHash.replace("#order", "")).trigger('click'); + } else { + $('.order-block').first().trigger('click'); + } + } else if (currentHash.indexOf("#user") == 0) { + $("a[href='#tab1']").trigger('click'); + } else if (currentHash.indexOf("#teamorder") == 0 || currentHash.indexOf("#myteam") == 0) { + $("a[href='#tab3']").trigger('click'); + } else { + $("a[href='#tab1']").trigger('click'); + } + } + + exports.restoreTabFromHash = restoreTabFromHash; + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.bindArchiveProjects = undefined; + + var _utils = __webpack_require__(3); + + function bindArchiveProjects() { + // Нажимаем на кнопку архивные сообщения + $("#trashed-button").on('click', function (e) { + e.preventDefault(); + var state = $(this).attr('data-show'); + var trashedOrderHtml = ""; + + if (state == 'true') { + $(this).attr('data-show', 'false'); + $(this).text("Скрыть архивные заказы"); + + $("#archive-space").show(); + $("#show-archive-label").show(); + } else { + $(this).attr('data-show', 'true'); + $(this).text("Показать архивные заказы"); + $("#archive-space").hide(); + $("#show-archive-label").hide(); + } + }); + + // Нажимаем на заказ в архмвных заказах + $(".messageBlock").on('click', '.trashedOrderBlock', function () { + var $this = $(this); + $("#chat-order-add").css("display", "none"); + $('.order-block, .trashedOrderBlock').each(function () { + $(this).removeClass('orAct'); + }); + $this.addClass('orAct'); + // var inbox = document.getElementById('message-chat-order-space'); + // var docList = document.getElementById('documentOrderSpace'); + // inbox.innerHTML = ''; + // docList.innerHTML = ''; + + + var orderId = $this.data('id'); + // let projectId = $this.data('project-id'); + // let recipentId = $this.data('recipent-id'); + // let orderName = $this.data('order-name'); + location.hash = '#order' + orderId; + // console.log(orderId); + window.chatController.create(orderId); + // $.ajax({ + // url: '/api/message', + // type: 'GET', + // beforeSend: function (xhr) { + // xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + // }, + // data: {'order': orderId, 'team__isnull': 'true'}, + // dataType: 'json', + // success: function (json) { + // $.each(json.results, function (i, v) { + // var senderName = 'Вы'; + // var className = 'youChat'; + // + // if (v.sender.id !== userId) { + // senderName = v.sender.username; + // className = ''; + // } + // + // inbox.innerHTML += '
    ' + + // '

    ' + senderName + '

    ' + v.created + '
    ' + + // '

    ' + v.text + '

    '; + // + // }); + // var height = inbox.scrollHeight; + // inbox.scrollTop = height; + // } + // }); + + // $("#order-stages").html(""); + // $("#completeWork").hide(); + // $("#add-form-order-note").hide(); + // $("#reserveSpace").hide(); + }); + } + + exports.bindArchiveProjects = bindArchiveProjects; + +/***/ }, +/* 23 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function chatContactsInit() { + /** + * Bind на кнопку "Отправить" в Закладке "Личные контакты" + */ + $('#contact-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat").val(); + var recipentId = $("#recipentContactId").val(); + var senderId = $("#senderContactId").val(); + var sendLinks = $("#document-send-contact a"); + + if (chatMessage || sendLinks.length > 0) { + $("#contact-chat-form .errorEmptyMessage").hide(); + + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + '' + $(this).text() + '' + '
  • '; + }); + console.log("sendLinkIds = ", sendLinkIds); + socket.send_message({ + "format_type": "add_message_contact", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles + } + } + }); + $("#chat").val(""); + $("#document-send-contact").html(""); + } else { + $("#contact-chat-form .errorEmptyMessage").show(); + } + }); + } + + function chatOrdersInit() { + /** + * Bind на кнопку "Отправить" в Закладке "Исполнители/Заказчики" + */ + $('#order-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat-order-add #chat").val(); + var recipentId = $("#chat-order-add #recipentId").val(); + var senderId = $("#chat-order-add #senderId").val(); + var orderId = $("#chat-order-add #orderId").val(); + var sendLinks = $("#document-send-order a"); + if (chatMessage || sendLinks.length > 0) { + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + '' + $(this).text() + '' + '
  • '; + }); + socket.send_message({ + "format_type": "add_message_order", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "order_id": orderId, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles + } + } + + }); + $("#chat-order-add #chat").val(""); + $("#document-send-order").html(""); + } else { + $("#chat-order-add .errorEmptyMessage").show(); + } + }); + } + + function chatTeamsInit() { + $("#add-team-chat-message").on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#team-chat-form #chatText").val(); + // var recipentId = $("#team-chat-form #recipentTeamId").val(); + var senderId = $("#team-chat-form #senderTeamId").val(); + var teamId = $("#team-chat-form #teamId").val(); + // var orderId = $("#team-chat-form #orderTeamId").val(); + var documentSendIds = $("#documentSendIds").val(); + var teamIds = $("#team-chat-form #teamIds").val(); + var sendLinks = $("#document-send a"); + if (chatMessage || sendLinks.length > 0) { + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + '' + $(this).text() + '' + '
  • '; + }); + socket.send_message({ + "format_type": "add_message_team", + "data": { + "sender_id": senderId, + // "recipent_id": recipentId, + "chat_message": chatMessage, + "team_id": teamId, + "team_ids": teamIds, + // "order_id": orderId, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles + } + } + }); + + $("#team-chat-form #chatText").val(""); + $("#document-send").html(""); + $("#documentSendIds").val(""); + } else { + $("#team-chat-form .errorEmptyMessage").show(); + } + }); + } + + exports.chatContactsInit = chatContactsInit; + exports.chatOrdersInit = chatOrdersInit; + exports.chatTeamsInit = chatTeamsInit; + +/***/ }, +/* 24 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.connect = undefined; + + var _loaders = __webpack_require__(4); + + var _messageCounters = __webpack_require__(18); + + function getUserPlace() { + /** + * Определяем в какой закладке Чата пользователь + */ + var hash = location.hash; + var tab = void 0, + id = void 0; + + var _arr = ["user", "order", "myteam"]; + for (var _i = 0; _i < _arr.length; _i++) { + var str = _arr[_i]; + if (hash.indexOf('#' + str) != -1) { + tab = str; + id = hash.replace('#' + str, ''); + } + } + return { tab: tab, id: id }; + } + + function checkMessageInPlace(message, place) { + /** + * Проверяем, направлено ли входящее сообщение на текущую вкладку пользователя + */ + // message.answer_type=place.tab + var eq = ['add_message_contact=user', 'add_message_order=order', 'add_message_team=myteam', 'approve_stages=order']; + console.log([message.answer_type, place.tab].join('=')); + console.log(message.order_id, '==', place.id, message.order_id == place.id); + if (eq.indexOf([message.answer_type, place.tab].join('=')) != -1 && (message.order_id == place.id || message.recipent_id == place.id || message.sender_id == place.id || message.team_id == place.id)) { + + return true; + } + return false; + } + + function connect() { + wsConnect.then(function (_socket) { + socket = _socket; + // Onmessage in Chat page + socket.addEventListener("message", function (event) { + var data = JSON.parse(event.data); + print.ws_print("new message on Chat page"); + console.log(", message =", data); + + var user_place = getUserPlace(); + // console.log("User place ", place.tab, place.id); + + if (checkMessageInPlace(data, user_place)) { + console.log("Сообщение принято открытым чатом"); + var chat_container_selectors = { + "user": "#message-chat-space", + "order": "#message-chat-order-space", + "myteam": "#message-chat-team-space" + }; + var documents_container_seletors = { + "user": "#documentSpace", + "order": "#documentOrderSpace", + "myteam": "#documentTeamSpace" + }; + var $chat_container = $(chat_container_selectors[user_place.tab]); + var $documents_container = $(documents_container_seletors[user_place.tab]); + var classMessage = 'youChat'; + var senderName = 'Вы'; + if (data.sender_id != userId) { + senderName = data.sender_name; + classMessage = ''; + } + if (data.is_system) { + senderName = 'Системное'; + classMessage = 'systemChat'; + } + + var chat_message = (0, _loaders.loadTemplate)('message_tmpl')({ + className: classMessage, + senderName: senderName, + message: { created: data.msg_time, text: data.msg } + }); + $chat_container.append(chat_message); + $chat_container.scrollTop($chat_container.prop("scrollHeight")); + + $documents_container.append(data.docs_attach); + + if (data.answer_type == 'approve_stages') { + window.chatController.statesController.redraw(); + } + } else { + console.log("Сообщение учтено счетчиком"); + (0, _messageCounters.countPlus)(data, user_place); + } + }); + + socket.addEventListener("close", function () { + console.error("Connection Lost"); + connect(); + }); + + socket.send_message = function (messageData) { + console.log('send message -->', messageData); + socket.send(JSON.stringify(messageData)); + }; + + socket.send_stages_approve = function (messageData) { + // TODO: Пометить сообщения как "системные" + socket.send(JSON.stringify(messageData)); + }; + }); + wsConnect.catch(function (reason) { + console.error("Server is not available", reason); + }); + } + + exports.connect = connect; + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.ChatPageController = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _StagesCustomerController = __webpack_require__(26); + + var _MessagesControllers = __webpack_require__(15); + + var _messageCounters = __webpack_require__(18); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var ChatPageController = function () { + function ChatPageController() { + _classCallCheck(this, ChatPageController); + + var self = this; + // console.log("NEW Chat CUSTOMER PageController"); + this.statesController = undefined; + this.messagesController = undefined; + // TODO: не забыть! + // recalculateMessages(); + } + + _createClass(ChatPageController, [{ + key: 'create', + value: function create(orderId, projectId, recipentId, orderName, secureOrder) { + this.statesController = new _StagesCustomerController.StagesController(orderId, projectId, recipentId, orderName, secureOrder); + this.messagesController = new _MessagesControllers.MessagesController(orderId); + } + }]); + + return ChatPageController; + }(); + + exports.ChatPageController = ChatPageController; + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.StagesController = undefined; + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + var _utils = __webpack_require__(3); + + var _loaders = __webpack_require__(4); + + var _Stages = __webpack_require__(14); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var message_format = { + "format_type": "approve_stages", + "data": { + "sender_id": "", + "recipent_id": "", + "order_id": "", + "msg": "", + "is_system": true + } + }; + + var STATUSES = { + 'not_agreed': 'не согласован', + 'send_approve': 'на согласовании', + 'agreed': 'согласовано', + 'cancel_approve': 'исполнитель отказался', + 'in_process': 'в процессе', + 'completed': 'завершен', + 'closed': 'закрыт' + + }; + + var StagesController = function () { + function StagesController(orderId, projectId, recipentId, orderName, secureOrder) { + _classCallCheck(this, StagesController); + + var self = this; + this.orderId = orderId; + this.orderName = orderName; + this.projectId = projectId; + this.recipentId = recipentId; + this.secureOrder = secureOrder; + this.data = {}; //JSON + this.stages = []; + this.stages_reserved = []; + this.stages_work = []; + this.STAGE_STATUSES = { + 'not_agreed': this.buildNotAgreedStage.bind(self), + 'send_approve': this.buildSendApproveStage.bind(self), + 'agreed': this.buildAgreedStage.bind(self), + 'in_process': this.buildProcessStage.bind(self), + 'completed': this.buildProcessStage.bind(self), + 'closed': this.buildProcessStage.bind(self) + }; + this.btnCompleteTmpl = (0, _loaders.loadTemplate)('bntCompleteStage_tmpl'); + this.btnSendReviewTmpl = (0, _loaders.loadTemplate)('btnSendReview_tmpl'); + this.$orderStagesContainer = $('#order-stages'); + this.$orderStagesContainer.html(''); + this.$stagesCount = $('#countStage'); + this.$stagesCount.unbind().on("change", this._changeNumStages.bind(self)); + this.$stagesCount.parent().show(); + this.buttons = { + btnApprove: $('#btnApprove'), + btnChange: $('#btnChange'), + btnToArchive: $('#btnToArchive'), + btnReserve: $('#btnReserve'), + btnsArbitration: $('.js-btnArbitration'), + btnSendReview: $('#order-review-add') + }; + this.stages_elements = { + $approve: $('#conditions-approve'), //1. Согласование условия + $reserve: $('#reserveSpace'), //2. Резервирование + $works: $('#completeWork') //3. Выполненная работа + }; + this.init(); + } + + _createClass(StagesController, [{ + key: 'init', + value: function init() { + var self = this; + + this.dataPromise = this.getOrderData({ orderId: this.orderId }); + this.dataPromise.then(self._onLoadData.bind(self)).catch(self._onLoadDataError.bind(self)); + } + }, { + key: 'getOrderData', + value: function getOrderData(_ref) { + var orderId = _ref.orderId; + + var self = this; + return Promise.resolve($.ajax({ + url: '/api/orders/' + orderId + '/', + dataType: 'json', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + } + })); + } + }, { + key: 'redraw', + value: function redraw() { + /** + * Полностью перерисовываем страницу Заказа + */ + console.log("Redraw customer stages"); + // $("#orderBlock" + this.orderId).trigger('click'); + this.init(); + } + }, { + key: 'buildStartStage', + value: function buildStartStage() { + /** + * Стадия: "Проект Предложен"(нет этапов) + */ + // Выделить цифру 1. красным + // $('#conditions-approve').find('.select') + this.$orderStagesContainer.show(); + this.buttons.btnApprove.show(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + this.$stagesCount.removeAttr('disabled'); + this.$stagesCount.val(1); + this.$stagesCount.trigger('change'); + // this.stages_elements.$approve.find('.js-help-text').show(); + // this.stages_elements.$reserve.find('.js-help-text').show(); + // this.stages_elements.$reserve.find('.stages-paid').hide(); + // this.stages_elements.$works.find('.js-help-text').show(); + // this.stages_elements.$works.find('#stagesWork').show(); + } // Нет Этапов + + }, { + key: 'buildNotAgreedStage', + value: function buildNotAgreedStage() { + console.log("Stage: not_agreed"); + this._renderStage('stage_tmpl'); + this.buttons.btnApprove.show(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + } // Статус "Не согласован" + + }, { + key: 'buildSendApproveStage', + value: function buildSendApproveStage() { + console.log("Stage: send_approve"); + this._renderStage('stage_tmpl', true); + this.$stagesCount.attr('disabled', true); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.show(); + this.buttons.btnToArchive.show(); + } // Статус "На согласовании" + + }, { + key: 'buildAgreedStage', + value: function buildAgreedStage() { + console.log('Stage: agreed'); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + this.$stagesCount.parent().hide(); + this._renderStage('stage_approved_tmpl', true); + this.stages_elements.$approve.find('.js-help-text').hide(); + this.stages_elements.$reserve.find('.js-help-text').show(); + this.stages_elements.$reserve.show(); + this.buttons.btnReserve.show(); + this.buttons.btnsArbitration.show(); + this._renderStageReserved('reserved_tmpl'); + } // Статус "Согласован" + + }, { + key: 'buildProcessStage', + value: function buildProcessStage() { + console.log('Stage: in_process'); + this.buildAgreedStage(); + this.stages_elements.$reserve.find('.js-btnArbitration').hide(); + this.stages_elements.$works.show(); + this._renderStageInWork('work_in_process_tmpl'); + } // Статус "В процессе"/"Завершен"/"Закрыт" + + }, { + key: '_buildPage', + value: function _buildPage() { + // console.log("Build PAge"); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + if (this.data.stages.length == 0) { + this.buildStartStage(); + } else { + var stageStatus = this.data.stages[0].status; + // console.log('stageStatus = ', stageStatus); + this.STAGE_STATUSES[stageStatus](); + } + this._bindEvents(); + } + }, { + key: '_renderStage', + value: function _renderStage(template_name) { + var disable = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var i = 0; + this.$orderStagesContainer.html(""); + var _iteratorNormalCompletion = true; + var _didIteratorError = false; + var _iteratorError = undefined; + + try { + for (var _iterator = this.data.stages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { + var stage_data = _step.value; + + i++; + var stage = new _Stages.StageForm(this.$orderStagesContainer, { + orderId: this.orderId, stage_num: i, stage_status: STATUSES[stage_data.status], + type: 'update', template_name: template_name, data: stage_data + }); + if (disable) stage.disable(); + this.stages.push(stage); + } + } catch (err) { + _didIteratorError = true; + _iteratorError = err; + } finally { + try { + if (!_iteratorNormalCompletion && _iterator.return) { + _iterator.return(); + } + } finally { + if (_didIteratorError) { + throw _iteratorError; + } + } + } + + this.$stagesCount.val(i); + } + }, { + key: '_renderStageReserved', + value: function _renderStageReserved(template_name) { + var $container = this.stages_elements.$reserve.find('.stages-paid'); + $container.html(""); + this.stages_reserved = []; + // Нет незарезервированных Этапов + var has_not_reserved_stages = false; + var _iteratorNormalCompletion2 = true; + var _didIteratorError2 = false; + var _iteratorError2 = undefined; + + try { + for (var _iterator2 = this.data.stages[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { + var stage_data = _step2.value; + + if (stage_data.status == 'agreed') has_not_reserved_stages = true; + var stage = new _Stages.StageReserved($container, { + template_name: template_name, data: stage_data + }); + this.stages_reserved.push(stage); + } + } catch (err) { + _didIteratorError2 = true; + _iteratorError2 = err; + } finally { + try { + if (!_iteratorNormalCompletion2 && _iterator2.return) { + _iterator2.return(); + } + } finally { + if (_didIteratorError2) { + throw _iteratorError2; + } + } + } + + if (!has_not_reserved_stages) { + this.buttons.btnReserve.hide(); + this.stages_elements.$reserve.find('.js-help-text').hide(); + } + } + }, { + key: '_renderStageInWork', + value: function _renderStageInWork(template_name) { + /** + * Отрисовываем блок "Выволнение работы", включая "Выполненныа работа" и "Оставить отзыв" + */ + var $container = this.stages_elements.$works.find('#stagesWork'); + $container.html(""); + var all_closed = this.data.stages.every(function (el) { + return el.status == 'closed'; + }); + if (all_closed) { + this.stages_elements.$works.find('.titleStepss').html('3. Выполненная работа'); + this.stages_elements.$works.find('.js-btnArbitration').hide(); + this.stages_elements.$works.find('.js-help-text').hide(); + var _iteratorNormalCompletion3 = true; + var _didIteratorError3 = false; + var _iteratorError3 = undefined; + + try { + for (var _iterator3 = this.data.stages[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { + var stage_data = _step3.value; + + var stage = new _Stages.StageInWork($container, { + template_name: template_name, + data: stage_data, + note_text: 'Закройте этап или подробно опишите замечания в чате' + }); + this.stages_work.push(stage); + } + } catch (err) { + _didIteratorError3 = true; + _iteratorError3 = err; + } finally { + try { + if (!_iteratorNormalCompletion3 && _iterator3.return) { + _iterator3.return(); + } + } finally { + if (_didIteratorError3) { + throw _iteratorError3; + } + } + } + + if (!this.data.has_user_review) { + var btnReviewOpenModel = $(this.btnSendReviewTmpl()); + btnReviewOpenModel.unbind().on('click', this._onBtnReviewOpenModal.bind(this)); + // Если кнопка "Оставить отзыв" еще не добавлена - добавляем + if (!this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.append(btnReviewOpenModel); + } else { + if (this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.find('#send-review').remove(); + } + } else { + var _iteratorNormalCompletion4 = true; + var _didIteratorError4 = false; + var _iteratorError4 = undefined; + + try { + for (var _iterator4 = this.data.stages[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { + var _stage_data = _step4.value; + + if (_stage_data.status == 'closed') continue; + var _stage = new _Stages.StageInWork($container, { + template_name: template_name, data: _stage_data + }); + if (_stage_data.status == 'completed') { + var $btn = $(this.btnCompleteTmpl({ stage: _stage_data, text: 'Закрыть этап' })); + $container.html(); + $container.append($btn); + $btn.on('click', this._onBtnClose.bind(this, _stage)); + } + this.stages_work.push(_stage); + } + } catch (err) { + _didIteratorError4 = true; + _iteratorError4 = err; + } finally { + try { + if (!_iteratorNormalCompletion4 && _iterator4.return) { + _iterator4.return(); + } + } finally { + if (_didIteratorError4) { + throw _iteratorError4; + } + } + } + } + } + }, { + key: '_onLoadData', + value: function _onLoadData(json) { + this.data = json; + this._buildPage(); + } + }, { + key: '_changeNumStages', + value: function _changeNumStages(event) { + /** + * Изменяет кол-во этапов(stages) + */ + var newNumStages = parseInt($(event.target).val()); + if (newNumStages < 1 || isNaN(newNumStages)) { + newNumStages = 1; + this.$stagesCount.val(newNumStages); + } + var currentNumStages = $('.js-stage-form:not(.remove-stages-form)').length; + if (currentNumStages == newNumStages) return; + if (currentNumStages > newNumStages) { + var _iteratorNormalCompletion5 = true; + var _didIteratorError5 = false; + var _iteratorError5 = undefined; + + try { + for (var _iterator5 = this.stages.slice().reverse()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) { + var stage = _step5.value; + + if (stage.remove()) { + var index = this.stages.indexOf(stage); + if (index >= 0) { + this.stages.splice(index, 1); + } + } + currentNumStages--; + if (currentNumStages == newNumStages) break; + } + } catch (err) { + _didIteratorError5 = true; + _iteratorError5 = err; + } finally { + try { + if (!_iteratorNormalCompletion5 && _iterator5.return) { + _iterator5.return(); + } + } finally { + if (_didIteratorError5) { + throw _iteratorError5; + } + } + } + } else { + var _iteratorNormalCompletion6 = true; + var _didIteratorError6 = false; + var _iteratorError6 = undefined; + + try { + for (var _iterator6 = this.stages.slice()[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) { + var _stage3 = _step6.value; + + if (_stage3.type == 'remove') { + _stage3.restore(); + } else continue; + currentNumStages++; + if (currentNumStages == newNumStages) break; + } + } catch (err) { + _didIteratorError6 = true; + _iteratorError6 = err; + } finally { + try { + if (!_iteratorNormalCompletion6 && _iterator6.return) { + _iterator6.return(); + } + } finally { + if (_didIteratorError6) { + throw _iteratorError6; + } + } + } + + while (currentNumStages < newNumStages) { + currentNumStages++; + var _stage2 = new _Stages.StageForm(this.$orderStagesContainer, { orderId: this.orderId, stage_num: currentNumStages, type: 'new', template_name: 'stage_tmpl' }); + this.stages.push(_stage2); + } + } + } //При изменении кол-ва этапов + + }, { + key: '_bindEvents', + value: function _bindEvents() { + var self = this; + this.buttons.btnApprove.unbind().on("click", this._onBtnApprove.bind(self)); + this.buttons.btnChange.unbind().on("click", this._onBtnChange.bind(self)); + this.buttons.btnToArchive.unbind().on("click", this._onBtnAToArchive.bind(self)); + this.buttons.btnReserve.unbind().on("click", this._onBtnReserve.bind(self)); + this.buttons.btnsArbitration.unbind().on("click", this._onBtnArbitration.bind(self)); + this.buttons.btnSendReview.unbind().on("click", this._onBtnSendReview.bind(self)); + $('#paymentfromSite').unbind().on('click', this._onBtnPaymentFromSite.bind(self)); + $("#reserve-stage-modal").find('#stage-num').unbind().on('change', function (event) { + // console.log("select stage cost = ", self.stages[this.value - 1].data.cost); + $("#reserve-stage-modal").find('#stage-cost').html(self.stages[this.value - 1].data.cost); + }); + } + + // BINDS + + }, { + key: '_onBtnApprove', + value: function _onBtnApprove(event) { + var _this = this; + + event.preventDefault(); + var self = this; + if (!this.stages.every(function (el) { + return el.is_valid(); + })) { + console.error('Не все поля форм валидны'); + return; + } + // При выполнении всех ajax запросов + Promise.all(this.stages.map(function (el) { + return el.sendAjax_approve(); + })).then(function () { + _this.buttons.btnApprove.hide(); + _this.buttons.btnChange.show(); + _this.buttons.btnToArchive.show(); + _this.$stagesCount.attr('disabled', true); + // var currentRecipentId = $(self).data('id'); + // var secureOrder = true; + // + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0423\u0441\u043B\u043E\u0432\u0438\u044F \u0437\u0430\u043A\u0430\u0437\u0430 ' + self.orderName + ' \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u044B \u043D\u0430 \u0441\u043E\u0433\u043B\u0430\u0441\u043E\u0432\u0430\u043D\u0438\u0435'; + console.log("Send-WS Отправить на согласование"); + socket.send_stages_approve(message); + //TODO: раскомментировать дурацкое окно + // $('#popupOk').modal('show'); + // }) + }); + } // "Отправить на согласование" + + }, { + key: '_onBtnChange', + value: function _onBtnChange(event) { + var _this2 = this; + + event.preventDefault(); + var self = this; + Promise.all(this.stages.map(function (el) { + return el.sendAjax_change(); + })).then(function () { + _this2.buttons.btnApprove.show(); + _this2.buttons.btnChange.hide(); + _this2.buttons.btnToArchive.hide(); + _this2.$stagesCount.attr('disabled', false); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0417\u0430\u043A\u0430\u0437 ' + self.orderName + ' \u043E\u0442\u043E\u0437\u0432\u0430\u043D \u0434\u043B\u044F \u0432\u043D\u0435\u0441\u0435\u043D\u0438\u044F \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439'; + console.log("Send-WS Внести изменения"); + socket.send_stages_approve(message); + }); + } // "Внести изменения" + + // TODO: test it + + }, { + key: '_onBtnAToArchive', + value: function _onBtnAToArchive(event) { + event.preventDefault(); + var self = this; + $.ajax({ + // async: false, + url: '/api/orders/' + this.orderId + '/', + type: 'DELETE', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + dataType: 'json' + }).done(function (json) { + console.log('delete complete'); + window.location.href = window.location.href.replace(getHash(), ""); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0417\u0430\u043A\u0430\u0437\u0430 ' + self.orderName + ' \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D \u0432 \u0430\u0440\u0445\u0438\u0432'; + console.log("Send-WS Отправить в архив"); + socket.send_stages_approve(message); + }).fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + }); + } // "Отказаться и отправить в архив" + + }, { + key: '_onBtnReserve', + value: function _onBtnReserve(event) { + var self = this; + event.preventDefault(); + // Set modal-window params + var $modal = $("#reserve-stage-modal"); + var total_cost = this.stages.map(function (el) { + return parseInt(el.data.cost); + }).reduce(function (a, b) { + return a + b; + }, 0); + // console.log('total cost = ', total_cost); + $modal.find('#total-cost').html(total_cost); + + var $select_stageNum = $modal.find('#stage-num'); + $select_stageNum.find('option').remove().end(); + var _iteratorNormalCompletion7 = true; + var _didIteratorError7 = false; + var _iteratorError7 = undefined; + + try { + for (var _iterator7 = this.stages[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) { + var stage = _step7.value; + + if (stage.data.is_paid) continue; + $select_stageNum.append(''); + } + // let $stage_cost = $modal.find('#stage-cost'); + // $stage_cost.html(self.stages[this.value - 1].data.cost); + } catch (err) { + _didIteratorError7 = true; + _iteratorError7 = err; + } finally { + try { + if (!_iteratorNormalCompletion7 && _iterator7.return) { + _iterator7.return(); + } + } finally { + if (_didIteratorError7) { + throw _iteratorError7; + } + } + } + + $modal.find('#stage-num').trigger('change'); + + $modal.modal('show'); + } // "Зарезервировать" --> Открывает модальное окно для резервирования + + }, { + key: '_onBtnPaymentFromSite', + value: function _onBtnPaymentFromSite(event) { + var self = this; + event.preventDefault(); + var $modal = $("#reserve-stage-modal"); + var sum = void 0, + stages_id = void 0; + if ($modal.find('input[name=choice_way]:checked').val() == 'all_stages') { + sum = $modal.find('#total-cost').html(); + stages_id = this.stages.map(function (el) { + return el.data.id; + }); + } else { + sum = $modal.find('#stage-cost').html(); + var num_stage = $modal.find('#stage-num').val() - 1; + stages_id = [this.stages[num_stage].data.id]; + } + $.ajax({ + url: '/wallets/payfromscore/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: { + sum: sum, + stages_id: stages_id.join(';') + }, + dataType: 'json', + success: function success(json) { + // console.log('success pay stage, json ', json); + $("#reserve-stage-modal").modal('toggle'); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0417\u0430\u043A\u0430\u0437\u0447\u0438\u043A \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043E\u0432\u0430\u043B \u0441\u0443\u043C\u043C\u0443 \u0434\u043B\u044F \u044D\u0442\u0430\u043F\u043E\u0432'; + console.log("Send-WS Оплата Этапа/Этапов"); + socket.send_stages_approve(message); + self.redraw(); + }, + error: function error(xhr) { + console.log('error pay stage, json', xhr.responseJSON); + $.jGrowl(xhr.responseJSON.message_error); + } + }); + } // Оплата с сайта(Счет на Proekton) + + }, { + key: '_onBtnClose', + value: function _onBtnClose(stage, event) { + event.preventDefault(); + var self = this; + stage.sendAjax_close().then(function (json) { + console.log("Этап закрыт успешно"); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u0417\u0430\u043A\u0430\u0437\u0447\u0438\u043A \u0437\u0430\u043A\u0440\u044B\u043B \u044D\u0442\u0430\u043F ' + json.name; + console.log("Send-WS Оплата Этапа/Этапов"); + socket.send_stages_approve(message); + self.redraw(); + }).catch(function (xhr) { + console.log("При закрытии этапа произошла ошибка -->", xhr); + }); + } // "Закрыть этап" + + }, { + key: '_onBtnReviewOpenModal', + value: function _onBtnReviewOpenModal(event) { + event.preventDefault(); + $('#review-add').modal('show'); + } // Открыть модальное окно "Оставить отзыв" + + }, { + key: '_onBtnSendReview', + value: function _onBtnSendReview(event) { + event.preventDefault(); + var self = this; + $('#projectReviewId').val(this.projectId); + $('#targetContractorId').val(this.recipentId); + var formData = $("#review-adds-form").serialize(); + $.ajax({ + url: '/api/reviews/', + type: 'POST', + beforeSend: function beforeSend(xhr) { + xhr.setRequestHeader("X-CSRFToken", (0, _utils.getCookie)('csrftoken')); + }, + data: formData, + dataType: 'json', + success: function success(json) { + $('#review-add').modal('hide'); + var message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = '\u041E\u0442\u0437\u044B\u0432 \u043D\u0430 \u0437\u0430\u043A\u0430\u0437 ' + self.orderName + ' \u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D'; + console.log("Send-WS Оставить отзыв"); + socket.send_stages_approve(message); + window.location = '/chat/#order'; + location.reload(); + // $("a[href='#tab2']").trigger('click'); + }, + error: function error(e) { + console.log('error'); + console.log(e); + } + }); + } // "Оставить отзыв" + + + }, { + key: '_onBtnArbitration', + value: function _onBtnArbitration(event) { + event.preventDefault(); + $("#arbitration-add").modal('show'); + } // "Обратиться в арбитраж" + + }, { + key: '_onLoadDataError', + value: function _onLoadDataError(error) { + console.log("Error loading data -->", error); + } + }]); + + return StagesController; + }(); + + exports.StagesController = StagesController; + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/assets/js/build/contractor_filter.js b/assets/js/build/contractor_filter.js index 9c2e0fd..b2ec298 100644 --- a/assets/js/build/contractor_filter.js +++ b/assets/js/build/contractor_filter.js @@ -40,19 +40,20 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _custom_check = __webpack_require__(1); + var _custom_check = __webpack_require__(27); - var _extended_field = __webpack_require__(2); + var _extended_field = __webpack_require__(28); - var _ajax_set_filter = __webpack_require__(3); + var _ajax_set_filter = __webpack_require__(29); - var _filter_toggle = __webpack_require__(4); + var _filter_toggle = __webpack_require__(30); function paginateTo(pageNum) { var $form = $('#filter-form'); @@ -73,7 +74,8 @@ }); /***/ }, -/* 1 */ + +/***/ 27: /***/ function(module, exports) { "use strict"; @@ -102,7 +104,8 @@ exports.customCheckInit = customCheckInit; /***/ }, -/* 2 */ + +/***/ 28: /***/ function(module, exports) { 'use strict'; @@ -132,7 +135,8 @@ exports.extendedFieldInit = extendedFieldInit; /***/ }, -/* 3 */ + +/***/ 29: /***/ function(module, exports) { 'use strict'; @@ -195,7 +199,8 @@ exports.modUrl = modUrl; /***/ }, -/* 4 */ + +/***/ 30: /***/ function(module, exports) { 'use strict'; @@ -225,4 +230,5 @@ exports.filterToggleInit = filterToggleInit; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/create_project.js b/assets/js/build/create_project.js index a1c6db0..4ef741f 100644 --- a/assets/js/build/create_project.js +++ b/assets/js/build/create_project.js @@ -46,23 +46,23 @@ 'use strict'; - var _file_upload = __webpack_require__(5); + var _file_upload = __webpack_require__(31); - var _extended_field = __webpack_require__(2); + var _extended_field = __webpack_require__(28); - var _custom_check = __webpack_require__(1); + var _custom_check = __webpack_require__(27); - var _read_more = __webpack_require__(7); + var _read_more = __webpack_require__(32); - var _only_one_checkbox = __webpack_require__(8); + var _only_one_checkbox = __webpack_require__(33); - var _popups = __webpack_require__(9); + var _popups = __webpack_require__(34); - var _scroll_on_required = __webpack_require__(10); + var _scroll_on_required = __webpack_require__(35); - var _ajax_registration = __webpack_require__(11); + var _ajax_registration = __webpack_require__(36); - var _test_seeds = __webpack_require__(12); + var _test_seeds = __webpack_require__(37); function showHideRealry() { var check = $('#checkbox-sb-realty'); @@ -97,7 +97,76 @@ }); /***/ }, -/* 1 */ +/* 1 */, +/* 2 */, +/* 3 */ +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + if (cookie.substring(0, name.length + 1) == name + '=') { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + function humanFileSize(bytes, si) { + var thresh = si ? 1000 : 1024; + + if (Math.abs(bytes) < thresh) return bytes + ' B'; + + var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + + var u = -1; + + do { + bytes /= thresh; + ++u; + } while (Math.abs(bytes) >= thresh && u < units.length - 1); + + return bytes.toFixed(1) + ' ' + units[u]; + } + + exports.humanFileSize = humanFileSize; + exports.getCookie = getCookie; + +/***/ }, +/* 4 */, +/* 5 */, +/* 6 */, +/* 7 */, +/* 8 */, +/* 9 */, +/* 10 */, +/* 11 */, +/* 12 */, +/* 13 */, +/* 14 */, +/* 15 */, +/* 16 */, +/* 17 */, +/* 18 */, +/* 19 */, +/* 20 */, +/* 21 */, +/* 22 */, +/* 23 */, +/* 24 */, +/* 25 */, +/* 26 */, +/* 27 */ /***/ function(module, exports) { "use strict"; @@ -126,7 +195,7 @@ exports.customCheckInit = customCheckInit; /***/ }, -/* 2 */ +/* 28 */ /***/ function(module, exports) { 'use strict'; @@ -156,9 +225,9 @@ exports.extendedFieldInit = extendedFieldInit; /***/ }, -/* 3 */, -/* 4 */, -/* 5 */ +/* 29 */, +/* 30 */, +/* 31 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -168,7 +237,7 @@ }); exports.fileUploadInit = undefined; - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); function fileUploadInit() { var $fileUploadContainer = $('#fileUploadContainer'); @@ -206,51 +275,7 @@ exports.fileUploadInit = fileUploadInit; /***/ }, -/* 6 */ -/***/ function(module, exports) { - - 'use strict'; - - Object.defineProperty(exports, "__esModule", { - value: true - }); - function getCookie(name) { - var cookieValue = null; - if (document.cookie && document.cookie != '') { - var cookies = document.cookie.split(';'); - for (var i = 0; i < cookies.length; i++) { - var cookie = jQuery.trim(cookies[i]); - if (cookie.substring(0, name.length + 1) == name + '=') { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; - } - - function humanFileSize(bytes, si) { - var thresh = si ? 1000 : 1024; - - if (Math.abs(bytes) < thresh) return bytes + ' B'; - - var units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; - - var u = -1; - - do { - bytes /= thresh; - ++u; - } while (Math.abs(bytes) >= thresh && u < units.length - 1); - - return bytes.toFixed(1) + ' ' + units[u]; - } - - exports.humanFileSize = humanFileSize; - exports.getCookie = getCookie; - -/***/ }, -/* 7 */ +/* 32 */ /***/ function(module, exports) { "use strict"; @@ -265,18 +290,12 @@ $target.siblings(".complete").toggle(); $target.toggleClass("less"); }); - - // $(".more").toggle(function () { - // $(this).text("less..").siblings(".complete").show(); - // }, function () { - // $(this).text("more..").siblings(".complete").hide(); - // }); } exports.readMoreInit = readMoreInit; /***/ }, -/* 8 */ +/* 33 */ /***/ function(module, exports) { "use strict"; @@ -307,7 +326,7 @@ exports.onlyOneCheckboxInit = onlyOneCheckboxInit; /***/ }, -/* 9 */ +/* 34 */ /***/ function(module, exports) { 'use strict'; @@ -362,7 +381,7 @@ exports.addMessage = addMessage; /***/ }, -/* 10 */ +/* 35 */ /***/ function(module, exports) { 'use strict'; @@ -382,7 +401,7 @@ exports.scrollOnRequiredInit = scrollOnRequiredInit; /***/ }, -/* 11 */ +/* 36 */ /***/ function(module, exports) { 'use strict'; @@ -480,7 +499,7 @@ exports.ajaxRegistrationInit = ajaxRegistrationInit; /***/ }, -/* 12 */ +/* 37 */ /***/ function(module, exports) { "use strict"; diff --git a/assets/js/build/create_worksell.js b/assets/js/build/create_worksell.js index 2bfaada..1312f0f 100644 --- a/assets/js/build/create_worksell.js +++ b/assets/js/build/create_worksell.js @@ -40,21 +40,22 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _image_upload = __webpack_require__(13); + var _image_upload = __webpack_require__(38); - var _scroll_on_required = __webpack_require__(10); + var _scroll_on_required = __webpack_require__(35); - var _popups = __webpack_require__(9); + var _popups = __webpack_require__(34); - var _ajax_registration = __webpack_require__(11); + var _ajax_registration = __webpack_require__(36); - var _ajax_send_form_data = __webpack_require__(14); + var _ajax_send_form_data = __webpack_require__(39); $(function () { (0, _image_upload.imageUploadInit)(); @@ -67,12 +68,8 @@ }); /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */ + +/***/ 3: /***/ function(module, exports) { 'use strict'; @@ -116,9 +113,8 @@ exports.getCookie = getCookie; /***/ }, -/* 7 */, -/* 8 */, -/* 9 */ + +/***/ 34: /***/ function(module, exports) { 'use strict'; @@ -173,7 +169,8 @@ exports.addMessage = addMessage; /***/ }, -/* 10 */ + +/***/ 35: /***/ function(module, exports) { 'use strict'; @@ -193,7 +190,8 @@ exports.scrollOnRequiredInit = scrollOnRequiredInit; /***/ }, -/* 11 */ + +/***/ 36: /***/ function(module, exports) { 'use strict'; @@ -291,8 +289,8 @@ exports.ajaxRegistrationInit = ajaxRegistrationInit; /***/ }, -/* 12 */, -/* 13 */ + +/***/ 38: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -302,7 +300,7 @@ }); exports.imageUploadInit = undefined; - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); // function previewImg() { // let $fileUploadWidgets = $('.file-upload-widget'); @@ -371,7 +369,8 @@ // export {imageUploadInit, previewImg} /***/ }, -/* 14 */ + +/***/ 39: /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -381,7 +380,7 @@ }); exports.sendFormData = undefined; - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); function sendFormData(e) { e.preventDefault(); @@ -430,4 +429,5 @@ exports.sendFormData = sendFormData; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/custom_components.js b/assets/js/build/custom_components.js index 55dc7fe..b44253f 100644 --- a/assets/js/build/custom_components.js +++ b/assets/js/build/custom_components.js @@ -47,9 +47,9 @@ 'use strict'; - var _custom_select = __webpack_require__(15); + var _custom_select = __webpack_require__(40); - var _custom_check = __webpack_require__(1); + var _custom_check = __webpack_require__(27); $(function () { (0, _custom_select.customSelectInit)(); @@ -58,7 +58,7 @@ /***/ }, -/***/ 1: +/***/ 27: /***/ function(module, exports) { "use strict"; @@ -88,7 +88,7 @@ /***/ }, -/***/ 15: +/***/ 40: /***/ function(module, exports) { 'use strict'; diff --git a/assets/js/build/customer_profile.js b/assets/js/build/customer_profile.js index 1ace80c..aeffe42 100644 --- a/assets/js/build/customer_profile.js +++ b/assets/js/build/customer_profile.js @@ -40,19 +40,20 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _show_hide = __webpack_require__(16); + var _show_hide = __webpack_require__(41); - var _bootstrap_tabs = __webpack_require__(17); + var _bootstrap_tabs = __webpack_require__(42); - var _sort_by = __webpack_require__(18); + var _sort_by = __webpack_require__(43); - var _custom_check = __webpack_require__(1); + var _custom_check = __webpack_require__(27); $(function () { (0, _bootstrap_tabs.restoreTab)(); @@ -64,40 +65,8 @@ }); /***/ }, -/* 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(); - } - 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 */ +/***/ 3: /***/ function(module, exports) { 'use strict'; @@ -141,16 +110,38 @@ exports.getCookie = getCookie; /***/ }, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */ + +/***/ 27: +/***/ 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(); + } + + 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; + +/***/ }, + +/***/ 41: /***/ function(module, exports) { "use strict"; @@ -166,7 +157,8 @@ exports.toggler = toggler; /***/ }, -/* 17 */ + +/***/ 42: /***/ function(module, exports) { "use strict"; @@ -201,7 +193,8 @@ exports.restoreTab = restoreTab; /***/ }, -/* 18 */ + +/***/ 43: /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -211,7 +204,7 @@ }); exports.sortRealtyBy = undefined; - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); function sortRealtyBy(data, container_id) { console.log("sort_by = ", data); @@ -234,4 +227,5 @@ exports.sortRealtyBy = sortRealtyBy; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/debugUtilsInit.js b/assets/js/build/debugUtilsInit.js new file mode 100644 index 0000000..ce4e128 --- /dev/null +++ b/assets/js/build/debugUtilsInit.js @@ -0,0 +1,79 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 0: +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var _utils_debug = __webpack_require__(44); + + // DEBUG + window.print = {}; + window.print.ws_print = _utils_debug.ws_print; + +/***/ }, + +/***/ 44: +/***/ function(module, exports) { + + 'use strict'; + + Object.defineProperty(exports, "__esModule", { + value: true + }); + function ws_print() { + for (var _len = arguments.length, messages = Array(_len), _key = 0; _key < _len; _key++) { + messages[_key] = arguments[_key]; + } + + var message = messages.join(' '); + console.log('%c WS: ' + message, 'background: white; color: blue'); + } + + exports.ws_print = ws_print; + +/***/ } + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/home_page.js b/assets/js/build/home_page.js index 1043326..e6f7512 100644 --- a/assets/js/build/home_page.js +++ b/assets/js/build/home_page.js @@ -47,7 +47,7 @@ 'use strict'; - var _popupYoutube = __webpack_require__(19); + var _popupYoutube = __webpack_require__(45); $(function () { (0, _popupYoutube.popupYoutubeInit)(); @@ -55,7 +55,7 @@ /***/ }, -/***/ 19: +/***/ 45: /***/ function(module, exports) { 'use strict'; diff --git a/assets/js/build/init_contractor_filter.js b/assets/js/build/init_contractor_filter.js index 40e1cd2..d267aef 100644 --- a/assets/js/build/init_contractor_filter.js +++ b/assets/js/build/init_contractor_filter.js @@ -40,21 +40,22 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _SelectedContainer = __webpack_require__(20); + var _SelectedContainer = __webpack_require__(46); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); - var _NoTreeSelect = __webpack_require__(24); + var _NoTreeSelect = __webpack_require__(50); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); - var _TreeSelect = __webpack_require__(26); + var _TreeSelect = __webpack_require__(52); var _TreeSelect2 = _interopRequireDefault(_TreeSelect); @@ -120,26 +121,8 @@ }); /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */, -/* 17 */, -/* 18 */, -/* 19 */, -/* 20 */ + +/***/ 46: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -154,15 +137,15 @@ var _desc, _value, _class; // ` - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -394,7 +377,8 @@ exports.default = SelectedContainer; /***/ }, -/* 21 */ + +/***/ 47: /***/ function(module, exports) { "use strict"; @@ -549,7 +533,8 @@ exports.default = DataTree; /***/ }, -/* 22 */ + +/***/ 48: /***/ function(module, exports) { "use strict"; @@ -605,7 +590,8 @@ exports.default = NoTreeData; /***/ }, -/* 23 */ + +/***/ 49: /***/ function(module, exports) { "use strict"; @@ -689,7 +675,8 @@ // export {onBind}; /***/ }, -/* 24 */ + +/***/ 50: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -703,9 +690,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -766,7 +753,8 @@ exports.default = NoTreeSelect; /***/ }, -/* 25 */ + +/***/ 51: /***/ function(module, exports) { "use strict"; @@ -1317,7 +1305,8 @@ exports.AbsBaseSelect = AbsBaseSelect; /***/ }, -/* 26 */ + +/***/ 52: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1331,9 +1320,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); @@ -1442,4 +1431,5 @@ exports.default = TreeSelect; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/init_create_worksell.js b/assets/js/build/init_create_worksell.js index dc2922f..b101cd1 100644 --- a/assets/js/build/init_create_worksell.js +++ b/assets/js/build/init_create_worksell.js @@ -40,33 +40,34 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _SelectedContainer = __webpack_require__(20); + var _SelectedContainer = __webpack_require__(46); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); - var _SelectedContainerCreate = __webpack_require__(27); + var _SelectedContainerCreate = __webpack_require__(53); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); - var _NoTreeSelect = __webpack_require__(24); + var _NoTreeSelect = __webpack_require__(50); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); - var _TreeSelect = __webpack_require__(26); + var _TreeSelect = __webpack_require__(52); var _TreeSelect2 = _interopRequireDefault(_TreeSelect); - var _SingleTreeSelect = __webpack_require__(28); + var _SingleTreeSelect = __webpack_require__(54); var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect); - var _SelectOrCreate = __webpack_require__(29); + var _SelectOrCreate = __webpack_require__(55); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); @@ -167,26 +168,8 @@ }); /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */, -/* 17 */, -/* 18 */, -/* 19 */, -/* 20 */ + +/***/ 46: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -201,15 +184,15 @@ var _desc, _value, _class; // ` - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -441,7 +424,8 @@ exports.default = SelectedContainer; /***/ }, -/* 21 */ + +/***/ 47: /***/ function(module, exports) { "use strict"; @@ -596,7 +580,8 @@ exports.default = DataTree; /***/ }, -/* 22 */ + +/***/ 48: /***/ function(module, exports) { "use strict"; @@ -652,7 +637,8 @@ exports.default = NoTreeData; /***/ }, -/* 23 */ + +/***/ 49: /***/ function(module, exports) { "use strict"; @@ -736,7 +722,8 @@ // export {onBind}; /***/ }, -/* 24 */ + +/***/ 50: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -750,9 +737,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -813,7 +800,8 @@ exports.default = NoTreeSelect; /***/ }, -/* 25 */ + +/***/ 51: /***/ function(module, exports) { "use strict"; @@ -1364,7 +1352,8 @@ exports.AbsBaseSelect = AbsBaseSelect; /***/ }, -/* 26 */ + +/***/ 52: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1378,9 +1367,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); @@ -1489,7 +1478,8 @@ exports.default = TreeSelect; /***/ }, -/* 27 */ + +/***/ 53: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1505,11 +1495,11 @@ var _desc, _value, _class; - var _SelectedContainer2 = __webpack_require__(20); + var _SelectedContainer2 = __webpack_require__(46); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -1590,7 +1580,8 @@ exports.default = SelectedContainerCreate; /***/ }, -/* 28 */ + +/***/ 54: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1602,9 +1593,9 @@ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var _AbsBaseSelect = __webpack_require__(25); + var _AbsBaseSelect = __webpack_require__(51); - var _TreeSelect2 = __webpack_require__(26); + var _TreeSelect2 = __webpack_require__(52); var _TreeSelect3 = _interopRequireDefault(_TreeSelect2); @@ -1685,7 +1676,8 @@ exports.default = SingleTreeSelect; /***/ }, -/* 29 */ + +/***/ 55: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1699,9 +1691,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -1923,4 +1915,5 @@ exports.default = SelectOrCreate; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/init_customer_project_create.js b/assets/js/build/init_customer_project_create.js index 6fd9edd..c6ea8eb 100644 --- a/assets/js/build/init_customer_project_create.js +++ b/assets/js/build/init_customer_project_create.js @@ -40,33 +40,34 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _SelectedContainer = __webpack_require__(20); + var _SelectedContainer = __webpack_require__(46); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); - var _SelectedContainerCreate = __webpack_require__(27); + var _SelectedContainerCreate = __webpack_require__(53); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); - var _NoTreeSelect = __webpack_require__(24); + var _NoTreeSelect = __webpack_require__(50); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); - var _TreeSelect = __webpack_require__(26); + var _TreeSelect = __webpack_require__(52); var _TreeSelect2 = _interopRequireDefault(_TreeSelect); - var _SingleTreeSelect = __webpack_require__(28); + var _SingleTreeSelect = __webpack_require__(54); var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect); - var _SelectOrCreate = __webpack_require__(29); + var _SelectOrCreate = __webpack_require__(55); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); @@ -176,8 +177,10 @@ } else { //Если перешли со страницы профиля по кнопке "Добавить заказ" var id = window.location.hash.replace("#", ""); - if (id) sb_realty_top.setElementById(id); - select_realty.add(id); + if (id) { + sb_realty_top.setElementById(id); + select_realty.add(id); + } } }); select_realty.on("add", function (args) { @@ -212,26 +215,8 @@ }); /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */, -/* 17 */, -/* 18 */, -/* 19 */, -/* 20 */ + +/***/ 46: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -246,15 +231,15 @@ var _desc, _value, _class; // ` - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -486,7 +471,8 @@ exports.default = SelectedContainer; /***/ }, -/* 21 */ + +/***/ 47: /***/ function(module, exports) { "use strict"; @@ -641,7 +627,8 @@ exports.default = DataTree; /***/ }, -/* 22 */ + +/***/ 48: /***/ function(module, exports) { "use strict"; @@ -697,7 +684,8 @@ exports.default = NoTreeData; /***/ }, -/* 23 */ + +/***/ 49: /***/ function(module, exports) { "use strict"; @@ -781,7 +769,8 @@ // export {onBind}; /***/ }, -/* 24 */ + +/***/ 50: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -795,9 +784,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -858,7 +847,8 @@ exports.default = NoTreeSelect; /***/ }, -/* 25 */ + +/***/ 51: /***/ function(module, exports) { "use strict"; @@ -1409,7 +1399,8 @@ exports.AbsBaseSelect = AbsBaseSelect; /***/ }, -/* 26 */ + +/***/ 52: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1423,9 +1414,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); @@ -1534,7 +1525,8 @@ exports.default = TreeSelect; /***/ }, -/* 27 */ + +/***/ 53: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1550,11 +1542,11 @@ var _desc, _value, _class; - var _SelectedContainer2 = __webpack_require__(20); + var _SelectedContainer2 = __webpack_require__(46); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -1635,7 +1627,8 @@ exports.default = SelectedContainerCreate; /***/ }, -/* 28 */ + +/***/ 54: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1647,9 +1640,9 @@ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var _AbsBaseSelect = __webpack_require__(25); + var _AbsBaseSelect = __webpack_require__(51); - var _TreeSelect2 = __webpack_require__(26); + var _TreeSelect2 = __webpack_require__(52); var _TreeSelect3 = _interopRequireDefault(_TreeSelect2); @@ -1730,7 +1723,8 @@ exports.default = SingleTreeSelect; /***/ }, -/* 29 */ + +/***/ 55: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1744,9 +1738,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -1968,4 +1962,5 @@ exports.default = SelectOrCreate; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/init_modal_realty_edit.js b/assets/js/build/init_modal_realty_edit.js index cfa039c..40767ed 100644 --- a/assets/js/build/init_modal_realty_edit.js +++ b/assets/js/build/init_modal_realty_edit.js @@ -40,37 +40,38 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _SelectedContainer = __webpack_require__(20); + var _SelectedContainer = __webpack_require__(46); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); - var _SelectedContainerCreate = __webpack_require__(27); + var _SelectedContainerCreate = __webpack_require__(53); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); - var _NoTreeSelect = __webpack_require__(24); + var _NoTreeSelect = __webpack_require__(50); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); - var _TreeSelect = __webpack_require__(26); + var _TreeSelect = __webpack_require__(52); var _TreeSelect2 = _interopRequireDefault(_TreeSelect); - var _SingleTreeSelect = __webpack_require__(28); + var _SingleTreeSelect = __webpack_require__(54); var _SingleTreeSelect2 = _interopRequireDefault(_SingleTreeSelect); - var _SelectOrCreate = __webpack_require__(29); + var _SelectOrCreate = __webpack_require__(55); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } @@ -229,12 +230,8 @@ }); /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */ + +/***/ 3: /***/ function(module, exports) { 'use strict'; @@ -278,20 +275,8 @@ exports.getCookie = getCookie; /***/ }, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */, -/* 17 */, -/* 18 */, -/* 19 */, -/* 20 */ + +/***/ 46: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -306,15 +291,15 @@ var _desc, _value, _class; // ` - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -546,7 +531,8 @@ exports.default = SelectedContainer; /***/ }, -/* 21 */ + +/***/ 47: /***/ function(module, exports) { "use strict"; @@ -701,7 +687,8 @@ exports.default = DataTree; /***/ }, -/* 22 */ + +/***/ 48: /***/ function(module, exports) { "use strict"; @@ -757,7 +744,8 @@ exports.default = NoTreeData; /***/ }, -/* 23 */ + +/***/ 49: /***/ function(module, exports) { "use strict"; @@ -841,7 +829,8 @@ // export {onBind}; /***/ }, -/* 24 */ + +/***/ 50: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -855,9 +844,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -918,7 +907,8 @@ exports.default = NoTreeSelect; /***/ }, -/* 25 */ + +/***/ 51: /***/ function(module, exports) { "use strict"; @@ -1469,7 +1459,8 @@ exports.AbsBaseSelect = AbsBaseSelect; /***/ }, -/* 26 */ + +/***/ 52: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1483,9 +1474,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); @@ -1594,7 +1585,8 @@ exports.default = TreeSelect; /***/ }, -/* 27 */ + +/***/ 53: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1610,11 +1602,11 @@ var _desc, _value, _class; - var _SelectedContainer2 = __webpack_require__(20); + var _SelectedContainer2 = __webpack_require__(46); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -1695,7 +1687,8 @@ exports.default = SelectedContainerCreate; /***/ }, -/* 28 */ + +/***/ 54: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1707,9 +1700,9 @@ var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - var _AbsBaseSelect = __webpack_require__(25); + var _AbsBaseSelect = __webpack_require__(51); - var _TreeSelect2 = __webpack_require__(26); + var _TreeSelect2 = __webpack_require__(52); var _TreeSelect3 = _interopRequireDefault(_TreeSelect2); @@ -1790,7 +1783,8 @@ exports.default = SingleTreeSelect; /***/ }, -/* 29 */ + +/***/ 55: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1804,9 +1798,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -2028,4 +2022,5 @@ exports.default = SelectOrCreate; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/init_portfolio_create_edit.js b/assets/js/build/init_portfolio_create_edit.js index 120f626..c6dd2c7 100644 --- a/assets/js/build/init_portfolio_create_edit.js +++ b/assets/js/build/init_portfolio_create_edit.js @@ -40,29 +40,30 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _SelectedContainer = __webpack_require__(20); + var _SelectedContainer = __webpack_require__(46); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); - var _SelectedContainerCreate = __webpack_require__(27); + var _SelectedContainerCreate = __webpack_require__(53); var _SelectedContainerCreate2 = _interopRequireDefault(_SelectedContainerCreate); - var _NoTreeSelect = __webpack_require__(24); + var _NoTreeSelect = __webpack_require__(50); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); - var _TreeSelect = __webpack_require__(26); + var _TreeSelect = __webpack_require__(52); var _TreeSelect2 = _interopRequireDefault(_TreeSelect); - var _SelectOrCreate = __webpack_require__(29); + var _SelectOrCreate = __webpack_require__(55); var _SelectOrCreate2 = _interopRequireDefault(_SelectOrCreate); @@ -122,26 +123,8 @@ // import SingleTreeSelect from 'components/SingleTreeSelect' /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */, -/* 17 */, -/* 18 */, -/* 19 */, -/* 20 */ + +/***/ 46: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -156,15 +139,15 @@ var _desc, _value, _class; // ` - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -396,7 +379,8 @@ exports.default = SelectedContainer; /***/ }, -/* 21 */ + +/***/ 47: /***/ function(module, exports) { "use strict"; @@ -551,7 +535,8 @@ exports.default = DataTree; /***/ }, -/* 22 */ + +/***/ 48: /***/ function(module, exports) { "use strict"; @@ -607,7 +592,8 @@ exports.default = NoTreeData; /***/ }, -/* 23 */ + +/***/ 49: /***/ function(module, exports) { "use strict"; @@ -691,7 +677,8 @@ // export {onBind}; /***/ }, -/* 24 */ + +/***/ 50: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -705,9 +692,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -768,7 +755,8 @@ exports.default = NoTreeSelect; /***/ }, -/* 25 */ + +/***/ 51: /***/ function(module, exports) { "use strict"; @@ -1319,7 +1307,8 @@ exports.AbsBaseSelect = AbsBaseSelect; /***/ }, -/* 26 */ + +/***/ 52: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1333,9 +1322,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); @@ -1444,7 +1433,8 @@ exports.default = TreeSelect; /***/ }, -/* 27 */ + +/***/ 53: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1460,11 +1450,11 @@ var _desc, _value, _class; - var _SelectedContainer2 = __webpack_require__(20); + var _SelectedContainer2 = __webpack_require__(46); var _SelectedContainer3 = _interopRequireDefault(_SelectedContainer2); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -1545,8 +1535,8 @@ exports.default = SelectedContainerCreate; /***/ }, -/* 28 */, -/* 29 */ + +/***/ 55: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1560,9 +1550,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -1784,4 +1774,5 @@ exports.default = SelectOrCreate; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/init_worksell_filter.js b/assets/js/build/init_worksell_filter.js index 257de54..f31a639 100644 --- a/assets/js/build/init_worksell_filter.js +++ b/assets/js/build/init_worksell_filter.js @@ -40,21 +40,22 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _SelectedContainer = __webpack_require__(20); + var _SelectedContainer = __webpack_require__(46); var _SelectedContainer2 = _interopRequireDefault(_SelectedContainer); - var _NoTreeSelect = __webpack_require__(24); + var _NoTreeSelect = __webpack_require__(50); var _NoTreeSelect2 = _interopRequireDefault(_NoTreeSelect); - var _TreeSelect = __webpack_require__(26); + var _TreeSelect = __webpack_require__(52); var _TreeSelect2 = _interopRequireDefault(_TreeSelect); @@ -120,26 +121,8 @@ }); // ` /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */, -/* 11 */, -/* 12 */, -/* 13 */, -/* 14 */, -/* 15 */, -/* 16 */, -/* 17 */, -/* 18 */, -/* 19 */, -/* 20 */ + +/***/ 46: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -154,15 +137,15 @@ var _desc, _value, _class; // ` - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); - var _decorators = __webpack_require__(23); + var _decorators = __webpack_require__(49); var _decorators2 = _interopRequireDefault(_decorators); @@ -394,7 +377,8 @@ exports.default = SelectedContainer; /***/ }, -/* 21 */ + +/***/ 47: /***/ function(module, exports) { "use strict"; @@ -549,7 +533,8 @@ exports.default = DataTree; /***/ }, -/* 22 */ + +/***/ 48: /***/ function(module, exports) { "use strict"; @@ -605,7 +590,8 @@ exports.default = NoTreeData; /***/ }, -/* 23 */ + +/***/ 49: /***/ function(module, exports) { "use strict"; @@ -689,7 +675,8 @@ // export {onBind}; /***/ }, -/* 24 */ + +/***/ 50: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -703,9 +690,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _NoTreeData = __webpack_require__(22); + var _NoTreeData = __webpack_require__(48); var _NoTreeData2 = _interopRequireDefault(_NoTreeData); @@ -766,7 +753,8 @@ exports.default = NoTreeSelect; /***/ }, -/* 25 */ + +/***/ 51: /***/ function(module, exports) { "use strict"; @@ -1317,7 +1305,8 @@ exports.AbsBaseSelect = AbsBaseSelect; /***/ }, -/* 26 */ + +/***/ 52: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -1331,9 +1320,9 @@ var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; - var _AbsBaseSelect2 = __webpack_require__(25); + var _AbsBaseSelect2 = __webpack_require__(51); - var _DataTree = __webpack_require__(21); + var _DataTree = __webpack_require__(47); var _DataTree2 = _interopRequireDefault(_DataTree); @@ -1442,4 +1431,5 @@ exports.default = TreeSelect; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/portfolio_create_edit.js b/assets/js/build/portfolio_create_edit.js index 691fc28..54b253e 100644 --- a/assets/js/build/portfolio_create_edit.js +++ b/assets/js/build/portfolio_create_edit.js @@ -40,17 +40,18 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _image_upload = __webpack_require__(13); + var _image_upload = __webpack_require__(38); - var _scroll_on_required = __webpack_require__(10); + var _scroll_on_required = __webpack_require__(35); - var _ajax_send_form_data = __webpack_require__(14); + var _ajax_send_form_data = __webpack_require__(39); $(function () { (0, _image_upload.imageUploadInit)(); @@ -60,12 +61,8 @@ }); /***/ }, -/* 1 */, -/* 2 */, -/* 3 */, -/* 4 */, -/* 5 */, -/* 6 */ + +/***/ 3: /***/ function(module, exports) { 'use strict'; @@ -109,10 +106,8 @@ exports.getCookie = getCookie; /***/ }, -/* 7 */, -/* 8 */, -/* 9 */, -/* 10 */ + +/***/ 35: /***/ function(module, exports) { 'use strict'; @@ -132,9 +127,8 @@ exports.scrollOnRequiredInit = scrollOnRequiredInit; /***/ }, -/* 11 */, -/* 12 */, -/* 13 */ + +/***/ 38: /***/ function(module, exports, __webpack_require__) { 'use strict'; @@ -144,7 +138,7 @@ }); exports.imageUploadInit = undefined; - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); // function previewImg() { // let $fileUploadWidgets = $('.file-upload-widget'); @@ -213,7 +207,8 @@ // export {imageUploadInit, previewImg} /***/ }, -/* 14 */ + +/***/ 39: /***/ function(module, exports, __webpack_require__) { "use strict"; @@ -223,7 +218,7 @@ }); exports.sendFormData = undefined; - var _utils = __webpack_require__(6); + var _utils = __webpack_require__(3); function sendFormData(e) { e.preventDefault(); @@ -272,4 +267,5 @@ exports.sendFormData = sendFormData; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/project_filter.js b/assets/js/build/project_filter.js index 5a1d1e1..650c753 100644 --- a/assets/js/build/project_filter.js +++ b/assets/js/build/project_filter.js @@ -40,17 +40,18 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _custom_check = __webpack_require__(1); + var _custom_check = __webpack_require__(27); - var _extended_field = __webpack_require__(2); + var _extended_field = __webpack_require__(28); - var _ajax_set_filter = __webpack_require__(3); + var _ajax_set_filter = __webpack_require__(29); function paginateTo(pageNum) { var $form = $('#filter-form'); @@ -70,7 +71,8 @@ }); /***/ }, -/* 1 */ + +/***/ 27: /***/ function(module, exports) { "use strict"; @@ -99,7 +101,8 @@ exports.customCheckInit = customCheckInit; /***/ }, -/* 2 */ + +/***/ 28: /***/ function(module, exports) { 'use strict'; @@ -129,7 +132,8 @@ exports.extendedFieldInit = extendedFieldInit; /***/ }, -/* 3 */ + +/***/ 29: /***/ function(module, exports) { 'use strict'; @@ -192,4 +196,5 @@ exports.modUrl = modUrl; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/build/registration.js b/assets/js/build/registration.js index 47bfc2c..41b0ee2 100644 --- a/assets/js/build/registration.js +++ b/assets/js/build/registration.js @@ -47,7 +47,7 @@ 'use strict'; - var _popups = __webpack_require__(9); + var _popups = __webpack_require__(34); function checkHash() { // on load of the page: switch to the currently selected tab @@ -65,7 +65,7 @@ /***/ }, -/***/ 9: +/***/ 34: /***/ function(module, exports) { 'use strict'; diff --git a/assets/js/build/user_profile_edit.js b/assets/js/build/user_profile_edit.js index d022c14..5c9fe2d 100644 --- a/assets/js/build/user_profile_edit.js +++ b/assets/js/build/user_profile_edit.js @@ -47,13 +47,13 @@ 'use strict'; - var _avatar_upload = __webpack_require__(30); + var _avatar_upload = __webpack_require__(56); - var _bootstrap_tabs = __webpack_require__(17); + var _bootstrap_tabs = __webpack_require__(42); - var _user_check_statuses = __webpack_require__(31); + var _user_check_statuses = __webpack_require__(57); - var _custom_select = __webpack_require__(15); + var _custom_select = __webpack_require__(40); $(function () { (0, _avatar_upload.avatarUploadInit)(); @@ -64,7 +64,7 @@ /***/ }, -/***/ 15: +/***/ 40: /***/ function(module, exports) { 'use strict'; @@ -108,7 +108,7 @@ /***/ }, -/***/ 17: +/***/ 42: /***/ function(module, exports) { "use strict"; @@ -144,7 +144,7 @@ /***/ }, -/***/ 30: +/***/ 56: /***/ function(module, exports) { 'use strict'; @@ -197,7 +197,7 @@ /***/ }, -/***/ 31: +/***/ 57: /***/ function(module, exports) { 'use strict'; diff --git a/assets/js/build/worksell_filter.js b/assets/js/build/worksell_filter.js index 9c2e0fd..b2ec298 100644 --- a/assets/js/build/worksell_filter.js +++ b/assets/js/build/worksell_filter.js @@ -40,19 +40,20 @@ /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ -/******/ ([ -/* 0 */ +/******/ ({ + +/***/ 0: /***/ function(module, exports, __webpack_require__) { 'use strict'; - var _custom_check = __webpack_require__(1); + var _custom_check = __webpack_require__(27); - var _extended_field = __webpack_require__(2); + var _extended_field = __webpack_require__(28); - var _ajax_set_filter = __webpack_require__(3); + var _ajax_set_filter = __webpack_require__(29); - var _filter_toggle = __webpack_require__(4); + var _filter_toggle = __webpack_require__(30); function paginateTo(pageNum) { var $form = $('#filter-form'); @@ -73,7 +74,8 @@ }); /***/ }, -/* 1 */ + +/***/ 27: /***/ function(module, exports) { "use strict"; @@ -102,7 +104,8 @@ exports.customCheckInit = customCheckInit; /***/ }, -/* 2 */ + +/***/ 28: /***/ function(module, exports) { 'use strict'; @@ -132,7 +135,8 @@ exports.extendedFieldInit = extendedFieldInit; /***/ }, -/* 3 */ + +/***/ 29: /***/ function(module, exports) { 'use strict'; @@ -195,7 +199,8 @@ exports.modUrl = modUrl; /***/ }, -/* 4 */ + +/***/ 30: /***/ function(module, exports) { 'use strict'; @@ -225,4 +230,5 @@ exports.filterToggleInit = filterToggleInit; /***/ } -/******/ ]); \ No newline at end of file + +/******/ }); \ No newline at end of file diff --git a/assets/js/src/chat/BINDS.js b/assets/js/src/chat/BINDS.js new file mode 100644 index 0000000..025478d --- /dev/null +++ b/assets/js/src/chat/BINDS.js @@ -0,0 +1,445 @@ +import {getCookie} from '../utils' +import {onClickCardWithCount} from './messageCounters' +import {loadTemplate} from './loaders' + +function dialog(message, yesCallback, notCallback) { + $("#dialog_delete .modal-title").html(message); + $("#dialog_delete").modal('show'); + $("#btnYes").click(function (e) { + e.preventDefault(); + yesCallback(); + $("#dialog_delete").modal('hide'); + }); + $("#btnNot").click(function (e) { + e.preventDefault(); + notCallback(); + $("#dialog_delete").modal('hide'); + }); +} + +function bindOrders() { + $('.order-block').on('click', function (event) { + event.preventDefault(); + let $this = $(this); + onClickCardWithCount($this); + $('.order-block').each(function (i, v) { + $(v).removeClass('orAct'); + }); + $this.addClass('orAct'); + let orderId = $this.data('id'); + let projectId = $this.data('project-id'); + let recipentId = $this.data('recipent-id'); + let orderName = $this.data('order-name'); + var secureOrder = $(this).data('secure-deal'); + secureOrder = Boolean(secureOrder); + window.location.hash = `order${orderId}`; + + $("#chat-order-add #orderId").val(orderId); + $("#add-form-order-note #orderNote").val(orderId); + $("#orderArbitrationId").val(orderId); + $("#projectReviewId").val(projectId); + $("#reserve-button").attr('data-order-id', orderId); + + $("#chat-order-add #recipentId").val(recipentId); + window.chatController.create(orderId, projectId, recipentId, orderName, secureOrder); + }); + $('.order-block .dimovChat').on('click', function (event) { + event.preventDefault(); + event.stopPropagation(); + // console.log('click on tr'); + }); +} + +function bindTeams() { + $('.team-block').on('click', function () { + onClickCardWithCount($(this)); + $('.team-order-block, .team-block').each(function () { + $(this).removeClass('orAct'); + }); + $(this).addClass('orAct'); + + var teamIds = ''; + $.each($(this).find('.team-chat-user'), function (i, v) { + teamIds += $(this).attr('data-id') + ";"; + }); + $("#team-chat-form #teamIds").val(teamIds); + + var inbox = document.getElementById('message-chat-team-space'); + inbox.innerHTML = ''; + + var docList = document.getElementById('documentTeamSpace'); + docList.innerHTML = ''; + + var teamId = $(this).attr('data-team-id'); + location.hash = '#myteam' + teamId; + + // var newCount = parseInt($("#count-tab-team").text()); + // var currNewCount = parseInt($(".team-count-" + teamId).text()); + // var resCount = newCount - currNewCount; + // $("#count-tab-team").text(resCount); + $(".team-count-" + teamId).text(0) + + $("#team-chat-form #teamId").val(teamId); + $("#add-form-team-note #teamNote").val(teamId); + $("#team-chat-form #recipentTeamId").val(""); + $("#team-chat-form #orderTeamId").val(""); + $("#add-form-team-note #orderNote").val(""); + + $.ajax({ + url: '/api/message', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: {'team': teamId, 'order__isnull': 'true'}, + dataType: 'json', + success: function (json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
    ' + + '

    ' + senderName + '

    ' + v.created + '
    ' + + '

    ' + v.text + '

    '; + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: { + 'team': teamId, + 'is_delete': false, + 'is_send': true, + }, + dataType: 'json', + success: function (json) { + $.each(json.results, function (i, v) { + docList.innerHTML += '
  • ' + v.file + '
  • '; + }); + }, + error: function (e) { + console.log(e); + } + }); + + $.ajax({ + url: '/api/note/', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: {'team': teamId}, + dataType: 'json', + success: function (json) { + // console.log(json.results); + var noteHtmlInbox = ''; + var note_tmpl = loadTemplate('note_tmpl'); + $.each(json.results, function (i, v) { + noteHtmlInbox += note_tmpl({text: v.text}); + + }); + $(".team-notes-block").html(noteHtmlInbox); + } + }); + + }); +} + +function bindArbitrationSend() { + // TODO: Test it + $('#order-arbitration-add').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + var formData = $("#arbitration-add-form").serialize(); + $.ajax({ + url: '/projects/arbitration/create/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: formData, + dataType: 'json', + success: function (json) { + // console.log(json); + $("#arbitration-add").modal('hide'); + $.jGrowl("Обращение в арбитраж добавлено", { + life: 4000 + }); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + }); +} + +function bindOnTabs() { + /** + * Биндит обработчики на Закладки + */ + $('a[data-toggle="tab"]').unbind().on('show.bs.tab', function (e) { + // console.log("TAB!"); + var activeTab = $(this).attr('href').substring(1); + var liveHash = URI(location.href).hash(); + + switch (activeTab) { + case 'tab1': + setTimeout(function () { + if (liveHash.indexOf("#user") != -1) { + var userHashId = liveHash.replace("#user", ""); + $("#userBlock" + userHashId).trigger('click'); + } else { + $(".user-block").first().trigger('click'); + } + }, 100); + break; + + case 'tab2': + // console.log("tab2"); + setTimeout(function () { + if (liveHash.indexOf("#order") != -1) { + var ordHashId = liveHash.replace("#order", ""); + $("#orderBlock" + ordHashId).trigger('click'); + } else { + $(".order-block").first().trigger('click'); + } + }, 100); + break; + + case 'tab3': + setTimeout(function () { + // console.log("on active TAB team"); + if (liveHash.indexOf("#teamorder") != -1) { + var teamHashId = liveHash.replace("#teamorder", ""); + $("#teamOrderBlock" + teamHashId).trigger('click'); + } else if (liveHash.indexOf("#myteam") != -1) { + var teamHashId = liveHash.replace("#myteam", ""); + $("#teamMyBlock" + teamHashId).trigger('click'); + } else { + var firstTeamBlock = $(".team-block").first(); + var firstTeamOrder = $(".team-order-block").first(); + if (firstTeamOrder.length == 1) { + firstTeamOrder.trigger('click'); + } else if (firstTeamBlock.length == 1) { + firstTeamBlock.trigger('click'); + } + } + }, 100); + + } + + }); +} + +function bindUserContacts() { + $(".conMess").click('on', function (e) { + e.preventDefault(); + e.stopPropagation(); + + var userId = $(this).attr('data-id'); + $.ajax({ + url: '/api/users/' + userId + '/', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + success: function (data) { + var outTable = ''; + if (data.username) { + outTable += 'Ник' + data.username + ''; + } + + if (data.fio) { + outTable += 'Ф.И.О' + data.fio + ''; + } + if (data.skype) { + outTable += 'Skype' + data.skype + ''; + } + + if (data.website) { + outTable += 'Сайт' + data.website + ''; + } + + if (data.phone) { + outTable += 'Телефон' + data.phone + ''; + } + + $("#contact-info table").html(outTable); + $("#contact-info").modal('show'); + // console.log(data); + }, + error: function (e, jqxhr) { + console.log(e); + } + }); + }); +} + +function bindGetUserMessages() { + $('.user-block').on('click', function () { + onClickCardWithCount($(this)); + // var newCount = parseInt($("#count-tab-contact").text()); + var contactId = $(this).attr('data-id'); + location.hash = '#user' + contactId; + $("#contact-chat-form #recipentContactId").val(contactId); + $("#add-form-contractor-note #recipentNoteContractor").val(contactId); + + $('.user-block').each(function () { + $(this).removeClass('mesAct'); + }); + + $(this).addClass('mesAct'); + var inbox = document.getElementById('message-chat-space'); + var sumSenderRecipent = parseInt(userId) + parseInt(contactId); + + $("#message-chat-space").removeClass().addClass("contact-space" + sumSenderRecipent); + // var currNewCount = parseInt($(".contact-count-" + sumSenderRecipent).text()); + // var resCount = newCount - currNewCount; + // $("#count-tab-contact").text(resCount); + $(".contact-count-" + sumSenderRecipent).text(0); + var docList = document.getElementById('documentSpace'); + inbox.innerHTML = ''; + docList.innerHTML = ''; + + $.ajax({ + url: '/api/message', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId + }, + dataType: 'json', + success: function (json) { + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + if (v.sender.id == contactId) { + senderName = v.sender.username; + className = ''; + } + inbox.innerHTML += '
    ' + + '

    ' + senderName + '

    ' + v.created + '
    ' + + '

    ' + v.text + '

    '; + }); + var height = inbox.scrollHeight; + inbox.scrollTop = height; + } + }); + + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId, + 'is_delete': false, + 'is_send': true, + }, + dataType: 'json', + + success: function (json) { + // console.log(json); + + $.each(json.results, function (i, v) { + docList.innerHTML += '
  • ' + v.file + '
  • '; + }); + }, + error: function (e) { + console.log(e); + } + }); + + $.ajax({ + url: '/api/note/', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: { + 'operand': 'in', + 'sender_id': userId, + 'recipent_id': contactId + }, + dataType: 'json', + success: function (json) { + // console.log(json.results); + var noteHtmlInbox = ''; + var note_tmpl = loadTemplate('note_tmpl'); + $.each(json.results, function (i, v) { + noteHtmlInbox += note_tmpl({text: v.text}); + }); + $(".contractor-notes-block").html(noteHtmlInbox); + } + }); + + }); +} + +function bindDeleteContact() { + $('.deleteMess').on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + + var senderId = userId; + var recipentId = $(this).attr('data-recipent-id'); + var _this = $(this); + + dialog("Вы действительно хотите удалить сообщения этого пользователя?", + function () { + $.ajax({ + url: '/chat/messages_delete/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: {'sender_id': senderId, 'recipent_id': recipentId}, + dataType: 'json', + success: function (json) { + + if (json.status == 'ok') { + _this.parent().remove(); + $("#message-chat-space").html(""); + } + + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + }.bind(null, senderId, recipentId, _this), + function () { + }); + + + }); +} + +export { + bindOrders, + bindArbitrationSend, + bindOnTabs, + bindUserContacts, + bindGetUserMessages, + bindTeams, + bindDeleteContact, +} \ No newline at end of file diff --git a/assets/js/src/chat/ChatContractorPageController.js b/assets/js/src/chat/ChatContractorPageController.js new file mode 100644 index 0000000..6e18d8c --- /dev/null +++ b/assets/js/src/chat/ChatContractorPageController.js @@ -0,0 +1 @@ +import {StagesController} from './StagesContractorController' import {MessagesController} from './MessagesControllers' import {DocumentsController} from './DocumentsControllers' class ChatPageController { constructor() { let self = this; console.log("NEW CONTRACTOR ChatPageController"); this.statesController = undefined; this.messagesController = undefined; this.documentsController = undefined; // TODO: не забыть! // $('.order-block').on('click', function (event) { // console.log("CLICK!!!"); // event.preventDefault(); // let $this = $(this); // $('.order-block').each(function (i, v) { // $(v).removeClass('orAct'); // }); // $this.addClass('orAct'); // let orderId = $this.data('id'); // let projectId = $this.data('project-id'); // let recipentId = $this.data('recipent-id'); // let orderName = $this.data('order-name'); // // console.log('orderId = ', orderId); // new StagesController(orderId, projectId, recipentId, orderName); // new MessagesController(orderId); // window.location.hash = `order${orderId}`; // // $("#chat-order-add #orderId").val(orderId); // $("#add-form-order-note #orderNote").val(orderId); // $("#orderArbitrationId").val(orderId); // $("#projectReviewId").val(projectId); // // console.log("recipentId = ", recipentId); // $("#chat-order-add #recipentId").val(recipentId); // $("#targetCustomerId").val(recipentId); // $("#add-form-order-note #recipentNote").val(recipentId); // // }); // $('.order-block .dimovChat').on('click', function (event) { // event.preventDefault(); // event.stopPropagation(); // // TODO: доделать сворачивание/разворачивание блока // // console.log('click on tr'); // }); } create(orderId, projectId, recipentId, orderName, secureOrder) { this.statesController = new StagesController(orderId, projectId, recipentId, orderName, secureOrder); this.messagesController = new MessagesController(orderId); this.documentsController = new DocumentsController(orderId); } // refresh() } export {ChatPageController} \ No newline at end of file diff --git a/assets/js/src/chat/ChatCustomerPageController.js b/assets/js/src/chat/ChatCustomerPageController.js new file mode 100644 index 0000000..679d9c3 --- /dev/null +++ b/assets/js/src/chat/ChatCustomerPageController.js @@ -0,0 +1 @@ +import {StagesController} from './StagesCustomerController' import {MessagesController} from './MessagesControllers' import {recalculateMessages} from './messageCounters' class ChatPageController { constructor() { let self = this; // console.log("NEW Chat CUSTOMER PageController"); this.statesController = undefined; this.messagesController = undefined; // TODO: не забыть! // recalculateMessages(); } create(orderId, projectId, recipentId, orderName, secureOrder) { this.statesController = new StagesController(orderId, projectId, recipentId, orderName, secureOrder); this.messagesController = new MessagesController(orderId); } } export {ChatPageController} \ No newline at end of file diff --git a/assets/js/src/chat/DocumentsControllers.js b/assets/js/src/chat/DocumentsControllers.js new file mode 100644 index 0000000..c5b8e87 --- /dev/null +++ b/assets/js/src/chat/DocumentsControllers.js @@ -0,0 +1,67 @@ +import {getCookie} from '../utils' +import {loadTemplate} from './loaders' + +class DocumentsController { + constructor(orderId) { + console.log('Create MessagesController'); + const self = this; + this.orderId = orderId; + this.$container = $('#documentOrderSpace'); + this.$container.html(""); + + this.messageTemplate = loadTemplate('document_attach_file_tmpl'); + this.dataPromise = this.getMessagesData(); + this.dataPromise.then( + self._onLoadData.bind(self) + ) + } + + getMessagesData() { + const self = this; + return Promise.resolve( + $.ajax({ + url: '/api/documents', + type: 'GET', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: { + 'order': self.orderId, + 'is_delete': false, + 'is_send': true, + }, + dataType: 'json', + // success: function (json) { + // + // }, + error: function (e) { + console.log(e); + } + })); + } + + addDocument(json) { + + } + + _onLoadData(json) { + const self = this; + // console.log('mesages json = ', json); + // console.log('$inbox = ', this.$inbox); + // console.log("messages render start"); + this.$container.html(""); + $.each(json.results, function (i, v) { + let document = $(self.messageTemplate( + { + href: `/chat/download/' + ${v.file}`, + text: v.file, + document_id: v.id + })); + self.$container.append(document); + }); + // console.log("messages render complete"); + // self.$inbox.scrollTop(self.$inbox.prop("scrollHeight")); + } +} + +export {DocumentsController} \ No newline at end of file diff --git a/assets/js/src/chat/MessagesControllers.js b/assets/js/src/chat/MessagesControllers.js new file mode 100644 index 0000000..8bb1d10 --- /dev/null +++ b/assets/js/src/chat/MessagesControllers.js @@ -0,0 +1,61 @@ +import {getCookie} from '../utils' +import {loadTemplate} from './loaders' + +class MessagesController { + constructor(orderId) { + console.log('Create MessagesController'); + const self = this; + this.orderId = orderId; + this.$inbox = $('#message-chat-order-space'); + this.$inbox.html(""); + this.messageTemplate = loadTemplate('message_tmpl'); + this.dataPromise = this.getMessagesData(); + this.dataPromise.then( + self._onLoadData.bind(self) + ) + } + + getMessagesData() { + const self = this; + return Promise.resolve($.ajax({ + url: '/api/message', + type: 'GET', + data: {'order': self.orderId, 'team__isnull': 'true'}, + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + success: function (json) { + console.log('Success Messages') + } + })); + } + + _onLoadData(json) { + const self = this; + // console.log('mesages json = ', json); + // console.log('$inbox = ', this.$inbox); + // console.log("messages render start"); + self.$inbox.html(""); + $.each(json.results, function (i, v) { + var senderName = 'Вы'; + var className = 'youChat'; + + if (v.sender.id !== userId) { + senderName = v.sender.username; + className = ''; + } + if (v.is_system) { + senderName = 'Системное'; + className = 'systemChat' + } + let message = $(self.messageTemplate({className: className, senderName: senderName, message: v})); + self.$inbox.append(message); + + }); + // console.log("messages render complete"); + self.$inbox.scrollTop(self.$inbox.prop("scrollHeight")); + } +} + +export {MessagesController} \ No newline at end of file diff --git a/assets/js/src/chat/Stages.js b/assets/js/src/chat/Stages.js new file mode 100644 index 0000000..feb09f9 --- /dev/null +++ b/assets/js/src/chat/Stages.js @@ -0,0 +1,340 @@ +import {loadTemplate} from './loaders' +// new-stages-form +// update-stages-form +// remove-stages-form + +class StageForm { + constructor($container, {orderId, stage_num, stage_status, type = 'new', formNamePostfix = '-stages-form', template_name, data = {}}, + kwargs = { + stage_num: stage_num, + stage_status: stage_status, + form_name: (type + formNamePostfix), + orderId: orderId, + stage: data + },) + // kwargs - auto generate from name_attributes + { + // console.log('Stage form template_name = ', template_name); + this.orderId = orderId; + this._type = type; + this.$container = $container; + this.self_tmpl = loadTemplate(template_name); + this.data = data; + this.$form = undefined; + this.stageId = (type != 'new') ? data.id : undefined; + this.create(kwargs); + } + + create(kwargs) { + /** + * Добавление шаблона-формы Этапа на страницу + */ + let el = $(this.self_tmpl(kwargs)); + this.$container.append(el); + this.$form = el.find('form'); + // console.log("form --> ", this.$form); + if (this.$form.length) this.$form.find('input[name=cost]').mask('000000000'); + } + + remove() { + /** + * Удаление, при уменьшении кол-ва этапов + * return true - удаляем из [] stages + */ + if (this.type == 'new') { + this.$form.parent().remove(); + return true; + } + this.type = 'remove'; + // this.$form.removeClass('update-stages-form').addClass('remove-stages-form'); + return false + } + + restore() { + /** + * Восстановление, при увеличении кол-ва этапов + */ + if (this.type == 'new') throw new Error("Попытка восстановить элемент с type='new'"); + this.type = 'update'; + // this.$form.removeClass('remove-stages-form').addClass('update-stages-form'); + } + + set type(newType) { + this.$form.removeClass(`${this._type}-stages-form`).addClass(`${newType}-stages-form`); + if (newType == 'remove') this.hide(); + if (newType == 'update') this.show(); + this._type = newType + } + + get type() { + return this._type + } + + disable() { + this.$form.find('input').attr('readonly', true); + } + + enable() { + this.$form.find('input').attr('readonly', false); + } + + hide() { + this.$form.parent().hide(); + } + + show() { + this.$form.parent().show() + } + + is_valid() { + let self = this; + let mesage = 'Это поле обязательно'; + let valid = true; + //Очищаем старые ошибки + this.$form.find('.error').html(""); + // Отображаем новые + this.$form.find(":input:not([type=hidden])").each(function (i, v) { + if (!$(v).val()) { + self.$form.find(`.error-${$(v).attr("name")}`).html(mesage).css('color', 'red'); + valid = false + } + }); + return valid + } + + sendAjax_approve() { + /** + * Отправка Этапа "на согласование" + */ + let self = this; + // console.log("Send AJAX Approve"); + if (this.type == 'new') { + // console.log('new stages approve'); + return Promise.resolve($.ajax({ + // async: false, + url: '/api/stages/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: this.$form.serialize(), + dataType: 'json', + }) + .done(function (json) { + self.type = 'update'; + self.disable(); + self.$form.find('.error').html(""); + // console.log("json -->", json); + self.stageId = json.id; + // console.log(json); + }) + .fail(function (xhr, errorMsg, error) { + console.log("ERROR, xhr", xhr); + $.each(xhr.responseJSON, function (i, v) { + self.$form.find('.error-' + i).html(v).css('color', 'red'); + // console.log(self.$form); + // console.log(v); + // console.log(i); + }); + })); + } else if (this.type == 'update') { + this.$form.find('input[name=status]').val('send_approve'); + return Promise.resolve($.ajax({ + url: `/api/stages/${this.stageId}/`, + type: 'PUT', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: this.$form.serialize(), + dataType: 'json', + }) + .done(function (json) { + self.$form.find('.error').html(""); + self.disable(); + }) + .fail(function (xhr, errorMsg, error) { + $.each(xhr.responseJSON, function (i, v) { + self.$form.find('.error-' + i).html(v).css('color', 'red'); + console.log(v); + console.log(i); + }); + })); + } else if (this.type == 'remove') { + return Promise.resolve($.ajax({ + url: `/api/stages/${this.stageId}/`, + type: 'DELETE', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + }) + .done(function (json) { + }) + .fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + })); + } + } + + sendAjax_accept(secureOrder) { + /** + * "Согласовать" Этапы (Исполнителем) + */ + // console.log("secureOrder = ", secureOrder); + // console.log("set new status =", secureOrder ? 'agreed': 'in_process'); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + //TODO: слать только изменения + data: { + status: secureOrder ? 'agreed': 'in_process', + }, + dataType: 'json', + })) + } + + sendAjax_change() { + /** + * Отправка Этапа "Внести изменения" + */ + let self = this; + // this.$form.find('input[name=status]').val('not_agreed'); + // console.log("ajax Change form -->", this.$form); + return Promise.resolve($.ajax({ + url: '/api/stages/' + this.stageId + '/', + type: 'PATCH', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + //TODO: слать только изменения + data: {status: 'not_agreed'}, + dataType: 'json', + }) + .done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + self.enable(); + }) + .fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + +} + +class StageReserved { + constructor($container, {template_name = 'reserved_tmpl', data}, + kwargs = { + reserved_cls: '', + reserved_name: '', + stage: data + },) { + // Вывод текста резервирования в зависимости от статуса этапа + let reserved_names = { + agreed: 'Не зарезервирована', + in_process: 'Зарезервирована', + completed: 'Зарезервирована', + closed: 'Переведена исполнителю', + }; + // Вывод текста резервирования в зависимости от статуса этапа + let reserved_classes = { + agreed: 'unreserved', + in_process: 'reserved', + completed: 'reserved', + closed: 'closed', + }; + kwargs.reserved_cls = reserved_classes[data.status]; + kwargs.reserved_name = reserved_names[data.status]; + this.data = data; + this.self_tmpl = loadTemplate(template_name); + this.$container = $container; + this.create(kwargs); + } + + create(kwargs) { + /** + * Добавление шаблона "Резервирование" Этапа на страницу + */ + this.$self = $(this.self_tmpl(kwargs)); + this.$container.append(this.$self); + // console.log("form --> ", this.$form); + // this.$form.find('input[name=cost]').mask('000000000'); + } +} + +class StageInWork { + constructor($container, {template_name = 'work_in_process_tmpl', note_text = '', data}, + kwargs = {stage: data, note_text: note_text}) { + this.stageId = data.id; + this.data = data; + this.self_tmpl = loadTemplate(template_name); + this.$container = $container; + this.create(kwargs); + } + + create(kwargs) { + /** + * Добавление шаблона "Выполнение работы" Этапа на страницу + */ + this.$self = $(this.self_tmpl(kwargs)); + this.$container.append(this.$self); + } + + hide() { + this.$self.hide(); + } + + sendAjax_complete() { + /** + * Отправка Этапа "Закрыть этап" + */ + let self = this; + return Promise.resolve($.ajax({ + url: `/api/stages/${this.stageId}/`, + type: 'PATCH', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: {status: 'completed'}, + dataType: 'json', + }) + .done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + // self.enable(); + }) + .fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } + + sendAjax_close() { + /** + * Отправка Этапа "Закрыть этап" + */ + let self = this; + return Promise.resolve($.ajax({ + url: `/api/stages/${this.stageId}/`, + type: 'PATCH', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + //TODO: слать только изменения + data: {status: 'closed'}, + dataType: 'json', + }) + .done(function (json) { + // enableStageFields(json.id); + // $form.find('.error').html(""); + // self.enable(); + }) + .fail(function (xhr) { + console.log("Ошибка, которой не должно быть json -->", xhr.responseJSON); + })); + } +} + +export {StageForm, StageReserved, StageInWork} \ No newline at end of file diff --git a/assets/js/src/chat/StagesContractorController.js b/assets/js/src/chat/StagesContractorController.js new file mode 100644 index 0000000..bb947d8 --- /dev/null +++ b/assets/js/src/chat/StagesContractorController.js @@ -0,0 +1,446 @@ +import {getCookie} from '../utils' +import {loadTemplate} from './loaders' +import {StageForm, StageReserved, StageInWork} from './Stages' + +let message_format = { + "format_type": "approve_stages", + "data": { + "sender_id": "", + "recipent_id": "", + "order_id": "", + "msg": "", + "is_system": true + } +}; + +const STATUSES = { + 'not_agreed': 'не согласован', + 'send_approve': 'на согласовании', + 'agreed': 'согласовано', + 'cancel_approve': 'исполнитель отказался', + 'in_process': 'в процессе', + 'completed': 'завершен', + 'closed': 'закрыт', + +}; + +//Contractor +class StagesController { + constructor(orderId, projectId, recipentId, orderName, secureOrder) { + const self = this; + this.orderId = orderId; + this.projectId = projectId; + this.recipentId = recipentId; + this.orderName = orderName; + this.secureOrder = secureOrder; + // console.log("ids -->", orderId, projectId, recipentId); + this.data = {}; //JSON + this.stages = []; + this.stages_reserved = []; + this.stages_work = []; + this.STAGE_STATUSES = { + 'not_agreed': this.buildStartStage.bind(self), + 'send_approve': this.buildSendApproveStage.bind(self), + 'agreed': this.buildAgreedStage.bind(self), + 'in_process': this.buildProcessStage.bind(self), + 'completed': this.buildProcessStage.bind(self), + 'closed': this.buildProcessStage.bind(self), + }; + this.btnCompleteTmpl = loadTemplate('bntCompleteStage_tmpl'); + this.btnSendReviewTmpl = loadTemplate('btnSendReview_tmpl'); + this.$orderStagesContainer = $('#order-stages'); + this.$orderStagesContainer.html(''); + this.buttons = { + btnApprove: $('#btnApprove'), // "Согласовать" + btnChange: $('#btnChange'), // "Отправить на внесение изменений" + btnsToArchive: $('.js-btnToArchive'), // "Отказаться от заказа" + btnsArbitration: $('.js-btnArbitration'),// "Обратиться в арбитраж" + btnSendReview: $('#order-review-add') // "Оставить отзыв" + }; + this.stages_elements = { + $approve: $('#conditions-approve'), //1. Согласование условия + $reserve: $('#reserveSpace'), //2. Резервирование (Отобразить) + $works: $('#completeWork') //3. Выполненная работа + }; + this.init(); + } + + init() { + const self = this; + + this.dataPromise = this.getOrderData({orderId: this.orderId}); + this.dataPromise + .then( + self._onLoadData.bind(self) + ) + .catch( + self._onLoadDataError.bind(self) + ); + } + + getOrderData({orderId}) { + const self = this; + return Promise.resolve($.ajax({ + url: `/api/orders/${orderId}/`, + dataType: 'json', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + })) + } + + redraw() { + /** + * Полностью перерисовываем страницу Заказа + */ + console.log("Redraw contractor stages"); + // $("#orderBlock" + this.orderId).trigger('click'); + this.init(); + } + + + buildStartStage() { + /** + * Стадия: "Проект Предложен"(нет этапов) + */ + // Выделить цифру 1. красным + // $('#conditions-approve').find('.select') + this.stages_elements.$approve.show(); + this.stages_elements.$reserve.show(); + this.stages_elements.$works.show(); + this.$orderStagesContainer.parent().hide(); + this.buttons.btnsToArchive.first().hide(); + this.$orderStagesContainer.show(); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.hide(); + this.buttons.btnsArbitration.hide(); + this.stages_elements.$approve.find('.js-help-text').show(); + this.stages_elements.$reserve.find('.stages-paid').html(""); + this.stages_elements.$works.find('.js-help-text').show(); + this.stages_elements.$works.find('#stagesWork').html(""); + if (this.secureOrder){ + this.stages_elements.$reserve.find('.js-help-text').show(); + } else { + this.stages_elements.$reserve.find('.js-help-text').hide(); + // this.stages_elements.$reserve.find('.js-help-text').html('Резервирование не предусмотрено, безопасная сделака не активна'); + } + + } // Нет Этапов / "Не согласован" + + // buildNotAgreedStage() { + // console.log("Stage: not_agreed"); + // // this._renderStage('stage_tmpl'); + // this.buttons.btnApprove.hide(); + // this.buttons.btnChange.hide(); + // this.buttons.btnToArchive.hide(); + // this.buttons.btnArbitration.hide(); + // } // Статус "Не согласован" + + buildSendApproveStage() { + console.log("Stage: send_approve"); + this._renderStage('stage_approved_tmpl', true); + this.$orderStagesContainer.parent().show(); + this.buttons.btnApprove.show(); + this.buttons.btnChange.show(); + this.buttons.btnsToArchive.first().show(); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + } // Статус "На согласовании" + + buildAgreedStage() { + console.log('Stage: agreed'); + this.$orderStagesContainer.parent().show(); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.hide(); + this.buttons.btnsToArchive.hide(); + this.buttons.btnsArbitration.first().hide(); + this.buttons.btnsArbitration.last().show(); + this._renderStage('stage_approved_tmpl', true); + this.stages_elements.$approve.find('.js-help-text').hide(); + this.stages_elements.$reserve.show(); + if (this.secureOrder){ + this._renderStageReserved('reserved_tmpl'); + this.stages_elements.$reserve.find('.js-help-text').show(); + }else{ + this.stages_elements.$reserve.find('.stages-paid').html(""); + this.stages_elements.$reserve.find('.js-help-text').hide(); + } + } // Статус "Согласован" + + buildProcessStage() { + console.log('Stage: in_process'); + this.buildAgreedStage(); + this.stages_elements.$reserve.find('.js-help-text').hide(); + this.stages_elements.$works.show(); + if (this.secureOrder) { + this._renderStageInWork('work_in_process_tmpl'); + } else { + this.stages_elements.$reserve.find('.stages-paid').html(""); + } + } // Статус "В процессе"/"Завершен"/"Закрыт" + + _buildPage() { + // console.log("Build PAge"); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + if (this.data.stages.length == 0) { + this.buildStartStage() + } else { + let stageStatus = this.data.stages[0].status; + // console.log('stageStatus = ', stageStatus); + this.STAGE_STATUSES[stageStatus](); + } + this._bindEvents(); + } + + _renderStage(template_name, disable = false) { + let i = 0; + // console.log("this.data.stages = ", this.data.stages); + this.$orderStagesContainer.html(""); + for (let stage_data of this.data.stages) { + i++; + // console.log('stage_data = ', stage_data); + let stage = new StageForm(this.$orderStagesContainer, + { + orderId: this.orderId, stage_num: i, stage_status: STATUSES[stage_data.status], + type: 'update', template_name: template_name, data: stage_data + }); + if (disable) stage.disable(); + this.stages.push(stage); + + } + } + + _renderStageReserved(template_name) { + /** + * Отрисовываем блок "Резервирование" + */ + // console.log("_renderStageReserved"); + let $container = this.stages_elements.$reserve.find('.stages-paid'); + $container.html(""); + this.stages_reserved = []; + // console.log("this.data.stages = ", this.data.stages); + // Нет незарезервированных Этапов + // let has_not_reserved_stages = false; + for (let stage_data of this.data.stages) { + // if (stage_data.status == 'agreed') has_not_reserved_stages = true; + let stage = new StageReserved($container, + { + template_name, data: stage_data + }); + this.stages_reserved.push(stage); + } + // if (!has_not_reserved_stages) { + // this.buttons.btnReserve.hide(); + // this.stages_elements.$reserve.find('.js-help-text').hide(); + // } + } + + _renderStageInWork(template_name) { + /** + * Отрисовываем блок "Выволнение работы", включая "Выполненныа работа" и "Оставить отзыв" + */ + let $container = this.stages_elements.$works.find('#stagesWork'); + $container.html(""); + let all_closed = this.data.stages.every((el)=>el.status == 'closed'); + if (all_closed) { + this.stages_elements.$works.find('.titleStepss').html('3. Выполненная работа'); + this.stages_elements.$works.find('.js-btnArbitration').hide(); + this.stages_elements.$works.find('.js-help-text').hide(); + for (let stage_data of this.data.stages) { + let stage = new StageInWork($container, + { + template_name, data: stage_data + }); + this.stages_work.push(stage); + } + // console.log("has_user_review = ", this.data.has_user_review); + if (!this.data.has_user_review) { + let btnReviewOpenModel = $(this.btnSendReviewTmpl()); + btnReviewOpenModel.unbind().on('click', this._onBtnReviewOpenModal.bind(this)); + // Если кнопка "Оставить отзыв" еще не добавлена - добавляем + if (!this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.append(btnReviewOpenModel); + } else { + if (this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.find('#send-review').remove() + } + + } else { + for (let stage_data of this.data.stages) { + if (stage_data.status == 'closed' || stage_data.status == 'agreed') continue; + let note_text = (stage_data.status == 'completed') ? '...НА УТВЕРЖДЕНИИ У ЗАКАЗЧИКА' : ''; + let stage = new StageInWork($container, + { + template_name, data: stage_data, note_text: note_text + }); + if (stage_data.status == 'in_process') { + let $btn = $(this.btnCompleteTmpl({stage: stage_data, text: 'Завершить этап'})); + $container.html(); + $container.append($btn); + $btn.on('click', this._onBtnComplete.bind(this, stage)) + } + this.stages_work.push(stage); + } + } + + } + + _onLoadData(json) { + this.data = json; + this._buildPage(); + } + + _bindEvents() { + const self = this; + this.buttons.btnApprove.unbind().on("click", this._onBtnAccept.bind(self)); + this.buttons.btnChange.unbind().on("click", this._onBtnChange.bind(self)); + this.buttons.btnsToArchive.unbind().on("click", this._onBtnAToArchive.bind(self)); + this.buttons.btnsArbitration.unbind().on("click", this._onBtnArbitration.bind(self)); + this.buttons.btnSendReview.unbind().on("click", this._onBtnSendReview.bind(self)); + $("#reserve-stage-modal").find('#stage-num').unbind().on('change', function (event) { + // console.log("select stage cost = ", self.stages[this.value - 1].data.cost); + $("#reserve-stage-modal").find('#stage-cost').html(self.stages[this.value - 1].data.cost); + }); + } + + // BINDS + + _onBtnAccept(event) { + event.preventDefault(); + const self = this; + Promise.all(this.stages.map((el)=>el.sendAjax_accept(self.secureOrder))).then(()=> { + console.log('Этапы согласованы'); + self.redraw(); + + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Условия заказа ${self.orderName} приняты`; + console.log("Send-WS Условия приняты"); + socket.send_stages_approve(message); + //TODO: раскомментировать дурацкое окно + // $('#popupOk').modal('show'); + // }) + }); + } // "Согласовать" + + _onBtnChange(event) { + event.preventDefault(); + const self = this; + Promise.all(this.stages.map((el)=>el.sendAjax_change())).then(()=> { + self.redraw(); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Заказ ${self.orderName} отправлен для внесения изменений`; + console.log("Send-WS Внести изменения"); + socket.send_stages_approve(message); + }); + + } // "Отправить на внесение изменений" + + // TODO: test it + _onBtnAToArchive(event) { + event.preventDefault(); + console.error("Отказаться от заказа. Не протестировано!!"); + // TODO: Не только удалять заказ, но и делать его копию со статусом "Открыто" + $.ajax({ + // async: false, + url: `/api/orders/${this.orderId}/`, + type: 'DELETE', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + }) + .done(function (json) { + console.log('delete complete'); + window.location.href = window.location.href.replace(getHash(), ""); + }) + .fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + }); + + } // "Отказаться от заказа" + + _onBtnComplete(stage, event) { + event.preventDefault(); + const self = this; + // let stageId = $(event.target).data('stage-id'); + // console.log('Complete stage id = ', stage.data.id); + stage.sendAjax_complete() + .then(function (json) { + self.redraw(); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Этап ${json.name} закрыт`; + console.log("Send-WS Закрытие этапа"); + socket.send_stages_approve(message); + }) + .catch(function (xhr) { + console.log("При закрытии этапа произошла ошибка -->", xhr); + }) + + } // "Закрыть этап" + + _onBtnReviewOpenModal(event) { + event.preventDefault(); + $('#review-add').modal('show'); + } // Открыть модальное окно "Оставить отзыв" + + _onBtnSendReview(event) { + event.preventDefault(); + const self = this; + $('#projectReviewId').val(this.projectId); + $('#targetCustomerId').val(this.recipentId); + // $('#fromContractorId').val('....current user'); + var formData = $("#review-adds-form").serialize(); + // console.log('Оставить отзыв formdata -->', formData); + $.ajax({ + url: '/api/reviews/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: formData, + dataType: 'json', + success: function (json) { + // console.log('Отзыв успешно отправлен, json -->', json); + // $('#review-add').modal('hide'); + // self.stages_elements.$works.find('.js-btnSendReview').hide(); + $('#review-add').modal('hide'); + self.redraw(); + + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Отзыв на заказ ${self.orderName} оставлен`; + console.log("Send-WS Оставить отзыв"); + socket.send_stages_approve(message); + // $("a[href='#tab2']").trigger('click'); + window.location = '/chat/#order'; + location.reload(); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + } // "Оставить отзыв" + + + _onBtnArbitration(event) { + event.preventDefault(); + $("#arbitration-add").modal('show'); + } // "Обратиться в арбитраж" + + _onLoadDataError(error) { + console.log("Error loading data -->", error); + } +} + +export {StagesController} \ No newline at end of file diff --git a/assets/js/src/chat/StagesCustomerController.js b/assets/js/src/chat/StagesCustomerController.js new file mode 100644 index 0000000..5541d05 --- /dev/null +++ b/assets/js/src/chat/StagesCustomerController.js @@ -0,0 +1,545 @@ +import {getCookie} from '../utils' +import {loadTemplate} from './loaders' +import {StageForm, StageReserved, StageInWork} from './Stages' + +let message_format = { + "format_type": "approve_stages", + "data": { + "sender_id": "", + "recipent_id": "", + "order_id": "", + "msg": "", + "is_system": true + } +}; + +const STATUSES = { + 'not_agreed': 'не согласован', + 'send_approve': 'на согласовании', + 'agreed': 'согласовано', + 'cancel_approve': 'исполнитель отказался', + 'in_process': 'в процессе', + 'completed': 'завершен', + 'closed': 'закрыт', + +}; + + +class StagesController { + constructor(orderId, projectId, recipentId, orderName, secureOrder) { + const self = this; + this.orderId = orderId; + this.orderName = orderName; + this.projectId = projectId; + this.recipentId = recipentId; + this.secureOrder = secureOrder; + this.data = {}; //JSON + this.stages = []; + this.stages_reserved = []; + this.stages_work = []; + this.STAGE_STATUSES = { + 'not_agreed': this.buildNotAgreedStage.bind(self), + 'send_approve': this.buildSendApproveStage.bind(self), + 'agreed': this.buildAgreedStage.bind(self), + 'in_process': this.buildProcessStage.bind(self), + 'completed': this.buildProcessStage.bind(self), + 'closed': this.buildProcessStage.bind(self), + }; + this.btnCompleteTmpl = loadTemplate('bntCompleteStage_tmpl'); + this.btnSendReviewTmpl = loadTemplate('btnSendReview_tmpl'); + this.$orderStagesContainer = $('#order-stages'); + this.$orderStagesContainer.html(''); + this.$stagesCount = $('#countStage'); + this.$stagesCount.unbind().on("change", this._changeNumStages.bind(self)); + this.$stagesCount.parent().show(); + this.buttons = { + btnApprove: $('#btnApprove'), + btnChange: $('#btnChange'), + btnToArchive: $('#btnToArchive'), + btnReserve: $('#btnReserve'), + btnsArbitration: $('.js-btnArbitration'), + btnSendReview: $('#order-review-add') + }; + this.stages_elements = { + $approve: $('#conditions-approve'), //1. Согласование условия + $reserve: $('#reserveSpace'), //2. Резервирование + $works: $('#completeWork') //3. Выполненная работа + }; + this.init(); + } + + init() { + const self = this; + + this.dataPromise = this.getOrderData({orderId: this.orderId}); + this.dataPromise + .then( + self._onLoadData.bind(self) + ) + .catch( + self._onLoadDataError.bind(self) + ); + } + + getOrderData({orderId}) { + const self = this; + return Promise.resolve($.ajax({ + url: `/api/orders/${orderId}/`, + dataType: 'json', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + })) + } + + redraw() { + /** + * Полностью перерисовываем страницу Заказа + */ + console.log("Redraw customer stages"); + // $("#orderBlock" + this.orderId).trigger('click'); + this.init(); + } + + buildStartStage() { + /** + * Стадия: "Проект Предложен"(нет этапов) + */ + // Выделить цифру 1. красным + // $('#conditions-approve').find('.select') + this.$orderStagesContainer.show(); + this.buttons.btnApprove.show(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + this.$stagesCount.removeAttr('disabled'); + this.$stagesCount.val(1); + this.$stagesCount.trigger('change'); + // this.stages_elements.$approve.find('.js-help-text').show(); + // this.stages_elements.$reserve.find('.js-help-text').show(); + // this.stages_elements.$reserve.find('.stages-paid').hide(); + // this.stages_elements.$works.find('.js-help-text').show(); + // this.stages_elements.$works.find('#stagesWork').show(); + + } // Нет Этапов + + buildNotAgreedStage() { + console.log("Stage: not_agreed"); + this._renderStage('stage_tmpl'); + this.buttons.btnApprove.show(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + } // Статус "Не согласован" + + buildSendApproveStage() { + console.log("Stage: send_approve"); + this._renderStage('stage_tmpl', true); + this.$stagesCount.attr('disabled', true); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.show(); + this.buttons.btnToArchive.show(); + } // Статус "На согласовании" + + buildAgreedStage() { + console.log('Stage: agreed'); + this.buttons.btnApprove.hide(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + this.$stagesCount.parent().hide(); + this._renderStage('stage_approved_tmpl', true); + this.stages_elements.$approve.find('.js-help-text').hide(); + this.stages_elements.$reserve.find('.js-help-text').show(); + this.stages_elements.$reserve.show(); + this.buttons.btnReserve.show(); + this.buttons.btnsArbitration.show(); + this._renderStageReserved('reserved_tmpl') + + } // Статус "Согласован" + + buildProcessStage() { + console.log('Stage: in_process'); + this.buildAgreedStage(); + this.stages_elements.$reserve.find('.js-btnArbitration').hide(); + this.stages_elements.$works.show(); + this._renderStageInWork('work_in_process_tmpl'); + } // Статус "В процессе"/"Завершен"/"Закрыт" + + _buildPage() { + // console.log("Build PAge"); + this.stages_elements.$reserve.hide(); + this.stages_elements.$works.hide(); + if (this.data.stages.length == 0) { + this.buildStartStage() + } else { + let stageStatus = this.data.stages[0].status; + // console.log('stageStatus = ', stageStatus); + this.STAGE_STATUSES[stageStatus](); + } + this._bindEvents(); + } + + _renderStage(template_name, disable = false) { + let i = 0; + this.$orderStagesContainer.html(""); + for (let stage_data of this.data.stages) { + i++; + let stage = new StageForm(this.$orderStagesContainer, + { + orderId: this.orderId, stage_num: i, stage_status: STATUSES[stage_data.status], + type: 'update', template_name: template_name, data: stage_data + }); + if (disable) stage.disable(); + this.stages.push(stage); + + } + this.$stagesCount.val(i); + } + + _renderStageReserved(template_name) { + let $container = this.stages_elements.$reserve.find('.stages-paid'); + $container.html(""); + this.stages_reserved = []; + // Нет незарезервированных Этапов + let has_not_reserved_stages = false; + for (let stage_data of this.data.stages) { + if (stage_data.status == 'agreed') has_not_reserved_stages = true; + let stage = new StageReserved($container, + { + template_name, data: stage_data + }); + this.stages_reserved.push(stage); + } + if (!has_not_reserved_stages) { + this.buttons.btnReserve.hide(); + this.stages_elements.$reserve.find('.js-help-text').hide(); + } + } + + _renderStageInWork(template_name) { + /** + * Отрисовываем блок "Выволнение работы", включая "Выполненныа работа" и "Оставить отзыв" + */ + let $container = this.stages_elements.$works.find('#stagesWork'); + $container.html(""); + let all_closed = this.data.stages.every((el)=>el.status == 'closed'); + if (all_closed) { + this.stages_elements.$works.find('.titleStepss').html('3. Выполненная работа'); + this.stages_elements.$works.find('.js-btnArbitration').hide(); + this.stages_elements.$works.find('.js-help-text').hide(); + for (let stage_data of this.data.stages) { + let stage = new StageInWork($container, + { + template_name, + data: stage_data, + note_text: 'Закройте этап или подробно опишите замечания в чате' + }); + this.stages_work.push(stage); + } + if (!this.data.has_user_review) { + let btnReviewOpenModel = $(this.btnSendReviewTmpl()); + btnReviewOpenModel.unbind().on('click', this._onBtnReviewOpenModal.bind(this)); + // Если кнопка "Оставить отзыв" еще не добавлена - добавляем + if (!this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.append(btnReviewOpenModel); + } else { + if (this.stages_elements.$works.find('#send-review').length) this.stages_elements.$works.find('#send-review').remove() + } + + } else { + for (let stage_data of this.data.stages) { + if (stage_data.status == 'closed') continue; + let stage = new StageInWork($container, + { + template_name, data: stage_data + }); + if (stage_data.status == 'completed') { + let $btn = $(this.btnCompleteTmpl({stage: stage_data, text: 'Закрыть этап'})); + $container.html(); + $container.append($btn); + $btn.on('click', this._onBtnClose.bind(this, stage)) + } + this.stages_work.push(stage); + } + } + + } + + _onLoadData(json) { + this.data = json; + this._buildPage(); + } + + _changeNumStages(event) { + /** + * Изменяет кол-во этапов(stages) + */ + let newNumStages = parseInt($(event.target).val()); + if (newNumStages < 1 || isNaN(newNumStages)) { + newNumStages = 1; + this.$stagesCount.val(newNumStages) + } + let currentNumStages = $('.js-stage-form:not(.remove-stages-form)').length; + if (currentNumStages == newNumStages) return; + if (currentNumStages > newNumStages) { + for (let stage of this.stages.slice().reverse()) { + if (stage.remove()) { + let index = this.stages.indexOf(stage); + if (index >= 0) { + this.stages.splice(index, 1); + } + } + currentNumStages--; + if (currentNumStages == newNumStages) break; + } + } else { + for (let stage of this.stages.slice()) { + if (stage.type == 'remove') { + stage.restore(); + } else continue; + currentNumStages++; + if (currentNumStages == newNumStages) break; + } + while (currentNumStages < newNumStages) { + currentNumStages++; + let stage = new StageForm(this.$orderStagesContainer, + {orderId: this.orderId, stage_num: currentNumStages, type: 'new', template_name: 'stage_tmpl'}); + this.stages.push(stage); + } + } + } //При изменении кол-ва этапов + + _bindEvents() { + const self = this; + this.buttons.btnApprove.unbind().on("click", this._onBtnApprove.bind(self)); + this.buttons.btnChange.unbind().on("click", this._onBtnChange.bind(self)); + this.buttons.btnToArchive.unbind().on("click", this._onBtnAToArchive.bind(self)); + this.buttons.btnReserve.unbind().on("click", this._onBtnReserve.bind(self)); + this.buttons.btnsArbitration.unbind().on("click", this._onBtnArbitration.bind(self)); + this.buttons.btnSendReview.unbind().on("click", this._onBtnSendReview.bind(self)); + $('#paymentfromSite').unbind().on('click', this._onBtnPaymentFromSite.bind(self)); + $("#reserve-stage-modal").find('#stage-num').unbind().on('change', function (event) { + // console.log("select stage cost = ", self.stages[this.value - 1].data.cost); + $("#reserve-stage-modal").find('#stage-cost').html(self.stages[this.value - 1].data.cost); + }); + } + + // BINDS + + _onBtnApprove(event) { + event.preventDefault(); + const self = this; + if (!this.stages.every((el)=>el.is_valid())) { + console.error('Не все поля форм валидны'); + return + } + // При выполнении всех ajax запросов + Promise.all(this.stages.map((el)=>el.sendAjax_approve())).then(()=> { + this.buttons.btnApprove.hide(); + this.buttons.btnChange.show(); + this.buttons.btnToArchive.show(); + this.$stagesCount.attr('disabled', true); + // var currentRecipentId = $(self).data('id'); + // var secureOrder = true; + // + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Условия заказа ${self.orderName} отправлены на согласование`; + console.log("Send-WS Отправить на согласование"); + socket.send_stages_approve(message); + //TODO: раскомментировать дурацкое окно + // $('#popupOk').modal('show'); + // }) + }); + } // "Отправить на согласование" + + _onBtnChange(event) { + event.preventDefault(); + const self = this; + Promise.all(this.stages.map((el)=>el.sendAjax_change())).then(()=> { + this.buttons.btnApprove.show(); + this.buttons.btnChange.hide(); + this.buttons.btnToArchive.hide(); + this.$stagesCount.attr('disabled', false); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Заказ ${self.orderName} отозван для внесения изменений`; + console.log("Send-WS Внести изменения"); + socket.send_stages_approve(message); + }); + + } // "Внести изменения" + + // TODO: test it + _onBtnAToArchive(event) { + event.preventDefault(); + const self = this; + $.ajax({ + // async: false, + url: `/api/orders/${this.orderId}/`, + type: 'DELETE', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + }) + .done(function (json) { + console.log('delete complete'); + window.location.href = window.location.href.replace(getHash(), ""); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Заказа ${self.orderName} отправлен в архив`; + console.log("Send-WS Отправить в архив"); + socket.send_stages_approve(message); + }) + .fail(function (xhr, errorMsg, error) { + console.log("delete fail, json -->", xhr); + }); + + } // "Отказаться и отправить в архив" + + _onBtnReserve(event) { + const self = this; + event.preventDefault(); + // Set modal-window params + let $modal = $("#reserve-stage-modal"); + let total_cost = this.stages.map((el)=>parseInt(el.data.cost)).reduce((a, b) => a + b, 0); + // console.log('total cost = ', total_cost); + $modal.find('#total-cost').html(total_cost); + + let $select_stageNum = $modal.find('#stage-num'); + $select_stageNum + .find('option') + .remove() + .end(); + for (let stage of this.stages) { + if (stage.data.is_paid) continue; + $select_stageNum.append(``); + } + // let $stage_cost = $modal.find('#stage-cost'); + // $stage_cost.html(self.stages[this.value - 1].data.cost); + $modal.find('#stage-num').trigger('change'); + + $modal.modal('show'); + } // "Зарезервировать" --> Открывает модальное окно для резервирования + + _onBtnPaymentFromSite(event) { + const self = this; + event.preventDefault(); + let $modal = $("#reserve-stage-modal"); + let sum, stages_id; + if ($modal.find('input[name=choice_way]:checked').val() == 'all_stages') { + sum = $modal.find('#total-cost').html(); + stages_id = this.stages.map((el)=>el.data.id); + } else { + sum = $modal.find('#stage-cost').html(); + let num_stage = $modal.find('#stage-num').val() - 1; + stages_id = [this.stages[num_stage].data.id]; + } + $.ajax({ + url: '/wallets/payfromscore/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: { + sum: sum, + stages_id: stages_id.join(';'), + }, + dataType: 'json', + success: function (json) { + // console.log('success pay stage, json ', json); + $("#reserve-stage-modal").modal('toggle'); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Заказчик зарезервировал сумму для этапов`; + console.log("Send-WS Оплата Этапа/Этапов"); + socket.send_stages_approve(message); + self.redraw(); + }, + error: function (xhr) { + console.log('error pay stage, json', xhr.responseJSON); + $.jGrowl(xhr.responseJSON.message_error); + } + }); + } // Оплата с сайта(Счет на Proekton) + + _onBtnClose(stage, event) { + event.preventDefault(); + const self = this; + stage.sendAjax_close() + .then(function (json) { + console.log("Этап закрыт успешно"); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Заказчик закрыл этап ${json.name}`; + console.log("Send-WS Оплата Этапа/Этапов"); + socket.send_stages_approve(message); + self.redraw(); + }) + .catch(function (xhr) { + console.log("При закрытии этапа произошла ошибка -->", xhr); + }) + + } // "Закрыть этап" + + _onBtnReviewOpenModal(event) { + event.preventDefault(); + $('#review-add').modal('show'); + } // Открыть модальное окно "Оставить отзыв" + + _onBtnSendReview(event) { + event.preventDefault(); + const self = this; + $('#projectReviewId').val(this.projectId); + $('#targetContractorId').val(this.recipentId); + var formData = $("#review-adds-form").serialize(); + $.ajax({ + url: '/api/reviews/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: formData, + dataType: 'json', + success: function (json) { + $('#review-add').modal('hide'); + let message = message_format; + message.data.sender_id = userId; + message.data.recipent_id = self.recipentId; + message.data.order_id = self.orderId; + message.data.msg = `Отзыв на заказ ${self.orderName} оставлен`; + console.log("Send-WS Оставить отзыв"); + socket.send_stages_approve(message); + window.location = '/chat/#order'; + location.reload(); + // $("a[href='#tab2']").trigger('click'); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + } // "Оставить отзыв" + + + _onBtnArbitration(event) { + event.preventDefault(); + $("#arbitration-add").modal('show'); + } // "Обратиться в арбитраж" + + _onLoadDataError(error) { + console.log("Error loading data -->", error); + } +} + +export {StagesController} \ No newline at end of file diff --git a/assets/js/src/chat/archiveProjects.js b/assets/js/src/chat/archiveProjects.js new file mode 100644 index 0000000..aabd223 --- /dev/null +++ b/assets/js/src/chat/archiveProjects.js @@ -0,0 +1,84 @@ +import {getCookie} from '../utils' + + +function bindArchiveProjects() { + // Нажимаем на кнопку архивные сообщения + $("#trashed-button").on('click', function (e) { + e.preventDefault(); + var state = $(this).attr('data-show'); + var trashedOrderHtml = ""; + + if (state == 'true') { + $(this).attr('data-show', 'false'); + $(this).text("Скрыть архивные заказы"); + + $("#archive-space").show(); + $("#show-archive-label").show(); + + } else { + $(this).attr('data-show', 'true'); + $(this).text("Показать архивные заказы"); + $("#archive-space").hide(); + $("#show-archive-label").hide(); + } + + + }); + + // Нажимаем на заказ в архмвных заказах + $(".messageBlock").on('click', '.trashedOrderBlock', function () { + let $this = $(this); + $("#chat-order-add").css("display", "none"); + $('.order-block, .trashedOrderBlock').each(function () { + $(this).removeClass('orAct'); + }); + $this.addClass('orAct'); + // var inbox = document.getElementById('message-chat-order-space'); + // var docList = document.getElementById('documentOrderSpace'); + // inbox.innerHTML = ''; + // docList.innerHTML = ''; + + + let orderId = $this.data('id'); + // let projectId = $this.data('project-id'); + // let recipentId = $this.data('recipent-id'); + // let orderName = $this.data('order-name'); + location.hash = '#order' + orderId; + // console.log(orderId); + window.chatController.create(orderId); + // $.ajax({ + // url: '/api/message', + // type: 'GET', + // beforeSend: function (xhr) { + // xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + // }, + // data: {'order': orderId, 'team__isnull': 'true'}, + // dataType: 'json', + // success: function (json) { + // $.each(json.results, function (i, v) { + // var senderName = 'Вы'; + // var className = 'youChat'; + // + // if (v.sender.id !== userId) { + // senderName = v.sender.username; + // className = ''; + // } + // + // inbox.innerHTML += '
    ' + + // '

    ' + senderName + '

    ' + v.created + '
    ' + + // '

    ' + v.text + '

    '; + // + // }); + // var height = inbox.scrollHeight; + // inbox.scrollTop = height; + // } + // }); + + // $("#order-stages").html(""); + // $("#completeWork").hide(); + // $("#add-form-order-note").hide(); + // $("#reserveSpace").hide(); + }); +} + +export {bindArchiveProjects} \ No newline at end of file diff --git a/assets/js/src/chat/chats.js b/assets/js/src/chat/chats.js new file mode 100644 index 0000000..4b15a62 --- /dev/null +++ b/assets/js/src/chat/chats.js @@ -0,0 +1,145 @@ +function chatContactsInit() { + /** + * Bind на кнопку "Отправить" в Закладке "Личные контакты" + */ + $('#contact-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat").val(); + var recipentId = $("#recipentContactId").val(); + var senderId = $("#senderContactId").val(); + var sendLinks = $("#document-send-contact a"); + + if (chatMessage || sendLinks.length > 0) { + $("#contact-chat-form .errorEmptyMessage").hide(); + + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + + '' + $(this).text() + '' + + '
  • '; + }); + // console.log("sendLinkIds = ", sendLinkIds); + socket.send_message({ + "format_type": "add_message_contact", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles, + } + } + }); + $("#chat").val(""); + $("#document-send-contact").html(""); + } else { + $("#contact-chat-form .errorEmptyMessage").show(); + } + + }); +} + +function chatOrdersInit() { + /** + * Bind на кнопку "Отправить" в Закладке "Исполнители/Заказчики" + */ + $('#order-chat-add-message').on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#chat-order-add #chat").val(); + var recipentId = $("#chat-order-add #recipentId").val(); + var senderId = $("#chat-order-add #senderId").val(); + var orderId = $("#chat-order-add #orderId").val(); + var sendLinks = $("#document-send-order a"); + if (chatMessage || sendLinks.length > 0) { + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + + '' + $(this).text() + '' + + '
  • '; + }); + socket.send_message({ + "format_type": "add_message_order", + "data": { + "sender_id": senderId, + "recipent_id": recipentId, + "chat_message": chatMessage, + "order_id": orderId, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles, + } + } + + }); + $("#chat-order-add #chat").val(""); + $("#document-send-order").html(""); + } else { + $("#chat-order-add .errorEmptyMessage").show(); + } + + }); +} + +function chatTeamsInit() { + $("#add-team-chat-message").on('click', function (e) { + e.preventDefault(); + var chatMessage = $("#team-chat-form #chatText").val(); + // var recipentId = $("#team-chat-form #recipentTeamId").val(); + var senderId = $("#team-chat-form #senderTeamId").val(); + var teamId = $("#team-chat-form #teamId").val(); + // var orderId = $("#team-chat-form #orderTeamId").val(); + var documentSendIds = $("#documentSendIds").val(); + var teamIds = $("#team-chat-form #teamIds").val(); + var sendLinks = $("#document-send a"); + if (chatMessage || sendLinks.length > 0) { + var sendLinkIds = ""; + var documentLinks = ""; + var documentAttachFiles = ""; + $.each(sendLinks, function (i, v) { + sendLinkIds += $(this).attr('data-id') + ';'; + documentLinks += 'Приложенный файл. скачать:
    ' + $(this).text() + '
    '; + documentAttachFiles += '
  • ' + + '' + $(this).text() + '' + + '
  • '; + + }); + socket.send_message({ + "format_type": "add_message_team", + "data": { + "sender_id": senderId, + // "recipent_id": recipentId, + "chat_message": chatMessage, + "team_id": teamId, + "team_ids": teamIds, + // "order_id": orderId, + "document_send_links": sendLinkIds, + "document_data": { + "document_links": documentLinks, + "document_attach_files": documentAttachFiles, + } + } + }); + + $("#team-chat-form #chatText").val(""); + $("#document-send").html(""); + $("#documentSendIds").val(""); + } else { + $("#team-chat-form .errorEmptyMessage").show(); + } + }); +} + + +export {chatContactsInit, chatOrdersInit, chatTeamsInit} \ No newline at end of file diff --git a/assets/js/src/chat/documents.js b/assets/js/src/chat/documents.js new file mode 100644 index 0000000..5045aec --- /dev/null +++ b/assets/js/src/chat/documents.js @@ -0,0 +1,157 @@ +import {getCookie} from '../utils' + +function uploadDocumentsContactInit() { + $("#upload-document-contact").bind('fileuploadsubmit', function (e, data) { + data.formData = { + sender: $("#contact-chat-form #senderContactId").val(), + recipent: $("#contact-chat-form #recipentContactId").val(), + } + + }); + + $('#upload-document-contact').fileupload({ + url: '/chat/create/', + crossDomain: false, + beforeSend: function (xhr, settings) { + // console.log("Upload form data -->", this.formData); + $('#progress .progress-bar').css( + 'width', + '0%' + ); + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + done: function (e, data) { + $.each(data.result.files, function (index, file) { + var htmlImg = ''; + var document_send = $(htmlImg).appendTo("#document-send-contact"); + }); + }, + fail: function (e) { + console.log(e); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .progress-bar').css( + 'width', + progress + '%' + ); + } + }).prop('disabled', !$.support.fileInput) + .parent().addClass($.support.fileInput ? undefined : 'disabled'); +} + +function uploadDocumentsOrderInit() { + $("#upload-document-order").bind('fileuploadsubmit', function (e, data) { + data.formData = { + sender: $("#chat-order-add #senderId").val(), + recipent: $("#chat-order-add #recipentId").val(), + order: $("#chat-order-add #orderId").val(), + } + // console.log(data.formData); + }); + + $('#upload-document-order').fileupload({ + url: '/chat/create/', + crossDomain: false, + beforeSend: function (xhr, settings) { + $('#progress .progress-bar').css( + 'width', + '0%' + ); + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + dataType: 'json', + done: function (e, data) { + $.each(data.result.files, function (index, file) { + var htmlImg = ''; + var document_send = $(htmlImg).appendTo("#document-send-order"); + }); + }, + fail: function (e) { + console.log(e); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .progress-bar').css( + 'width', + progress + '%' + ); + } + }).prop('disabled', !$.support.fileInput) + .parent().addClass($.support.fileInput ? undefined : 'disabled'); +} + +function uploadDocumentsTeamInit() { + $("#upload-document-team").bind('fileuploadsubmit', function (e, data) { + data.formData = { + sender: $("#team-chat-form #senderTeamId").val(), + recipent: $("#team-chat-form #recipentTeamId").val(), + order: $("#team-chat-form #orderTeamId").val(), + team: $("#team-chat-form #teamId").val(), + }; + // console.log(data.formData); + }); + + $('#upload-document-team').fileupload({ + url: '/chat/create/', + crossDomain: false, + beforeSend: function (xhr, settings) { + $('#progress .progress-bar').css( + 'width', + '0%' + ); + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); + }, + dataType: 'json', + done: function (e, data) { + $.each(data.result.files, function (index, file) { + var currentValue = $("#documentSendIds").val(); + currentValue += file.id + ';'; + $("#documentSendIds").val(currentValue); + var htmlImg = ''; + var document_send = $(htmlImg).appendTo("#document-send"); + }); + }, + fail: function (e) { + console.log(e); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .progress-bar').css( + 'width', + progress + '%' + ); + } + }).prop('disabled', !$.support.fileInput) + .parent().addClass($.support.fileInput ? undefined : 'disabled'); +} + +function bindRemoveDocuments() { + $('.tab-content').on('click', '.remove-document', function (e) { + e.preventDefault(); + var dataId = $(this).attr('data-id'); + var _this = $(this); + $.ajax({ + url: '/api/documents/' + dataId + '/', + type: 'PATCH', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: {is_delete: true}, + dataType: 'json', + success: function (json) { + _this.parent().remove(); + // console.log(json); + }, + error: function (e, jqxhr) { + console.log(jqxhr); + } + }); + }); +} + +export {uploadDocumentsContactInit, uploadDocumentsOrderInit, uploadDocumentsTeamInit, bindRemoveDocuments} \ No newline at end of file diff --git a/assets/js/src/chat/formats/receive_message_formats.py b/assets/js/src/chat/formats/receive_message_formats.py new file mode 100644 index 0000000..e8d7798 --- /dev/null +++ b/assets/js/src/chat/formats/receive_message_formats.py @@ -0,0 +1,9 @@ +write_message = {'msg': "", + 'msg_time': ".strftime('%Y-%m-%d %H:%M:%S')", + 'order_id': "", + 'recipent_id': "", + 'sender_id': "", + 'sender_name': "", + 'answer_type': "", + 'docs_attach': "", + } diff --git a/assets/js/src/chat/formats/send_message_formats.js b/assets/js/src/chat/formats/send_message_formats.js new file mode 100644 index 0000000..72bfd0f --- /dev/null +++ b/assets/js/src/chat/formats/send_message_formats.js @@ -0,0 +1,36 @@ +//1-approve_stages +var approve_stages = { + "format_type": "approve_stages", + "data": { + "sender_id": "", + "recipent_id": "", + "order_id": "", + "msg": "Заказчик зарезервировал сумму для этапов " + json.stages, + } +}; + +//2-add_message_order +var add_message_order = { + "format_type": "add_message_order", + "data": { + "sender_id": "", + "recipent_id": "", + "chat_message": "", + "order_id": "", + "document_send_links": "id;id;id", + "document_data": { + "document_links": 'links/document_link_tmpl.html(...copy)', + "document_attach_files": 'links/document_attach_file_tmpl.html(...copy)', + } + } + +}; + +//3-add_message_contact +var add_message_contact = add_message_order; + +//4-add_message_team +var add_message_team = add_message_order; +add_message_team["team_id"] = ""; +add_message_team["team_ids"] = "id;id;id"; + diff --git a/assets/js/src/chat/loaders.js b/assets/js/src/chat/loaders.js new file mode 100644 index 0000000..7b76cb6 --- /dev/null +++ b/assets/js/src/chat/loaders.js @@ -0,0 +1,28 @@ +import stage_tmpl from './templates/stage_tmpl.html' +import stage_approved_tmpl from './templates/stage_approved_tmpl.html' +import reserved_tmpl from './templates/reserved_tmpl.html' +import message_tmpl from './templates/message_tmpl.html' +import work_in_process_tmpl from './templates/work_in_process_tmpl.html' +import bntCompleteStage_tmpl from './templates/buttons/bntCompleteStage_tmpl.html' +import btnSendReview_tmpl from './templates/buttons/btnSendReview_tmpl.html' +import document_attach_file_tmpl from './templates/links/document_attach_file_tmpl.html' +import note_tmpl from './templates/note_tmpl.html' + +function loadTemplate(template_name) { + let templates = { + stage_tmpl: stage_tmpl, + stage_approved_tmpl: stage_approved_tmpl, + reserved_tmpl: reserved_tmpl, + message_tmpl: message_tmpl, + work_in_process_tmpl: work_in_process_tmpl, + bntCompleteStage_tmpl: bntCompleteStage_tmpl, + btnSendReview_tmpl: btnSendReview_tmpl, + document_attach_file_tmpl: document_attach_file_tmpl, + note_tmpl: note_tmpl, + }; + + if (!templates[template_name]) throw new Error(`Template ${template_name} does not exist`); + return templates[template_name] +} + +export {loadTemplate} \ No newline at end of file diff --git a/assets/js/src/chat/messageCounters.js b/assets/js/src/chat/messageCounters.js new file mode 100644 index 0000000..b4169de --- /dev/null +++ b/assets/js/src/chat/messageCounters.js @@ -0,0 +1,43 @@ +function recalculateTabsCounter() { + // let tabs = [$('#count-tab-contact'), $('#count-tab-order'), $('#count-tab-team')] + let tabs = [$('#tab1'), $('#tab2'), $('#tab3')]; + let total_messages_count = 0; + for (let tab of tabs){ + let count_sum = Array.from((tab.find('.js-count').map((i, el)=>parseInt($(el).html())))).reduce((a, b) => a + b, 0); + let $tab_counter = $(`a[href="#${tab.attr('id')}"]`).find('.count-tab'); + $tab_counter.html(count_sum); + total_messages_count += count_sum; + // console.log($tab_counter, 'new value -->', count_sum); + } + let $header_counter = $('.js-all-messages'); + $header_counter.html(total_messages_count); +} + +function countPlus(message, place) { + /** + * Увеличиваем счетчик соответствующий сообщению(message) + */ + // console.log("MESSAGE = ", message); + let $container; + if (message.answer_type == "add_message_contact"){ + $container = $(`.contact-count-${message.sender_id}`); + } else if (message.answer_type == "add_message_order"){ + $container = $(`#count-order-${message.order_id}`); + } else if (message.answer_type == "add_message_team") { + $container = $(`#count-team-${message.team_id}`); + } + // console.log("container = ", $container); + $container.html(parseInt($container.html()) + 1); + recalculateTabsCounter(); +} + +function onClickCardWithCount($card){ + /** + * При нажатии на карточку со счетчиком новых сообщений + */ + // console.log('Обнулем счетчик ', $card); + $card.find('.js-count').html(0); + recalculateTabsCounter(); +} + +export {countPlus, onClickCardWithCount} \ No newline at end of file diff --git a/assets/js/src/chat/notes.js b/assets/js/src/chat/notes.js new file mode 100644 index 0000000..1ec480b --- /dev/null +++ b/assets/js/src/chat/notes.js @@ -0,0 +1,77 @@ +import {loadTemplate} from './loaders' +var note_tmpl = loadTemplate('note_tmpl'); + +function bindContractorNotes() { + $('#add-note-contractor').on('click', function (e) { + e.preventDefault(); + $.ajax({ + url: '/api/note/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: $("#add-form-contractor-note").serialize(), + dataType: 'json', + success: function (json) { + // console.log(json); + $("#add-form-contractor-note #chat2").val(""); + let li = note_tmpl({text: json.text}); + $(li).appendTo(".contractor-notes-block"); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); + }); +} + +function bindOrderNotes() { + $('#add-note-button').on('click', function (e) { + e.preventDefault(); + $.ajax({ + url: '/api/note/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: $("#add-form-order-note").serialize(), + dataType: 'json', + success: function (json) { + // $("
  • " + json.text + "
  • ").appendTo(".order-notes-block"); + let li = note_tmpl({text: json.text}); + $(li).appendTo(".order-notes-block"); + $("#add-form-order-note #chat2").val(""); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); +}); +} + +function bindTeamNotes() { + $('#add-team-note-button').on('click', function (e) { + e.preventDefault(); + $.ajax({ + url: '/api/note/', + type: 'POST', + beforeSend: function (xhr) { + xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')) + }, + data: $("#add-form-team-note").serialize(), + dataType: 'json', + success: function (json) { + $("
  • " + json.text + "
  • ").appendTo(".team-notes-block"); + $("#add-form-team-note #chat2").val(""); + }, + error: function (e) { + console.log('error'); + console.log(e); + } + }); +}); +} + +export {bindContractorNotes, bindOrderNotes, bindTeamNotes} \ No newline at end of file diff --git a/assets/js/src/chat/parts.js b/assets/js/src/chat/parts.js new file mode 100644 index 0000000..0d06e61 --- /dev/null +++ b/assets/js/src/chat/parts.js @@ -0,0 +1,27 @@ +import {getCookie} from '../utils' + +function restoreTabFromHash() { + var currentHash = URI(location.href).hash(); + if (currentHash.indexOf("#order") == 0) { + $("a[href='#tab2']").trigger('click'); + // console.log("click on ", "#orderBlock" + currentHash.replace("#order", "")); + let obj_id = currentHash.replace("#order", ""); + // console.log("obj_id = ", obj_id); + if (obj_id) { + $("#orderBlock" + currentHash.replace("#order", "")).trigger('click'); + } else { + $('.order-block').first().trigger('click'); + } + + } else if (currentHash.indexOf("#user") == 0) { + $("a[href='#tab1']").trigger('click'); + } else if (currentHash.indexOf("#teamorder") == 0 || currentHash.indexOf("#myteam") == 0) { + $("a[href='#tab3']").trigger('click'); + } else { + $("a[href='#tab1']").trigger('click'); + } +} + + + +export {restoreTabFromHash} \ No newline at end of file diff --git a/assets/js/src/chat/templates/buttons/bntCompleteStage_tmpl.html b/assets/js/src/chat/templates/buttons/bntCompleteStage_tmpl.html new file mode 100644 index 0000000..90a0edb --- /dev/null +++ b/assets/js/src/chat/templates/buttons/bntCompleteStage_tmpl.html @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/assets/js/src/chat/templates/buttons/btnSendReview_tmpl.html b/assets/js/src/chat/templates/buttons/btnSendReview_tmpl.html new file mode 100644 index 0000000..df81dfc --- /dev/null +++ b/assets/js/src/chat/templates/buttons/btnSendReview_tmpl.html @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/assets/js/src/chat/templates/links/document_attach_file_tmpl.html b/assets/js/src/chat/templates/links/document_attach_file_tmpl.html new file mode 100644 index 0000000..73fd89e --- /dev/null +++ b/assets/js/src/chat/templates/links/document_attach_file_tmpl.html @@ -0,0 +1,12 @@ + +
  • + ${this.text} +
    +
  • + + \ No newline at end of file diff --git a/assets/js/src/chat/templates/links/document_link_tmpl.html b/assets/js/src/chat/templates/links/document_link_tmpl.html new file mode 100644 index 0000000..f82849b --- /dev/null +++ b/assets/js/src/chat/templates/links/document_link_tmpl.html @@ -0,0 +1,7 @@ + +
    + Приложенный файл. скачать:
    + + $(this.text) + +
    \ No newline at end of file diff --git a/assets/js/src/chat/templates/message_tmpl.html b/assets/js/src/chat/templates/message_tmpl.html new file mode 100644 index 0000000..c7197e1 --- /dev/null +++ b/assets/js/src/chat/templates/message_tmpl.html @@ -0,0 +1,7 @@ + +
    +
    +

    ${this.senderName}

    ${this.message.created} +
    +

    ${this.message.text}

    +
    \ No newline at end of file diff --git a/assets/js/src/chat/templates/note_tmpl.html b/assets/js/src/chat/templates/note_tmpl.html new file mode 100644 index 0000000..e13300f --- /dev/null +++ b/assets/js/src/chat/templates/note_tmpl.html @@ -0,0 +1,6 @@ +
    +
  • + ${this.text} +
  • +
    +
    diff --git a/assets/js/src/chat/templates/reserved_tmpl.html b/assets/js/src/chat/templates/reserved_tmpl.html new file mode 100644 index 0000000..411014b --- /dev/null +++ b/assets/js/src/chat/templates/reserved_tmpl.html @@ -0,0 +1,5 @@ + + +
  • Сумма за этап ${this.stage.pos} +
    ${this.reserved_name}
    +
  • \ No newline at end of file diff --git a/assets/js/src/chat/templates/stage_approved_tmpl.html b/assets/js/src/chat/templates/stage_approved_tmpl.html new file mode 100644 index 0000000..31f12be --- /dev/null +++ b/assets/js/src/chat/templates/stage_approved_tmpl.html @@ -0,0 +1,29 @@ + +
    +
    +
    + ЭТАП ${this.stage_num} +
    +
    + ${this.stage_status} +
    +
    +
    + +
    + ${this.stage.name} +
    + Результат этапа +
    + ${this.stage.result} +
    + Цена +
    + ${this.stage.cost} ₽ +
    + Срок +
    + до ${this.stage.term} +
    + +
    \ No newline at end of file diff --git a/assets/js/src/chat/templates/stage_tmpl.html b/assets/js/src/chat/templates/stage_tmpl.html new file mode 100644 index 0000000..ac21205 --- /dev/null +++ b/assets/js/src/chat/templates/stage_tmpl.html @@ -0,0 +1,29 @@ + +
    +

    ЭТАП ${this.stage_num}

    +
    + + +

    + + +

    + +

    + + + + +

    + + +

    +
    +
    \ No newline at end of file diff --git a/assets/js/src/chat/templates/work_in_process_tmpl.html b/assets/js/src/chat/templates/work_in_process_tmpl.html new file mode 100644 index 0000000..f14d97c --- /dev/null +++ b/assets/js/src/chat/templates/work_in_process_tmpl.html @@ -0,0 +1,10 @@ + +
    + В работе: ${this.stage.name}
    + Результат этапа: ${this.stage.result}
    + Срок сдачи: ${this.stage.term}
    + ${this.stage.cost} р +
    + ${this.note_text} +
    +
    \ No newline at end of file diff --git a/assets/js/src/chat/utils_debug.js b/assets/js/src/chat/utils_debug.js new file mode 100644 index 0000000..7ca565b --- /dev/null +++ b/assets/js/src/chat/utils_debug.js @@ -0,0 +1,6 @@ +function ws_print(...messages) { + let message = messages.join(' '); + console.log(`%c WS: ${message}`, 'background: white; color: blue'); +} + +export {ws_print} \ No newline at end of file diff --git a/assets/js/src/chat/wsChatConnect.js b/assets/js/src/chat/wsChatConnect.js new file mode 100644 index 0000000..5b8db0b --- /dev/null +++ b/assets/js/src/chat/wsChatConnect.js @@ -0,0 +1,114 @@ +import {loadTemplate} from './loaders' +import {countPlus} from './messageCounters' + +function getUserPlace() { + /** + * Определяем в какой закладке Чата пользователь + */ + let hash = location.hash; + let tab, id; + + for (let str of ["user", "order", "myteam"]) { + if (hash.indexOf(`#${str}`) != -1) { + tab = str; + id = hash.replace(`#${str}`, ''); + } + } + return {tab, id} +} + +function checkMessageInPlace(message, place) { + /** + * Проверяем, направлено ли входящее сообщение на текущую вкладку пользователя + */ + // message.answer_type=place.tab + let eq = ['add_message_contact=user', 'add_message_order=order', 'add_message_team=myteam', 'approve_stages=order']; + // console.log([message.answer_type, place.tab].join('=')); + // console.log(message.order_id, '==', place.id, message.order_id == place.id); + if ((eq.indexOf([message.answer_type, place.tab].join('=')) != -1) && + ((message.order_id == place.id) || (message.recipent_id == place.id) || (message.sender_id == place.id) || (message.team_id == place.id))) { + + return true + } + return false +} + +function connect() { + wsConnect.then(function (_socket) { + socket = _socket; + // Onmessage in Chat page + socket.addEventListener("message", function (event) { + var data = JSON.parse(event.data); + print.ws_print("new message on Chat page"); + console.log(", message =", data); + + let user_place = getUserPlace(); + // console.log("User place ", place.tab, place.id); + + if (checkMessageInPlace(data, user_place)) { + console.log("Сообщение принято открытым чатом"); + let chat_container_selectors = { + "user": "#message-chat-space", + "order": "#message-chat-order-space", + "myteam": "#message-chat-team-space", + }; + let documents_container_seletors = { + "user": "#documentSpace", + "order": "#documentOrderSpace", + "myteam": "#documentTeamSpace", + }; + let $chat_container = $(chat_container_selectors[user_place.tab]); + let $documents_container = $(documents_container_seletors[user_place.tab]); + var classMessage = 'youChat'; + var senderName = 'Вы'; + if (data.sender_id != userId) { + senderName = data.sender_name; + classMessage = ''; + } + if (data.is_system){ + senderName = 'Системное'; + classMessage = 'systemChat' + } + + let chat_message = loadTemplate('message_tmpl')({ + className: classMessage, + senderName: senderName, + message: {created: data.msg_time, text: data.msg} + }); + $chat_container.append(chat_message); + $chat_container.scrollTop($chat_container.prop("scrollHeight")); + + $documents_container.append(data.docs_attach); + + if (data.answer_type == 'approve_stages') { + window.chatController.statesController.redraw(); + } + + } else { + console.log("Сообщение учтено счетчиком"); + countPlus(data, user_place) + } + + }); + + socket.addEventListener("close", function () { + console.error("Connection Lost"); + connect(); + }); + + socket.send_message = function (messageData) { + console.log('send message -->', messageData); + socket.send(JSON.stringify(messageData)); + }; + + socket.send_stages_approve = function (messageData) { + // TODO: Пометить сообщения как "системные" + socket.send(JSON.stringify(messageData)); + }; + }); + wsConnect.catch(function (reason) { + console.error("Server is not available", reason) + }) +} + +export {connect} \ No newline at end of file diff --git a/assets/js/src/chat_contractor_oop.js b/assets/js/src/chat_contractor_oop.js new file mode 100644 index 0000000..4bb146d --- /dev/null +++ b/assets/js/src/chat_contractor_oop.js @@ -0,0 +1,63 @@ +import {ChatPageController} from './chat/ChatContractorPageController' +import { + bindOrders, + bindArbitrationSend, + bindOnTabs, + bindUserContacts, + bindGetUserMessages, + bindTeams, + bindDeleteContact +} from './chat/BINDS' + +import { + uploadDocumentsContactInit, + uploadDocumentsOrderInit, + uploadDocumentsTeamInit, + bindRemoveDocuments +} from './chat/documents' + +import {bindContractorNotes, bindOrderNotes, bindTeamNotes} from './chat/notes' + +import {restoreTabFromHash} from './chat/parts' + +import {bindArchiveProjects} from './chat/archiveProjects' + +import {chatContactsInit, chatOrdersInit, chatTeamsInit} from './chat/chats' +import {connect} from './chat/wsChatConnect' + +window.connect = connect; +window.socket = undefined; + +$(function () { + bindArbitrationSend(); + window.onhashchange = function (e) { + $('a[data-toggle="tab"][href="#' + location.hash.slice(1) + '"]').trigger("click"); + }; + window.chatController = new ChatPageController(); + bindOrders(); + bindTeams(); + bindOnTabs(); + bindUserContacts(); + bindGetUserMessages(); + bindArchiveProjects(); + bindDeleteContact(); + + // Chats + chatContactsInit(); + chatOrdersInit(); + chatTeamsInit(); + + //Documents + uploadDocumentsContactInit(); + uploadDocumentsOrderInit(); + uploadDocumentsTeamInit(); + bindRemoveDocuments(); + + //Notes + bindContractorNotes(); + bindOrderNotes(); + bindTeamNotes(); + + //restore + restoreTabFromHash(); +}); \ No newline at end of file diff --git a/assets/js/src/chat_customer_oop.js b/assets/js/src/chat_customer_oop.js new file mode 100644 index 0000000..293589b --- /dev/null +++ b/assets/js/src/chat_customer_oop.js @@ -0,0 +1,47 @@ +import {ChatPageController} from './chat/ChatCustomerPageController' +import { + bindOrders, + bindArbitrationSend, + bindOnTabs, + bindUserContacts, + bindGetUserMessages, + bindDeleteContact +} from './chat/BINDS' + +import {restoreTabFromHash} from './chat/parts' + +import {chatContactsInit, chatOrdersInit} from './chat/chats' +import {connect} from './chat/wsChatConnect' + +import {bindArchiveProjects} from './chat/archiveProjects' + +window.connect = connect; +window.socket = undefined; + +$(function () { + $('body').on('focus', ".term-picker", function () { + $(this).datepicker({ + minDate: 0, + }); + }); + + bindArbitrationSend(); + window.onhashchange = function (e) { + // console.log("Change Hash!!! ", 'a[data-toggle="tab"][href="#' + location.hash.slice(1) + '"]'); + $('a[data-toggle="tab"][href="#' + location.hash.slice(1) + '"]').trigger("click"); + }; + + window.chatController = new ChatPageController(); + bindOrders(); + bindOnTabs(); + restoreTabFromHash(); + bindUserContacts(); + bindGetUserMessages(); + bindArchiveProjects(); + bindDeleteContact(); + + //Chats + chatContactsInit(); + chatOrdersInit(); + +}); \ No newline at end of file diff --git a/assets/js/src/debugUtilsInit.js b/assets/js/src/debugUtilsInit.js new file mode 100644 index 0000000..7f91be3 --- /dev/null +++ b/assets/js/src/debugUtilsInit.js @@ -0,0 +1,5 @@ +import {ws_print} from './chat/utils_debug' + +// DEBUG +window.print = {}; +window.print.ws_print = ws_print; \ No newline at end of file diff --git a/assets/js/src/init_customer_project_create.js b/assets/js/src/init_customer_project_create.js index aff853c..9ab0c0d 100644 --- a/assets/js/src/init_customer_project_create.js +++ b/assets/js/src/init_customer_project_create.js @@ -115,8 +115,10 @@ $(function () { }else{ //Если перешли со страницы профиля по кнопке "Добавить заказ" let id = window.location.hash.replace("#", ""); - if (id) sb_realty_top.setElementById(id); - select_realty.add(id); + if (id) { + sb_realty_top.setElementById(id); + select_realty.add(id); + } } }); select_realty.on("add", (args)=> { diff --git a/assets/js/src/seeds/read_more.js b/assets/js/src/seeds/read_more.js index a6b12e0..36d6320 100644 --- a/assets/js/src/seeds/read_more.js +++ b/assets/js/src/seeds/read_more.js @@ -5,12 +5,6 @@ function readMoreInit() { $target.siblings(".complete").toggle(); $target.toggleClass("less"); }); - - // $(".more").toggle(function () { - // $(this).text("less..").siblings(".complete").show(); - // }, function () { - // $(this).text("more..").siblings(".complete").hide(); - // }); } export {readMoreInit} \ No newline at end of file diff --git a/assets/js/chat.js b/assets/js/trash/chat.js similarity index 88% rename from assets/js/chat.js rename to assets/js/trash/chat.js index 10ead9f..c852baa 100644 --- a/assets/js/chat.js +++ b/assets/js/trash/chat.js @@ -40,9 +40,9 @@ var SocketHandler = function () { var intervalId; sock.onopen = function () { console.log("Start connect"); - intervalId = setInterval(function () { - sock.send('{"dummy": 1}'); - }, 15000); + // intervalId = setInterval(function () { + // sock.send('{"dummy": 1}'); + // }, 15000); }; sock.onmessage = function (event) { @@ -140,68 +140,68 @@ $(function () { } var currentHash = URI(location.href).hash(); - $('a[data-toggle="tab"]').on('show.bs.tab', function (e) { - console.log("TAB!"); - var activeTab = $(this).attr('href').substring(1); - var liveHash = URI(location.href).hash(); - - switch (activeTab) { - case 'tab1': - setTimeout(function () { - if (liveHash.indexOf("#user") == 0) { - var userHashId = liveHash.replace("#user", ""); - $("#userBlock" + userHashId).trigger('click'); - } else { - $(".user-block").first().trigger('click'); - } - }, 100); - break; - - case 'tab2': - console.log("tab2"); - updateCounts(); - setTimeout(function () { - if (liveHash.indexOf("#order") == 0) { - var ordHashId = liveHash.replace("#order", ""); - $("#orderBlock" + ordHashId).trigger('click'); - } else { - $(".order-block").first().trigger('click'); - } - }, 100); - break; - - case 'tab3': - setTimeout(function () { - if (liveHash.indexOf("#teamorder") == 0) { - var teamHashId = liveHash.replace("#teamorder", ""); - $("#teamOrderBlock" + teamHashId).trigger('click'); - } else if (liveHash.indexOf("#myteam") == 0) { - var teamHashId = liveHash.replace("#myteam", ""); - $("#teamMyBlock" + teamHashId).trigger('click'); - } else { - var firstTeamBlock = $(".team-block").first(); - var firstTeamOrder = $(".team-order-block").first(); - if (firstTeamOrder.length == 1) { - firstTeamOrder.trigger('click'); - } else if (firstTeamBlock.length == 1) { - firstTeamBlock.trigger('click'); - } - } - }, 100); - - } - - }); - - if (currentHash.indexOf("#order") == 0) { - $("a[href='#tab2']").trigger('click'); - } else if (currentHash.indexOf("#user") == 0) { - $("a[href='#tab1']").trigger('click'); - } else if (currentHash.indexOf("#teamorder") == 0 || currentHash.indexOf("#myteam") == 0) { - $("a[href='#tab3']").trigger('click'); - } else { - $("a[href='#tab1']").trigger('click'); - } + // $('a[data-toggle="tab"]').on('show.bs.tab', function (e) { + // console.log("TAB!"); + // var activeTab = $(this).attr('href').substring(1); + // var liveHash = URI(location.href).hash(); + // + // switch (activeTab) { + // case 'tab1': + // setTimeout(function () { + // if (liveHash.indexOf("#user") == 0) { + // var userHashId = liveHash.replace("#user", ""); + // $("#userBlock" + userHashId).trigger('click'); + // } else { + // $(".user-block").first().trigger('click'); + // } + // }, 100); + // break; + // + // case 'tab2': + // console.log("tab2"); + // updateCounts(); + // setTimeout(function () { + // if (liveHash.indexOf("#order") == 0) { + // var ordHashId = liveHash.replace("#order", ""); + // $("#orderBlock" + ordHashId).trigger('click'); + // } else { + // $(".order-block").first().trigger('click'); + // } + // }, 100); + // break; + // + // case 'tab3': + // setTimeout(function () { + // if (liveHash.indexOf("#teamorder") == 0) { + // var teamHashId = liveHash.replace("#teamorder", ""); + // $("#teamOrderBlock" + teamHashId).trigger('click'); + // } else if (liveHash.indexOf("#myteam") == 0) { + // var teamHashId = liveHash.replace("#myteam", ""); + // $("#teamMyBlock" + teamHashId).trigger('click'); + // } else { + // var firstTeamBlock = $(".team-block").first(); + // var firstTeamOrder = $(".team-order-block").first(); + // if (firstTeamOrder.length == 1) { + // firstTeamOrder.trigger('click'); + // } else if (firstTeamBlock.length == 1) { + // firstTeamBlock.trigger('click'); + // } + // } + // }, 100); + // + // } + // + // }); + + // if (currentHash.indexOf("#order") == 0) { + // $("a[href='#tab2']").trigger('click'); + // } else if (currentHash.indexOf("#user") == 0) { + // $("a[href='#tab1']").trigger('click'); + // } else if (currentHash.indexOf("#teamorder") == 0 || currentHash.indexOf("#myteam") == 0) { + // $("a[href='#tab3']").trigger('click'); + // } else { + // $("a[href='#tab1']").trigger('click'); + // } // Информация о заказе $(".messageBlock").on('click','.full-order-info', function (e) { @@ -276,6 +276,7 @@ $(function () { }); }); + // "Оплата с сайта" (copy) $("#paymentfromSite").on('click', function () { var sum = $("#stageSumPay").val(); var stages = $("#stagesIds").val(); @@ -315,7 +316,7 @@ $(function () { }) }); - //Удаление документа + //Удаление документа(copy) $('.tab-content').on('click', '.remove-document', function (e) { e.preventDefault(); var dataId = $(this).attr('data-id'); @@ -338,7 +339,7 @@ $(function () { }); }); - // Вытащить сообщения для конактов + // Вытащить сообщения для конактов(copy) $('.user-block').on('click', function () { var newCount = parseInt($("#count-tab-contact").text()); var contactId = $(this).attr('data-id'); @@ -437,6 +438,7 @@ $(function () { }); + // Удалить контакт из "Личные" (copy) $('.deleteMess').on('click', function (e) { e.preventDefault(); e.stopPropagation(); @@ -512,6 +514,7 @@ $(function () { }); + // Добавление заметок Исполнителем (copy) $('#add-note-contractor').on('click', function (e) { e.preventDefault(); $.ajax({ @@ -534,7 +537,7 @@ $(function () { }); }); - //Добавить заметку. + //Добавить заметку Заказ (copy) $('#add-note-button').on('click', function (e) { e.preventDefault(); $.ajax({ @@ -556,7 +559,7 @@ $(function () { }); }); - //Добавить заметку. + //Добавить заметку Группа (copy) $('#add-team-note-button').on('click', function (e) { e.preventDefault(); $.ajax({ @@ -578,7 +581,7 @@ $(function () { }); }); - // Добавление сообщения для заказа. + // Добавление сообщения для заказа(copy) $('#order-chat-add-message').on('click', function (e) { e.preventDefault(); var chatMessage = $("#chat-order-add #chat").val(); @@ -620,7 +623,7 @@ $(function () { }); - // Добавление сообщения для контакта + // Добавление сообщения для контакта(copy) $('#contact-chat-add-message').on('click', function (e) { e.preventDefault(); var chatMessage = $("#chat").val(); @@ -664,7 +667,7 @@ $(function () { }); - // Добавление сообщения в арбитраж + // Добавление сообщения в арбитраж (copy) $('#order-arbitration-add').on('click', function (e) { e.preventDefault(); e.stopPropagation(); @@ -691,6 +694,7 @@ $(function () { }); }); + //Загрузка документов Order(copy) $("#upload-document-order").bind('fileuploadsubmit', function (e, data) { data.formData = { sender: $("#chat-order-add #senderId").val(), @@ -700,7 +704,7 @@ $(function () { console.log(data.formData); }); - //Загрузка документов + // + Загрузка документов Order(copy) $('#upload-document-order').fileupload({ url: '/chat/create/', crossDomain: false, @@ -734,6 +738,7 @@ $(function () { }).prop('disabled', !$.support.fileInput) .parent().addClass($.support.fileInput ? undefined : 'disabled'); //Загрузка документов + // + Загрузка документов Contact(copy) $("#upload-document-contact").bind('fileuploadsubmit', function (e, data) { data.formData = { sender: $("#contact-chat-form #senderContactId").val(), @@ -742,6 +747,7 @@ $(function () { }); + //Загрузка документов Contact(copy!) $('#upload-document-contact').fileupload({ url: '/chat/create/', crossDomain: false, @@ -783,7 +789,7 @@ $(function () { $("#text-new").val(""); }); - // Добавление отзыва + // Добавление отзыва(complete) $('#order-review-add').on('click', function (e) { e.preventDefault(); e.stopPropagation(); @@ -820,7 +826,7 @@ $(function () { }); }); - // Нажимаем на кнопку архивные сообщения + // Нажимаем на кнопку архивные сообщения(complete) $("#trashed-button").on('click',function(e){ e.preventDefault(); var state = $(this).attr('data-show'); @@ -833,31 +839,6 @@ $(function () { $("#archive-space").show(); $("#show-archive-label").show(); - //$.ajax({ - // url: '/api/orders/', - // type: 'GET', - // dataType: 'json', - // success: function (json) { - // console.log(json.results); - // $.each(json.results, function (i, v) { - // - // var temp = '
    ' + - // '

    ' + v.project.name + '

    ' + - // 'Исполнитель:'+ v.contractor_name +'

    ' + - // '' + - // 'Полное описание заказа
    '; - // - // trashedOrderHtml += temp; - // }); - // $("#trashed-orders").html(trashedOrderHtml); - // - // }, - // error: function (e, jqxhr) { - // console.log(e); - // } - //}); - }else { $(this).attr('data-show','true'); $(this).text("Показать архивные заказы"); @@ -868,7 +849,7 @@ $(function () { }); - // Нажимаем на заказ в архмвных заказах + // Нажимаем на заказ в архмвных заказах(complete) $(".messageBlock").on('click','.trashedOrderBlock',function(){ $("#chat-order-add").css("display", "none"); $('.order-block, .trashedOrderBlock').each(function () { diff --git a/assets/js/chat_contractor.js b/assets/js/trash/chat_contractor.js similarity index 85% rename from assets/js/chat_contractor.js rename to assets/js/trash/chat_contractor.js index 871a2af..e666cb7 100644 --- a/assets/js/chat_contractor.js +++ b/assets/js/trash/chat_contractor.js @@ -1,3 +1,51 @@ +/***TEMPLATES***/ +var wrapper_btn_tmpl = (btn_tmpl) => + ` +
    ${btn_tmpl}
    +`; + +var btn_tmpl_approve = (args = {}) => + ` + +`; + +var btn_tmpl_change = (args = {}) => + ` + +`; + +var btn_tmpl_refuse = (args = {}) => + ` + +`; + +function replaceButtons($container, buttons_html = []) { + console.log("replace Buttons"); + $container.html(""); + for (var button_html of buttons_html) { + $container.append(button_html); + } +} + + $(function () { function dialog(message, yesCallback, notCallback) { @@ -19,6 +67,7 @@ $(function () { var url = '/chat/create/'; + // + Загрузка документов Team (complete) $("#upload-document-team").bind('fileuploadsubmit', function (e, data) { data.formData = { sender: $("#team-chat-form #senderTeamId").val(), @@ -29,7 +78,7 @@ $(function () { console.log(data.formData); }); - //Загрузка документов + //Загрузка документов Team (complete) $('#upload-document-team').fileupload({ url: url, crossDomain: false, @@ -49,7 +98,7 @@ $(function () { currentValue += file.id + ';'; $("#documentSendIds").val(currentValue); var htmlImg = ''; + '
    '; var document_send = $(htmlImg).appendTo("#document-send"); }); }, @@ -66,17 +115,17 @@ $(function () { }).prop('disabled', !$.support.fileInput) .parent().addClass($.support.fileInput ? undefined : 'disabled'); - // Согласование этапов + // "Согласовать" (complete) $("#order-stages").on('click', "#approve-stages", function (e) { e.preventDefault(); - var orderId = $(this).attr('data-order-id'); - var senderId = $(this).attr('data-sender-id'); - var recipentId = $(this).attr('data-recipent-id'); + var orderId = $(this).data('order-id'); + var senderId = $(this).data('sender-id'); + var recipentId = $(this).data('recipent-id'); var caption = "Вы действительно хотите согласовать этапы?"; confirm(caption, function () { $(".stage-block-approve").each(function () { - var stageId = $(this).attr('data-id'); + var stageId = $(this).data('id'); $.ajax({ //async: false, url: '/api/stages/' + stageId + '/', @@ -124,16 +173,17 @@ $(function () { }); - // Отказаться от этапов + // "Отправить на внесение изменений" (complete) $("#order-stages").on('click', "#cancel-stages", function (e) { + console.log("Отправить на внесение изменений"); e.preventDefault(); var senderId = $(this).attr('data-sender-id'); var recipentId = $(this).attr('data-recipent-id'); var orderId = $(this).attr('data-order-id'); var caption = "Вы действительно хотите отказаться от этапов?"; - confirm(caption,function() { + confirm(caption, function () { $(".stage-block-approve").each(function () { - var stageId = $(this).attr('data-id'); + var stageId = $(this).data('id'); $.ajax({ url: '/api/stages/' + stageId + '/', type: 'PATCH', @@ -165,7 +215,7 @@ $(function () { "msg": "Исполнитель отказался от текущих этапов " + orderId, } }); - }.bind(),caption); + }.bind(), caption); }); @@ -271,6 +321,7 @@ $(function () { }); + // Отображаем сообщения "Группы"(copy) $('.team-block').on('click', function () { $('.team-order-block, .team-block').each(function () { @@ -365,17 +416,19 @@ $(function () { }); - // Вытащить сообщения для чата заказа + // Заполняем страницу Заказа(complete) $('.order-block').on('click', function () { + console.log("Заполняем страницу Заказа"); $('.order-block').each(function () { $(this).removeClass('orAct'); }); $(this).addClass('orAct'); - var orderId = $(this).attr('data-id'); + var orderId = $(this).data('id'); location.hash = '#order' + orderId; - var recipentId = $(this).attr('data-recipent-id'); - var projectId = $(this).attr('data-project-id'); - var teamCurrentId = parseInt($(this).attr('data-team-id')); + var senderId = ''; + var recipentId = $(this).data('recipent-id'); + var projectId = $(this).data('project-id'); + var teamCurrentId = parseInt($(this).data('team-id')); var newCount = parseInt($("#count-tab-order").text()); var currNewCount = parseInt($(".order-count-" + orderId).text()); @@ -383,11 +436,11 @@ $(function () { $("#count-tab-order").text(resCount); $(".order-count-" + orderId).text(0); - if (teamCurrentId>0){ + if (teamCurrentId > 0) { $("#fromTeamId").val(teamCurrentId); $("#fromContractorId").val(""); - }else { - $("#fromTeamId").val("") + } else { + $("#fromTeamId").val(""); $("#fromContractorId").val(userId); } @@ -537,12 +590,36 @@ $(function () { if (statusNotAgreed) { - htmlInbox += ''; + // htmlInbox += wrapper_btn_tmpl( + // btn_tmpl_approve() + btn_tmpl_change() + btn_tmpl_refuse() + // ); + if (stagesResults[0] && stagesResults[0].status == 'send_approve') { + htmlInbox += + wrapper_btn_tmpl(btn_tmpl_approve({ + senderId: senderId, + recipentId: recipentId, + orderId: orderId + }) + + btn_tmpl_change({ + senderId: senderId, + recipentId: recipentId, + orderId: orderId + }) + + btn_tmpl_refuse({ + senderId: senderId, + recipentId: recipentId, + orderId: orderId + }) + ); + } else { + htmlInbox += wrapper_btn_tmpl(btn_tmpl_refuse({ + senderId: senderId, + recipentId: recipentId, + orderId: orderId + }) + ); + + } } } @@ -582,7 +659,7 @@ $(function () { } else { $("#leaveReview").hide(); } - }else{ + } else { $("#leaveReview").hide(); } }); @@ -590,6 +667,7 @@ $(function () { }); + // Закрыть этап (complete) $('#tab2').on('click', '.closeStage', function (e) { e.preventDefault(); var stageId = $(this).attr('data-stage-id'); @@ -623,7 +701,7 @@ $(function () { }); }); - //Добавить сообщение для исполнителей в группе + //Добавить сообщение для исполнителей в группе(copy) $("#add-team-chat-message").on('click', function (e) { e.preventDefault(); var chatMessage = $("#team-chat-form #chatText").val(); diff --git a/assets/js/chat_customer.js b/assets/js/trash/chat_customer.js similarity index 99% rename from assets/js/chat_customer.js rename to assets/js/trash/chat_customer.js index 7615ce7..5d50d28 100644 --- a/assets/js/chat_customer.js +++ b/assets/js/trash/chat_customer.js @@ -209,6 +209,7 @@ $(function () { htmlInbox = htmlInboxStage + htmlInbox; $("#order-stages").html(htmlInbox); $("#completeWork").hide(); + $("#completeWork").hide(); if (stagesInWork.length > 0) { $("#completeWork").show(); @@ -280,7 +281,7 @@ $(function () { }); }); - // Добавление этапов + // Добавление этапов(complete) $("#order-stages").on('click', "#addStagesForm", function (e) { e.preventDefault(); var currentOrderId = $(this).attr('data-order-id'); @@ -391,7 +392,7 @@ $(function () { }); -//Изменение счетчика + //Изменение счетчика(complete) $('#order-stages-tab').on('change', '#countStage', function () { var countStage = parseInt($(this).val()); var currentCountStage = $("#order-stages .numberStepp").length; @@ -431,7 +432,7 @@ $(function () { }); -// Для заказов все вытащить + // Для заказов все вытащить(complete) $('.order-block').on('click', function () { var newCount = parseInt($("#count-tab-order").text()); $("#chat-order-add").css("display", "block"); diff --git a/chat/chat.py b/chat/chat.py index 94cc6ff..8ee4175 100644 --- a/chat/chat.py +++ b/chat/chat.py @@ -22,8 +22,10 @@ class ChatHandler(websocket.WebSocketHandler): waiters = set() def open(self, *args, **kwargs): + print("open") self.user_id = kwargs.get('user_id', 1) self.waiters.add((self.user_id, self)) + print("num connection = ", len(self.waiters)) # @gen.coroutine def on_message(self, message): @@ -63,6 +65,7 @@ class ChatHandler(websocket.WebSocketHandler): team_ids_raw = message_data['data'].get('team_ids', None) message = message_data['data'].get('chat_message', None) docs_send_links = message_data['data'].get('document_send_links', None) + is_system = message_data['data'].get('is_system', False) if 'document_data' in message_data['data']: docs_links = message_data['data']['document_data'].get('document_links', ""); docs_attach = message_data['data']['document_data'].get('document_attach_files', "") @@ -88,16 +91,17 @@ class ChatHandler(websocket.WebSocketHandler): order_value = "NULL" if order_id is None or not order_id else order_id insert_sql = "INSERT INTO chat_message (id,text,created, sender_id,recipent_id," \ - " private_type,team_id, order_id,is_delete,is_new) " \ - "VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},{4},{5},{6},{7}) RETURNING id". \ - format(message, sender_id, recipent_id, private_type, team_value, order_value, is_delete, is_new) + " private_type,team_id, order_id,is_delete,is_new,is_system) " \ + "VALUES (DEFAULT,'{0}',NOW(),{1},{2},{3},{4},{5},{6},{7},{8}) RETURNING id". \ + format(message, sender_id, recipent_id, private_type, team_value, order_value, is_delete, is_new, is_system) cursor_list = yield dict(cursor=self.db.execute(insert_sql)) cursor = cursor_list.get('cursor') result = cursor.fetchone() message_id = result[0] + team_ids = [] if team_ids_raw: - team_ids = [t for t in team_ids_raw.rstrip(';').split(';')] + team_ids = [int(t) for t in team_ids_raw.rstrip(';').split(';')] values_str = ''; for t in team_ids: values_str += '(DEFAULT,{0},{1}),'.format(message_id, t) @@ -128,21 +132,31 @@ class ChatHandler(websocket.WebSocketHandler): if docs_links: message += '

    ' + docs_links - if message_type: - waiters = tuple(w for c, w in self.waiters if c == recipent_id) - else: - waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id) - - for waiter in waiters: - waiter.write_message({'msg': message, - 'msg_time': msg_time, - 'order_id': order_id, - 'recipent_id': recipent_id, - 'sender_id': sender_id, - 'sender_name': sender_name, - 'answer_type': answer_type, - 'docs_attach': docs_attach, - }) + # if message_type: + # waiters = tuple(w for c, w in self.waiters if c == recipent_id) + # else: + # waiters = tuple(w for c, w in self.waiters if c == recipent_id or c == sender_id) + + # if answer_type == 'add_message_contact': order_id = recipent_id + # if answer_type == 'add_message_team': order_id = team_id + + for user_id, waiter in self.waiters: + # print(recipent_id, '==', waiter.user_id) + # print(sender_id, '==', waiter.user_id) + # print('types -->', type(recipent_id), type(sender_id), type(user_id)) + if int(recipent_id) == int(user_id) or int(sender_id) == int(user_id) or int(user_id) in team_ids: + # print("waiter.user_id = ", waiter.user_id) + waiter.write_message({'msg': message, + 'msg_time': msg_time, + 'order_id': order_id, + 'team_id': team_id, + 'recipent_id': recipent_id, + 'sender_id': sender_id, + 'sender_name': sender_name, + 'answer_type': answer_type, + 'is_system': is_system, + 'docs_attach': docs_attach, + }) def check_origin(self, origin): return True diff --git a/chat/migrations/0015_message_is_system.py b/chat/migrations/0015_message_is_system.py new file mode 100644 index 0000000..3249a88 --- /dev/null +++ b/chat/migrations/0015_message_is_system.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.7 on 2017-01-31 13:09 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('chat', '0014_newmessage'), + ] + + operations = [ + migrations.AddField( + model_name='message', + name='is_system', + field=models.BooleanField(default=False), + ), + ] diff --git a/chat/models.py b/chat/models.py index bbe164a..47728fa 100644 --- a/chat/models.py +++ b/chat/models.py @@ -10,11 +10,14 @@ class Message(models.Model): created = models.DateTimeField(default=timezone.now) order = models.ForeignKey(Order, related_name='messages', null=True, blank=True) sender = models.ForeignKey(User, related_name='sender_messages') + # TODO: recipent --> recipient recipent = models.ForeignKey(User, related_name='recipent_messages') private_type = models.BooleanField(default=False) team = models.ForeignKey(Team, related_name='messages', null=True, blank=True) is_delete = models.BooleanField(default=False) is_new = models.BooleanField(default=True) + # Системное + is_system = models.BooleanField(default=False) def __str__(self): return self.text diff --git a/chat/serializers.py b/chat/serializers.py index 0ef0750..e74fa59 100644 --- a/chat/serializers.py +++ b/chat/serializers.py @@ -56,6 +56,7 @@ class MessageSerializer(ModelSerializer): 'private_type', 'team', 'documents', + 'is_system' ) def get_text(self, obj): diff --git a/chat/static/sass/chat_add.sass b/chat/static/sass/chat_add.sass new file mode 100644 index 0000000..00ef1d4 --- /dev/null +++ b/chat/static/sass/chat_add.sass @@ -0,0 +1,325 @@ +@import "base/variavles" +@import "modules/mods" +@import "base/colors" + +%icons + margin-left: 0px + display: inline-flex + align-items: center + &:before + content: '' + display: inline-block + width: 20px + height: 20px + background-size: cover + position: relative + left: -5px + +.contractor-notes-block, .team-notes-block, .order-notes-block + text-align: left + padding-left: 45px + font-family: Arial, Verdana, Helvetica, sans-serif + +ol + li + display: list-item + list-style: decimal inside + white-space: nowrap + overflow: hidden + text-overflow: ellipsis + max-width: 180px + +.note-wrapper + position: relative + +.modal-header + text-align: center + +// Системное сообщение +.systemChat + background-color: #ffe9ed + +.review-type + .alignleft + float: left + //width: 33% + text-align: left + + .aligncenter + float: left + //width: 33% + text-align: center + + .alignright + float: right + //width: 33% + text-align: right + +.chat-button + transition: all 0.3s + width: 100% + background-color: #f1f1f1 + text-transform: uppercase + color: #373737 + //display: inline-block + font-family: "pfdintextcomppro-regular", sans-serif + font-size: 18px + letter-spacing: 1px + margin-bottom: 5px + &:visited, &:link + color: #373737 + &:hover + box-shadow: 0 0 15px rgba(0, 0, 0, 0.8) + transform: scale(1.04) + //color: #7e7e7e + padding: 25px 30px + &.icon-hand + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_hands_gray.png") + size: 24px 24px + repeat: no-repeat + &.icon-books + @extend %icons + &:before + width: 30px + height: 25px + background: + image: url("#{$static}/img/icons/icon_books.png") + size: 30px 25px + repeat: no-repeat + &.icon-print + @extend %icons + &:before + width: 30px + height: 25px + background: + image: url("#{$static}/img/icons/icon_print.png") + size: 30px 25px + repeat: no-repeat + &.icon-change + @extend %icons + &:before + width: 20px + height: 24px + background: + image: url("#{$static}/img/icons/icon_edit.png") + size: 20px 24px + repeat: no-repeat + &.icon-credit_card + @extend %icons + &:before + width: 25px + height: 28px + background: + image: url("#{$static}/img/icons/icon_credit_card_gray.png") + size: 25px 28px + repeat: no-repeat + &.icon-arbitration + @extend %icons + &:before + width: 25px + height: 28px + background: + image: url("#{$static}/img/icons/icon_arbitration.png") + size: 25px 28px + repeat: no-repeat + + &.icon-complete_stage + @extend %icons + &:before + width: 25px + height: 28px + background: + image: url("#{$static}/img/icons/icon_complete_stage.png") + size: 25px 28px + repeat: no-repeat + &.icon-check + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_check.png") + size: 25px 25px + repeat: no-repeat + +a.btn.btn-send + transition: all 0.3s + padding: 5px 25px !important + background-color: white + border: 1px solid #BEBEBE + border-radius: 40px + &:hover + transform: scale(1.04) + box-shadow: 0 0 15px rgba(0, 0, 0, 0.2) + &.icon-send + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_arrow_gray.png") + size: 24px 24px + repeat: no-repeat + +.icon-protect + display: inline-block + @extend %icons + &:before + width: 18px + height: 20px + left: 0 + background: + image: url("#{$static}/img/icons/icon_protect.png") + size: 18px 20px + repeat: no-repeat + +.icon-note + display: inline-block + @extend %icons + &:before + width: 30px + height: 20px + left: 0 + background: + image: url("#{$static}/img/icons/icon_pen_black.png") + size: 20px 20px + repeat: no-repeat + +.stage-data + padding-left: 3px + background-color: #f1f1f1 + color: #8c8c8c + font-size: 12px + +.stage-status + font-style: italic + color: #5e5e5e + +.stages-paid + li + padding-left: 25px + margin-top: 15px + .text + padding-left: 10px + .reserved + //display: inline-block + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_coins_green.png") + size: 25px 25px + repeat: no-repeat + + .unreserved + //display: inline-block + color: #FD010E + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_coins_red.png") + size: 25px 25px + repeat: no-repeat + .closed + //display: inline-block + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_coins_gray.png") + size: 25px 25px + repeat: no-repeat + +.border + border-top: 1px solid #CFCFCF + position: relative + height: 20px + margin-top: 10px + .bird + position: absolute + border: 30px solid transparent + border-top: 12px solid #CFCFCF + top: 0 + left: 50% + margin-left: -30px + &:before + content: '' + display: block + position: absolute + border: 30px solid transparent + border-top: 12px solid white + top: -13px + left: 50% + margin-left: -30px + +.select + color: #FD010E + +.note + color: #FD010E + padding-top: 10px + font-size: 12px + +//Team +.team-block + .team-user-list + overflow-y: auto + display: -webkit-box + line-height: 16px + max-height: 64px + hyphens: none + + .max-rows + overflow-y: hidden + display: -webkit-box + line-height: 16px + max-height: 32px + + .icon-hand + @extend %icons + &:before + width: 25px + height: 25px + background: + image: url("#{$static}/img/icons/icon_hands_gray.png") + size: 24px 24px + repeat: no-repeat + + a + cursor: crosshair + &:visited + color: #333333 + &:hover + color: black + +a.docs + &-more, &-less + color: #{map_get($component_colors, select)} + cursor: pointer + &:hover + color: darken(#FD010E, 25%) + box-shadow: none + + &-more:before + content: '...Развернуть' + &-less:before + content: '...Cвернуть' + +.remove-note + position: absolute + width: 11px + height: 11px + background: url('../img/delDoc.png') no-repeat center + background-size: cover + right: -20px !important + top: 2px + cursor: pointer \ No newline at end of file diff --git a/chat/templates/chat_contractor.html b/chat/templates/chat_contractor.html index 85860e3..b12ad3f 100644 --- a/chat/templates/chat_contractor.html +++ b/chat/templates/chat_contractor.html @@ -2,6 +2,11 @@ {% load staticfiles %} {% load thumbnail %} {% load user_tags %} +{% load sass_tags %} +{% block head_css %} + + +{% endblock %} {% block content %} {% include 'partials/header.html' %}
    @@ -27,8 +32,8 @@
  • - Исполнители,Группы{{ teams_ms_count }} + Группы{{ teams_ms_count }}
  • @@ -39,107 +44,116 @@
    -
    -
    -

    Контакты

    - {% for contact in contacts_users %} - {% include 'inc-contact-card.html' %} - {% endfor %} - -
    -
    - -
    -
    -
    - - - - - -
    -
    - -

    Прикрепить файл

    +
    +
    +
    +
    +
    + + Контакты + +
    +
    -
    - отправить -
    - -
    + {% for contact in contacts_users %} + {% include 'inc-contact-card.html' %} + {% endfor %} -
    -
    -

    Прикрепленные документы

    -
      -
    - - Распечатать с помощью ресурса - +
    -
    -
      -
    -
    -

    Для заметок

    - - - - - сохранить +
    +
    + + + + + + +
    + +
    +

    прикрепить файл

    +
    + отправить +
    +
    +
    +
    +
    + {% include 'partials/inc-attach-documents.html' with class='documentSpace' %} + {#

    Прикрепленные документы

    #} + {#
      #} + {#
    #} + {# #} +
    +
    +
      +
      +
      Для заметок
      + + + + + {# сохранить#} + сохранить +
      +
      - - {% include 'contact-info.html' %} - + + {% include 'contact-info.html' %} + +
      -
      -
      -

      Заказы

      - {% for order in orders %} -
      - -

      {{ order }}

      -
      -

      - - Исполнитель: {{ request.user.get_full_name }}

      - - - - Полное описание заказа - - +
      +
      +
      +
      +
      + + Заказы + +
      - {% endfor %} + {% for order in orders %} + {% include 'partials/inc-order-card.html' %} + {% endfor %} - {% if archive_orders %} - - - +
      +
      + +
      + + + + + +
      + +
      +

      прикрепить файл

      +
      + отправить +
      +
      +
      +
      -
      -
      -
      - -
      - - - - - -
      -
      - -

      Прикрепить файл

      +
      +
      +
      +
      + + Порядок работы + +
      +
      +
      + {# 1.Согласование условий #} +
      +

      + 1. Согласование условий

      +

      + Обсуджение задания и условий выполнения работы. Подтверждение заказа исполнителем. +

      +
      +
      -
      +
      + + - -
      -
      -

      Этапы работы

      -
      -

      1 / Согласование условий

      -

      - Обсуждение задания и условий выполнения работы. - Подтверждение заказа исполнителем. -

      -
      -
      - - + -
      -

      3 / Выполнение работы

      -

      - Процесс выполнения задания в заказе до получения - заказчиком итогового результата работы. -

      -
      + + -
      - @@ -263,137 +339,86 @@
      -
      -
      -

      Заказы

      - {% for torder in team_orders %} -
      - -

      - {{ torder }} -

      -
      -

      - - - Исполнитель: {{ torder.team.name }} -

      -
        - {% for tuser in torder.team.users.all %} -
      • {{ tuser }}
      • - {% endfor %} -
      -

      - Чаты: - {% if request.user.pk != torder.team.owner.pk %} - {{ torder.team.owner.username }} - {% endif %} - {% for tuser in torder.team.contractors.all %} - {% if request.user.pk != tuser.pk %} - {{ tuser.username }} - {% endif %} - {% endfor %} -

      - - - Полное описание заказа - +
      +
      +
      +
      +
      + + Группы + +
      - {% endfor %} - - {% for yteam in your_teams %} -
      - -

      - {{ yteam }} -

      -
      -

      - - Владелец группы: {{ yteam.owner }} -

      -
        - {% for tuser in yteam.contractors.all %} -
      • {{ tuser }}
      • - {% endfor %} -
      -

      - Чаты: - {% if request.user.pk != torder.team.owner.pk %} - {{ yteam.owner.username }} - {% endif %} - {% for tuser in yteam.contractors.all %} - {% if request.user.pk != tuser.pk %} - {{ tuser.username }} - {% endif %} - {% endfor %} -

      + {# {% for torder in team_orders %}#} + {# {% include 'partials/inc-order-card.html' with order=torder %}#} + {# {% endfor %}#} -
      -
      + {% for yteam in your_teams %} + {% include 'partials/inc-team-card.html' %} - {% endfor %} + {% endfor %} +
      -
      -
      -
      -
      - - - - - - - - -
      -
      - -

      Прикрепить файл

      -
      -
      -
      +
      +
      + + + + + + + + + +
      + +
      +

      прикрепить файл

      +
      + + отправить +
      +
      - -
      - отправить -
      - -
      -
      - -
      -

      Прикрепленные документы

      -
        - - Распечатать с помощью ресурса - +
        +
        + +
        + {% include 'partials/inc-attach-documents.html' with class='documentTeamSpace' %} + {#

        Прикрепленные документы

        #} + {#
          #} + {# #} +
          -
          -
            -
          -

          Для заметок

          -
          - - - - - - сохранить -
          +
          +
            + +
            +
            Для заметок
            + + + + + + {# сохранить#} + сохранить +
            +
            @@ -402,7 +427,9 @@ {% include 'order_info.html' %}
            - {% include 'partials/footer.html' %} +
            @@ -415,6 +442,7 @@ var port = '{{ request.META.SERVER_PORT }}'; - - + {# #} + {# #} + {% endblock %} diff --git a/chat/templates/chat_customer.html b/chat/templates/chat_customer.html index 0f65f65..ae52c63 100644 --- a/chat/templates/chat_customer.html +++ b/chat/templates/chat_customer.html @@ -1,13 +1,32 @@ {% extends 'partials/base.html' %} -{% load staticfiles %} +{% load static %} {% load thumbnail %} -{% load user_tags %} +{% load sass_tags %} +{% block head_css %} + + +{% endblock %} {% block content %} {% include 'partials/header.html' %} +
            -

            Чат

            +

            Переговорная

            @@ -31,61 +50,88 @@
            -
            -
            -

            Контакты

            - {% for contact in contacts_users %} - {% include 'inc-contact-card.html' %} - {% endfor %} +
            + +
            +
            +
            +
            + + Контакты + +
            +
            -
            -
            -
            -
            -
            - - - - - -
            -
            - -

            Прикрепить файл

            -
            - отправить + {% for contact in contacts_users %} + {% include 'inc-contact-card.html' %} + {% endfor %} +
            +
            + +
            +
            + + + + + - + {#
            #} + {#
            #} + {# #} + {#

            Прикрепить файл

            #} + {#
            #} + {#
            #} + {# отправить#} + {#
            #} + {# EDIT#} +
            + +
            +

            прикрепить файл

            +
            +
            + отправить +
            + + -
            -
            -
            -

            Прикрепленные документы

            -
              -
            - - Распечатать с помощью ресурса -
            + +
            +
            + {% include 'partials/inc-attach-documents.html' with class='documentSpace' %} + {#

            Прикрепленные документы

            #} + {#
              #} + {#
            #} + {# #} + {# Распечатать с помощью ресурса#} + {# #} +
            -
            -

            Заметки

            -
              -
            -
            -

            Для заметок

            - - - - сохранить -
            +
            +
              +
              +
              Для заметок
              + + + + + {# сохранить#} + сохранить +
              +
              - {% include 'contact-info.html' %} @@ -94,61 +140,43 @@
              -
              -
              -

              Заказы

              - {% for order in orders %} -
              - -

              {{ order }}

              -
              -

              - - Исполнитель: - {% if order.order.contractor %} - {{ order.order.contractor.get_full_name }} - {% else %} - {{ order.order.team.name }} - {% endif %} -

              - - - Полное описание заказа - - {# #} - {# Удалить заказ#} - {# #} +
              + +
              +
              +
              +
              + + Заказы + +
              - {% endfor %} + {% for order in orders %} + {% include 'partials/inc-order-card.html' %} + {% endfor %} - {% if archive_projects %} - - - -
              -
              -