diff --git a/docs/source/conf.py b/docs/source/conf.py index 7e99943..d45b1cd 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -132,6 +132,7 @@ extensions = { 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', + 'sphinx.ext.napoleon', 'sphinx_rtd_theme', 'sphinx.ext.graphviz', 'sphinx.ext.inheritance_diagram', @@ -205,3 +206,5 @@ set_type_checking_flag = True typehints_fully_qualified = True always_document_param_types = True typehints_document_rtype = True + +napoleon_attr_annotations = True diff --git a/main/extra_func.py b/main/extra_func.py index 75a9f72..3e54ae4 100644 --- a/main/extra_func.py +++ b/main/extra_func.py @@ -115,7 +115,7 @@ class ZendeskAdmin: user = self.admin.users.search(email).values[0] return user.organization.name if user.organization else None - def create_admin(self) -> Zenpy: + def create_admin(self) -> None: """ Функция создает администратора, проверяя наличие вводимых данных в env. @@ -142,7 +142,7 @@ class ZendeskAdmin: raise ValueError('invalid access_controller`s login data') -def update_role(user_profile: UserProfile, role: int) -> UserProfile: +def update_role(user_profile: UserProfile, role: int) -> None: """ Функция меняет роль пользователя. @@ -158,7 +158,7 @@ def update_role(user_profile: UserProfile, role: int) -> UserProfile: zendesk.admin.users.update(user) -def make_engineer(user_profile: UserProfile, who_changes: User) -> UserProfile: +def make_engineer(user_profile: UserProfile, who_changes: User) -> None: """ Функция устанавливает пользователю роль инженера. @@ -168,7 +168,7 @@ def make_engineer(user_profile: UserProfile, who_changes: User) -> UserProfile: update_role(user_profile, ROLES['engineer']) -def make_light_agent(user_profile: UserProfile, who_changes: User) -> UserProfile: +def make_light_agent(user_profile: UserProfile, who_changes: User) -> None: """ Функция устанавливает пользователю роль легкого агента. diff --git a/main/forms.py b/main/forms.py index 613fc34..81b2e8a 100644 --- a/main/forms.py +++ b/main/forms.py @@ -14,7 +14,7 @@ class CustomRegistrationForm(RegistrationFormUniqueEmail): :type visible_fields.email: :class:`django_registration.forms.RegistrationFormUniqueEmail` """ - def __init__(self, *args, **kwargs) -> RegistrationFormUniqueEmail: + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) for visible in self.visible_fields(): if visible.field.widget.attrs.get('class', False): @@ -96,12 +96,11 @@ class StatisticForm(forms.Form): :type range_end: :class:`django.forms.fields.DateField` """ email = forms.EmailField( - label='Электроная почта', + label='Электронная почта', widget=forms.EmailInput( attrs={ 'placeholder': 'example@ngenix.ru', 'class': 'form-control', - 'style': 'background-color:#f2f2f2;' } ), ) diff --git a/main/templates/base/menu.html b/main/templates/base/menu.html index 93799a5..ef5df18 100644 --- a/main/templates/base/menu.html +++ b/main/templates/base/menu.html @@ -15,21 +15,27 @@ {% else %} class="btn btn-secondary" {% endif %} - href="{% url 'profile' %}">Профиль + href="{% url 'profile' %}">Профиль {% if perms.main.has_control_access %} Управление + href="{% url 'control' %}">Управление + Статистика {% else %} Запрос прав + href="{% url 'work' request.user.id %}">Запрос прав {% endif %} Выйти @@ -40,13 +46,13 @@ {% else %} class="btn btn-secondary" {% endif %} - href="/accounts/login">Войти + href="/accounts/login">Войти Зарегистрироваться + href="/accounts/register">Зарегистрироваться {% endif %} diff --git a/main/templates/pages/adm_ruleset.html b/main/templates/pages/adm_ruleset.html index c0a5ad9..a951f80 100644 --- a/main/templates/pages/adm_ruleset.html +++ b/main/templates/pages/adm_ruleset.html @@ -8,6 +8,7 @@ {% block extra_css %} + {% endblock %} {% block extra_scripts %} @@ -21,7 +22,7 @@
-

Свободных Мест: {{ licences_remaining }}

+

Свободных Мест:

{% block form %} @@ -37,10 +38,16 @@ + - diff --git a/main/templates/pages/statistic.html b/main/templates/pages/statistic.html index 9a9219b..b467250 100644 --- a/main/templates/pages/statistic.html +++ b/main/templates/pages/statistic.html @@ -26,7 +26,7 @@
{% for radio in form.interval%} {{ radio.tag }} -
+ + Name Email RoleChecked
- + {% for date in log_stats.keys %} - + {% endfor %} @@ -96,7 +96,7 @@ {% for time in log_stats.values %} - + {% endfor %} diff --git a/main/views.py b/main/views.py index 0129b3a..f352147 100644 --- a/main/views.py +++ b/main/views.py @@ -30,13 +30,17 @@ from .models import UserProfile def setup_context(profile_lit: bool = False, control_lit: bool = False, work_lit: bool = False, - registration_lit: bool = False, login_lit: bool = False): + registration_lit: bool = False, login_lit: bool = False, stats_lit: bool = False): + + print(profile_lit, control_lit, work_lit, registration_lit, login_lit) + context = { 'profile_lit': profile_lit, 'control_lit': control_lit, 'work_lit': work_lit, 'registration_lit': registration_lit, 'login_lit': login_lit, + 'stats_lit': stats_lit, } return context @@ -300,30 +304,6 @@ class AdminPageView(LoginRequiredMixin, PermissionRequiredMixin, SuccessMessageM make_light_agent(user, self.request.user) log(user, self.request.user.userprofile) - def get_context_data(self, **kwargs) -> dict: - """ - Функция формирования контента страницы администратора (с проверкой прав доступа) - """ - - # context = super().get_context_data(**kwargs) - - # context['licences_remaining'] = max(0, ZENDESK_MAX_AGENTS - context['engineers']) - # return context - - context = setup_context(control_lit=True) - context.update(super().get_context_data(**kwargs)) - users = get_list_or_404( - UserProfile, role='agent') - context['engineers'], context['light_agents'] = count_users(get_users_list()) - context.update({ - 'users': users, - 'ZENDESK_ROLES': ZENDESK_ROLES, - 'engineers': context['engineers'], - 'light_agents': context['light_agents'], - 'licences_remaining': max(0, ZENDESK_MAX_AGENTS - context['engineers']), - }) - return context # TODO: need to get profile page url - class CustomLoginView(LoginView): """ @@ -349,7 +329,8 @@ class UsersViewSet(viewsets.ReadOnlyModelViewSet): 'users': serializer.data, 'engineers': count[0], 'light_agents': count[1], - "zendesk_users": self.get_zendesk_users(self.choose_users(users.values, profiles)) + 'zendesk_users': self.get_zendesk_users(self.choose_users(users.values, profiles)), + 'max_agents': ZENDESK_MAX_AGENTS } return Response(res) @@ -386,7 +367,7 @@ def statistic_page(request: WSGIRequest) -> HttpResponse: if not request.user.is_superuser: return redirect('index') - context = setup_context() + context = setup_context(stats_lit=True) context.update({ 'pagename': 'страница статистики', 'errors': list(), diff --git a/static/main/js/control.js b/static/main/js/control.js index 82f9f27..0215b05 100644 --- a/static/main/js/control.js +++ b/static/main/js/control.js @@ -1,15 +1,18 @@ "use strict"; +function head_checkbox() { + let head_checkbox = document.getElementById("head-checkbox"); + head_checkbox.addEventListener("click", () => { + let checkboxes = document.getElementsByName("users"); + for (let checkbox of checkboxes) checkbox.click(); + }); +} + // React class ModelUserTableRow extends React.Component { render() { return ( - - - + + + ); } @@ -38,12 +46,12 @@ class ZendeskUserTableRow extends React.Component { render() { return ( + - ); } @@ -68,9 +76,22 @@ class TableBody extends React.Component { engineers: 0, light_agents: 0, zendesk_users: [], + max_agents: 3, }; } + change_elemnts_html() { + let elements = document.querySelectorAll(".info-quantity-value"); + let licences = document.getElementById("licences_remaining"); + elements[0].innerHTML = this.state.engineers; + elements[1].innerHTML = this.state.light_agents; + let max_licences = Math.max( + this.state.max_agents - this.state.engineers, + 0 + ); + licences.innerHTML = "Свободных мест: " + max_licences; + } + async get_users() { await axios.get("/api/users").then((response) => { this.setState({ @@ -78,11 +99,10 @@ class TableBody extends React.Component { engineers: response.data.engineers, light_agents: response.data.light_agents, zendesk_users: response.data.zendesk_users, + max_agents: response.data.max_agents, }); - let elements = document.querySelectorAll(".info-quantity-value"); - elements[0].innerHTML = this.state.engineers; - elements[1].innerHTML = this.state.light_agents; }); + this.change_elemnts_html(); } delete_pretext() { @@ -111,3 +131,4 @@ class TableBody extends React.Component { } ReactDOM.render(, document.getElementById("tbody")); +head_checkbox();
Пользователи/Даты {{date}}{{ date | date:'d.m' }}
{{ form.email.value }}{{time}}{{ time | floatformat:2 }}
- {this.props.user.name} - {this.props.user.user.email}{this.props.user.zendesk_role} + {this.props.user.name} + {this.props.user.user.email}{this.props.user.zendesk_role}
{this.props.user.name} {this.props.user.email} {this.props.user.zendesk_role}