#ARC-4 Section 7

remotes/origin/PR-39
ArturBaybulatov 9 years ago
parent 0e43a71f2b
commit a8f2cc350c
  1. 37
      assets/index.js
  2. 2
      assets/js/chat.js
  3. 19
      common/migrations/0014_auto_20160906_1713.py
  4. 2
      common/views.py
  5. 2
      templates/partials/base.html
  6. 10
      templates/test.html
  7. 23
      users/filters.py
  8. 3
      users/models.py
  9. 3
      users/serializers.py
  10. 32
      users/templates/contractor_office.html
  11. 32
      users/templates/contractor_profile.html
  12. 19
      users/templates/partials/modals/add_team_member.html
  13. 5
      users/urls.py
  14. 12
      users/views.py

@ -196,6 +196,43 @@ function initSimpleSpecSelect2($select, specId) {
// Team invitation contractor select -------------------------------
var contractorSelectOptions = {
language: 'ru',
placeholder: 'Выберите пользователя', // Required by `allowClear`
allowClear: true,
}
function initContractorSelect($select) {
return $.ajax({url: '/api/users/?is_contractor=true', method: 'GET', dataType: 'json'})
.then(function(res) {
var contractors = res.results
$select.select2(_.merge(contractorSelectOptions, {
data: _.map(function(contractor) {
return {
id: contractor.id,
text: contractor.username,
origItem: contractor,
}
}, contractors),
}))
})
}
// Location select ---------------------------------------------- // Location select ----------------------------------------------

@ -1,6 +1,6 @@
var SocketHandler = function () { var SocketHandler = function () {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + '/chat/' + userId + '/'; var url = 'ws://' + domain + ':8888/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-09-06 14:13
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('common', '0013_liveimageupload'),
]
operations = [
migrations.AlterModelOptions(
name='liveimageupload',
options={'verbose_name': 'Живая загрузка изображений', 'verbose_name_plural': 'Живая загрузка изображений'},
),
]

@ -111,7 +111,7 @@ class LiveImageUploadDeleteView(NoCsrfMixin, LoginRequiredMixin, View):
live_img.delete() live_img.delete()
return JsonResponse({'status': 'success'}) return JsonResponse({'status': 'success'})
else: else:
return JsonResponse({'status': 'failure'}) return JsonResponse({'status': 'error'})
class CustomRegistrationView(RegistrationView): class CustomRegistrationView(RegistrationView):

@ -87,7 +87,7 @@
if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/510/work-projects') != 0)) { if ((queryString.indexOf('/chat') != 0) && (queryString.indexOf('/users/contractor-office/510/work-projects') != 0)) {
domain = domain.replace(':' + port, ''); domain = domain.replace(':' + port, '');
var url = 'ws://' + domain + '/chat/' + userId + '/'; var url = 'ws://' + domain + ':8888/chat/' + userId + '/';
var sock = new WebSocket(url); var sock = new WebSocket(url);
var intervalId; var intervalId;
sock.onopen = function () { sock.onopen = function () {

@ -15,7 +15,7 @@
<div class='container-fluid'> <div class='container-fluid'>
<div class='row'> <div class='row'>
<div class='col-xs-12' style='margin-top: 15px'> <div class='col-xs-12' style='margin-top: 15px'>
<span data-tooltip data-placement="bottom" title="{% tooltip name='Test' %}">Hello there</span> {{ request.get_host }}{{ request.get_full_path }}
</div> </div>
</div> </div>
</div> </div>
@ -26,13 +26,5 @@
<script src='{% static "js/bootstrap.min.js" %}'></script> <script src='{% static "js/bootstrap.min.js" %}'></script>
<script src='{% static "my-libs.js" %}'></script> <script src='{% static "my-libs.js" %}'></script>
<script>
$('[data-tooltip]').tooltip({
html: true,
container: 'body', // Remove unwanted side-effects
trigger : 'hover', // Disable tooltip remaining visible after a click
})
</script>
</body> </body>
</html> </html>

@ -1,23 +1,41 @@
from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter from rest_framework_filters import FilterSet, RelatedFilter, AllLookupsFilter, MethodFilter
import pydash as _; _.map = _.map_; _.filter = _.filter_
from .models import User, Team, ContractorResumeFiles, ContractorResume from .models import User, Team, ContractorResumeFiles, ContractorResume
class UserFilterSet(FilterSet): class UserFilterSet(FilterSet):
id = AllLookupsFilter()
email = AllLookupsFilter() email = AllLookupsFilter()
first_name = AllLookupsFilter() first_name = AllLookupsFilter()
id = AllLookupsFilter()
is_active = AllLookupsFilter() is_active = AllLookupsFilter()
is_admin = AllLookupsFilter() is_admin = AllLookupsFilter()
is_contractor = MethodFilter()
is_customer = MethodFilter()
last_name = AllLookupsFilter() last_name = AllLookupsFilter()
projects = RelatedFilter('projects.filters.ProjectFilterSet') projects = RelatedFilter('projects.filters.ProjectFilterSet')
class Meta: class Meta:
model = User model = User
def filter_is_contractor(self, name, qs, value):
if value == 'true':
return _.filter(qs, lambda user: user.is_contractor())
return qs
def filter_is_customer(self, name, qs, value):
if value == 'true':
return _.filter(qs, lambda user: user.is_customer())
return qs
class TeamFilterSet(FilterSet): class TeamFilterSet(FilterSet):
id = AllLookupsFilter() id = AllLookupsFilter()
name = AllLookupsFilter() name = AllLookupsFilter()
owner = RelatedFilter('users.filters.UserFilterSet') owner = RelatedFilter('users.filters.UserFilterSet')
class Meta: class Meta:
@ -37,6 +55,7 @@ class ContractorResumeFilesFilterSet(FilterSet):
id = AllLookupsFilter() id = AllLookupsFilter()
title = AllLookupsFilter() title = AllLookupsFilter()
img = AllLookupsFilter() img = AllLookupsFilter()
resume = RelatedFilter('users.filters.ContractorResumeFilterSet') resume = RelatedFilter('users.filters.ContractorResumeFilterSet')
class Meta: class Meta:

@ -212,6 +212,9 @@ class User(AbstractBaseUser, PermissionsMixin):
def is_customer(self): def is_customer(self):
return self.groups.filter(name='Заказчики').exists() return self.groups.filter(name='Заказчики').exists()
def has_team(self):
return self.is_contractor() and bool(util.get_related_or_none(self, 'team'))
def is_owner_profile(self, user_id): def is_owner_profile(self, user_id):
pass pass

@ -51,8 +51,11 @@ class UserSerializer(ModelSerializer):
'financial_info', 'financial_info',
'first_name', 'first_name',
'gender', 'gender',
'has_team',
'id', 'id',
'is_active', 'is_active',
'is_contractor',
'is_customer',
'last_name', 'last_name',
'last_time_visit', 'last_time_visit',
'location', 'location',

@ -5,6 +5,7 @@
{% block content %} {% block content %}
{% include 'partials/modals/add_team_member.html' %}
{% include 'partials/header.html' %} {% include 'partials/header.html' %}
<div class="container mainScore"> <div class="container mainScore">
@ -75,7 +76,7 @@
</div> </div>
<div class="menuUser disTab"> <div class="menuUser disTab">
<a href="{% url 'users:contractor-filter' %}" class="add-man"> <a href="#" onclick="return false" data-toggle="modal" data-target="#addTeamMemberModal" class="add-man -add-team-member">
добавить участника добавить участника
</a> </a>
@ -326,6 +327,35 @@
window.loadMorePortfolios = loadMorePortfolios window.loadMorePortfolios = loadMorePortfolios
window.loadMoreWorkSells = loadMoreWorkSells window.loadMoreWorkSells = loadMoreWorkSells
// Add new team member --------------------------------------------
{% if request.user.has_team %}
var $contractorSelect = window.$contractorSelect = $('.-contractor-select').first()
var $addTeamMemberModal = $('#addTeamMemberModal')
{# var addTeamMemberUrl = '/users/add-team-member/%id%/'#}
initContractorSelect($contractorSelect)
$addTeamMemberModal.find('.-action-button').first().on('click', function($evt) {
$addTeamMemberModal.modal('hide')
socketMain.add_message({
format_type: 'add_message_contact',
data: {
sender_id: {{ request.user.pk }},
recipent_id: $contractorSelect.select2('val'),
chat_message: 'Приглашаю в группу http://{{ request.get_host }}{% url 'users:team-profile' pk=request.user.team.pk %}',
},
})
$.jGrowl('Приглашение успешно отправлено')
})
{% endif %}
}()) }())
</script> </script>
{% endblock %} {% endblock %}

@ -32,9 +32,9 @@
</li> </li>
{% endif %} {% endif %}
{% if contractor.pk != request.user.pk and request.user.is_contractor %} {% if contractor.pk != request.user.pk and request.user.is_contractor and request.user.has_team %}
<li class="icon_um2"> <li class="icon_um2">
<a href="javascript:void(0)"> <a href="#" onclick="return false" class='-team-invitation'>
пригласить в группу пригласить в группу
</a> </a>
<span></span> <span></span>
@ -776,20 +776,22 @@
// Team invitation ----------------------------------------------- // Team invitation -----------------------------------------------
function inviteToTeam(msg) { {% if contractor.pk != request.user.pk and request.user.is_contractor and request.user.has_team %}
socketMain.add_message({ $('.-team-invitation').first().on('click', function($evt) {
format_type: 'add_message_contact', socketMain.add_message({
format_type: 'add_message_contact',
data: {
sender_id: {{ request.user.pk }}, data: {
recipent_id: {{ contractor.pk }}, sender_id: {{ request.user.pk }},
chat_message: msg, recipent_id: {{ contractor.pk }},
}, chat_message: 'Приглашаю в группу http://{{ request.get_host }}{% url 'users:team-profile' pk=request.user.team.pk %}',
},
})
$.jGrowl('Приглашение успешно отправлено')
$(this).fadeOut()
}) })
} {% endif %}
window.inviteToTeam = inviteToTeam
//----------------------------------------------------------------- //-----------------------------------------------------------------

@ -0,0 +1,19 @@
<div class="modal fade" id="addTeamMemberModal" tabindex="-1">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span>&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<input type="hidden" class="-contractor-select" style="width: 100%">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Отмена</button>
<button type="button" class="btn btn-primary -action-button">Пригласить</button>
</div>
</div>
</div>
</div>

@ -3,7 +3,9 @@ from django.conf.urls import include
from django.contrib.auth.views import login, logout from django.contrib.auth.views import login, logout
from .views import ( from .views import (
AddTeamMember,
contractor_resumefile_create, contractor_resumefile_create,
ContractorChatProjectsView,
ContractorFilterView, ContractorFilterView,
ContractorOfficeProjectsView, ContractorOfficeProjectsView,
ContractorOfficeView, ContractorOfficeView,
@ -17,7 +19,6 @@ from .views import (
TeamProfileView, TeamProfileView,
UserFinancialInfoEditView, UserFinancialInfoEditView,
UserProfileEditView, UserProfileEditView,
ContractorChatProjectsView,
) )
@ -42,4 +43,6 @@ urlpatterns = [
urls.url(r'^teams/(?P<pk>\d+)/$', TeamProfileView.as_view(), name='team-profile'), urls.url(r'^teams/(?P<pk>\d+)/$', TeamProfileView.as_view(), name='team-profile'),
urls.url(r'^contractor-office/(?P<pk>\d+)/work-projects/$', ContractorChatProjectsView.as_view(), name='contractor-office-chat-projects'), urls.url(r'^contractor-office/(?P<pk>\d+)/work-projects/$', ContractorChatProjectsView.as_view(), name='contractor-office-chat-projects'),
urls.url(r'^add-team-member/(?P<pk>\d+)/$', AddTeamMember.as_view(), name='add-team-member'),
] ]

@ -1,5 +1,7 @@
from common.mixins import NoCsrfMixin
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.mail import send_mail from django.core.mail import send_mail
@ -722,5 +724,15 @@ class CustomerProfileReviewsView(BaseMixin, View):
return render(request, self.template_name, context) return render(request, self.template_name, context)
class AddTeamMember(NoCsrfMixin, LoginRequiredMixin, View):
def post(self, request, *args, **kwargs):
# import code; code.interact(local=dict(globals(), **locals()))
# if request.user.is_contractor()...
# kwargs.get('pk')
#
return JsonResponse({'status': 'success'})
# import code; code.interact(local=dict(globals(), **locals())) # import code; code.interact(local=dict(globals(), **locals()))

Loading…
Cancel
Save