Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
{% block _config_userconfig_widget %}
{% set fields = form.children %}
{% set fieldKeys = fields|keys %}
{% if fieldKeys|filter(v => v in ['saml_idp_metadata', 'saml_idp_own_certificate', 'saml_idp_own_private_key', 'saml_idp_own_password'])|length > 0 %}
<h4 class="fw-sb mt-48 mb-xs">{{ 'mautic.user.config.header.saml'|trans }}</h4>
<div class="text-muted small pb-md">{{ 'mautic.core.config.header.saml.description'|trans }}</div>
<div class="row">
<div class="panel panel-default mb-md">
<div class="panel-body">
<div class="row">
{% if fields.saml_idp_entity_id is defined %}
<div class="col-xs-12">
{{ form_row(fields.saml_idp_entity_id) }}
</div>
{% endif %}
<div class="col-xs-12">
{{ form_row(fields.saml_idp_metadata, {'fieldValue': formConfig.parameters.saml_idp_metadata}) }}
</div>
<div class="col-xs-12">
{{ form_row(fields.saml_idp_default_role) }}
</div>
</div>
<hr />
<div class="alert alert-info">{{ 'mautic.user.config.form.saml.idp_attributes'|trans }}</div>
<div class="row">
<div class="col-xs-12">
{{ form_row(fields.saml_idp_email_attribute) }}
</div>
<div class="col-xs-12">
{{ form_row(fields.saml_idp_username_attribute) }}
</div>
</div>
<div class="row">
<div class="col-xs-12">
{{ form_row(fields.saml_idp_firstname_attribute) }}
</div>
<div class="col-xs-12">
{{ form_row(fields.saml_idp_lastname_attribute) }}
</div>
</div>
<hr />
<div class="alert alert-info">{{ 'mautic.user.config.form.saml.idp.own_certificate.description'|trans }}</div>
<div class="row">
<div class="col-xs-12">
{{ form_row(fields.saml_idp_own_certificate, {'fieldValue': formConfig.parameters.saml_idp_own_certificate}) }}
</div>
<div class="col-xs-12">
{{ form_row(fields.saml_idp_own_private_key, {'fieldValue': formConfig.parameters.saml_idp_own_private_key}) }}
</div>
</div>
<div class="row">
<div class="col-xs-12">
{{ form_row(fields.saml_idp_own_password) }}
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,20 @@
{% for theme in themes %}
<div class="radio-option col-xs-12 col-md-4 mb-lg">
<label class="d-flex fd-column" for="theme-{{ theme.id }}">
{% if theme.preview ends with '.twig' %}
{{ include(theme.preview) }}
{% else %}
<img src="{{ asset(theme.preview) }}" alt="{{ theme.name|trans }} preview" aria-hidden="true" class="mb-sm">
{% endif %}
<div class="d-flex fd-row gap-3">
<input type="radio" id="theme-{{ theme.id }}" name="theme" value="{{ theme.id }}"
data-attribute-toggle="theme" data-attribute-value="{{ theme.id }}"
{% if theme.checked|default(false) %}checked{% endif %}>
<div class="text-content">
<strong>{{ theme.name|trans }}</strong>
<div class="text-help">{{ theme.description|trans }}</div>
</div>
</div>
</label>
</div>
{% endfor %}

View File

@@ -0,0 +1,29 @@
<svg class="mb-sm" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_795_75)">
<path d="M0 0H228V120H0V0Z" fill="#161616"/>
<path d="M75 39H47C45.8954 39 45 39.8954 45 41V73C45 74.1046 45.8954 75 47 75H75C76.1046 75 77 74.1046 77 73V41C77 39.8954 76.1046 39 75 39Z" fill="#262626"/>
<path d="M0 0H40V120H0V0Z" fill="#262626"/>
<path d="M90 20H48C46.3431 20 45 21.3431 45 23C45 24.6569 46.3431 26 48 26H90C91.6569 26 93 24.6569 93 23C93 21.3431 91.6569 20 90 20Z" fill="#393939"/>
<path d="M214.153 39H84.8472C83.827 39 83 40.132 83 41.5283V103.472C83 104.868 83.827 106 84.8472 106H214.153C215.173 106 216 104.868 216 103.472V41.5283C216 40.132 215.173 39 214.153 39Z" fill="#262626"/>
<path opacity="0.3" d="M216 44H83V56H216V44Z" fill="var(--primary-60)"/>
<path d="M143.958 47H90.389C88.8587 47 87.6182 48.3431 87.6182 50C87.6182 51.6569 88.8587 53 90.389 53H143.958C145.489 53 146.729 51.6569 146.729 50C146.729 48.3431 145.489 47 143.958 47Z" fill="var(--primary-60)"/>
<g clip-path="url(#clip1_795_75)">
<path d="M213 20H209C208.448 20 208 20.4477 208 21V25C208 25.5523 208.448 26 209 26H213C213.552 26 214 25.5523 214 25V21C214 20.4477 213.552 20 213 20Z" fill="white"/>
</g>
<g clip-path="url(#clip2_795_75)">
<path d="M205 20H201C200.448 20 200 20.4477 200 21V25C200 25.5523 200.448 26 201 26H205C205.552 26 206 25.5523 206 25V21C206 20.4477 205.552 20 205 20Z" fill="var(--primary-60)"/>
</g>
<path d="M213 9H187C185.343 9 184 10.3431 184 12C184 13.6569 185.343 15 187 15H213C214.657 15 216 13.6569 216 12C216 10.3431 214.657 9 213 9Z" fill="#393939"/>
</g>
<defs>
<clipPath id="clip0_795_75">
<rect width="228" height="120" fill="white"/>
</clipPath>
<clipPath id="clip1_795_75">
<rect x="208" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
<clipPath id="clip2_795_75">
<rect x="200" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,29 @@
<svg width="228" height="120" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_795_117)">
<path d="M0 0H228V120H0V0Z" fill="#1C1C2E"/>
<path d="M75 39H47C45.8954 39 45 39.8954 45 41V73C45 74.1046 45.8954 75 47 75H75C76.1046 75 77 74.1046 77 73V41C77 39.8954 76.1046 39 75 39Z" fill="#232336"/>
<path d="M0 0H40V120H0V0Z" fill="#232336"/>
<path d="M90 20H48C46.3431 20 45 21.3431 45 23C45 24.6569 46.3431 26 48 26H90C91.6569 26 93 24.6569 93 23C93 21.3431 91.6569 20 90 20Z" fill="#323248"/>
<path d="M214.153 39H84.8472C83.827 39 83 40.132 83 41.5283V103.472C83 104.868 83.827 106 84.8472 106H214.153C215.173 106 216 104.868 216 103.472V41.5283C216 40.132 215.173 39 214.153 39Z" fill="#232336"/>
<path opacity="0.3" d="M216 44H83V56H216V44Z" fill="#F7B84B"/>
<path d="M143.958 47H90.389C88.8587 47 87.6182 48.3431 87.6182 50C87.6182 51.6569 88.8587 53 90.389 53H143.958C145.489 53 146.729 51.6569 146.729 50C146.729 48.3431 145.489 47 143.958 47Z" fill="#F7B84B"/>
<g clip-path="url(#clip1_795_117)">
<path d="M213 20H209C208.448 20 208 20.4477 208 21V25C208 25.5523 208.448 26 209 26H213C213.552 26 214 25.5523 214 25V21C214 20.4477 213.552 20 213 20Z" fill="#8C98C6"/>
</g>
<g clip-path="url(#clip2_795_117)">
<path d="M205 20H201C200.448 20 200 20.4477 200 21V25C200 25.5523 200.448 26 201 26H205C205.552 26 206 25.5523 206 25V21C206 20.4477 205.552 20 205 20Z" fill="#F7B84B"/>
</g>
<path d="M213 9H187C185.343 9 184 10.3431 184 12C184 13.6569 185.343 15 187 15H213C214.657 15 216 13.6569 216 12C216 10.3431 214.657 9 213 9Z" fill="#323248"/>
</g>
<defs>
<clipPath id="clip0_795_117">
<rect width="228" height="120" fill="white"/>
</clipPath>
<clipPath id="clip1_795_117">
<rect x="208" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
<clipPath id="clip2_795_117">
<rect x="200" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,29 @@
<svg class="mb-sm" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_794_43)">
<path d="M0 0H228V120H0V0Z" fill="white"/>
<path d="M75 39H47C45.8954 39 45 39.8954 45 41V73C45 74.1046 45.8954 75 47 75H75C76.1046 75 77 74.1046 77 73V41C77 39.8954 76.1046 39 75 39Z" fill="#F4F4F4"/>
<path d="M0 0H40V120H0V0Z" fill="#F4F4F4"/>
<path d="M90 20H48C46.3431 20 45 21.3431 45 23C45 24.6569 46.3431 26 48 26H90C91.6569 26 93 24.6569 93 23C93 21.3431 91.6569 20 90 20Z" fill="#DADADA"/>
<path d="M214.153 39H84.8472C83.827 39 83 40.132 83 41.5283V103.472C83 104.868 83.827 106 84.8472 106H214.153C215.173 106 216 104.868 216 103.472V41.5283C216 40.132 215.173 39 214.153 39Z" fill="#F4F4F4"/>
<path opacity="0.3" d="M216 44H83V56H216V44Z" fill="var(--primary-60)"/>
<path d="M143.958 47H90.389C88.8587 47 87.6182 48.3431 87.6182 50C87.6182 51.6569 88.8587 53 90.389 53H143.958C145.489 53 146.729 51.6569 146.729 50C146.729 48.3431 145.489 47 143.958 47Z" fill="var(--primary-60)"/>
<g clip-path="url(#clip1_794_43)">
<path d="M213 20H209C208.448 20 208 20.4477 208 21V25C208 25.5523 208.448 26 209 26H213C213.552 26 214 25.5523 214 25V21C214 20.4477 213.552 20 213 20Z" fill="#161616"/>
</g>
<g clip-path="url(#clip2_794_43)">
<path d="M205 20H201C200.448 20 200 20.4477 200 21V25C200 25.5523 200.448 26 201 26H205C205.552 26 206 25.5523 206 25V21C206 20.4477 205.552 20 205 20Z" fill="var(--primary-60)"/>
</g>
<path d="M213 9H187C185.343 9 184 10.3431 184 12C184 13.6569 185.343 15 187 15H213C214.657 15 216 13.6569 216 12C216 10.3431 214.657 9 213 9Z" fill="#DADADA"/>
</g>
<defs>
<clipPath id="clip0_794_43">
<rect width="228" height="120" fill="white"/>
</clipPath>
<clipPath id="clip1_794_43">
<rect x="208" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
<clipPath id="clip2_794_43">
<rect x="200" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,29 @@
<svg width="228" height="120" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_795_103)">
<path d="M0 0H228V120H0V0Z" fill="#002B36"/>
<path d="M75 39H47C45.8954 39 45 39.8954 45 41V73C45 74.1046 45.8954 75 47 75H75C76.1046 75 77 74.1046 77 73V41C77 39.8954 76.1046 39 75 39Z" fill="#073642"/>
<path d="M0 0H40V120H0V0Z" fill="#073642"/>
<path d="M90 20H48C46.3431 20 45 21.3431 45 23C45 24.6569 46.3431 26 48 26H90C91.6569 26 93 24.6569 93 23C93 21.3431 91.6569 20 90 20Z" fill="#586E75"/>
<path d="M214.153 39H84.8472C83.827 39 83 40.132 83 41.5283V103.472C83 104.868 83.827 106 84.8472 106H214.153C215.173 106 216 104.868 216 103.472V41.5283C216 40.132 215.173 39 214.153 39Z" fill="#073642"/>
<path opacity="0.3" d="M216 44H83V56H216V44Z" fill="#268BD2"/>
<path d="M143.958 47H90.389C88.8587 47 87.6182 48.3431 87.6182 50C87.6182 51.6569 88.8587 53 90.389 53H143.958C145.489 53 146.729 51.6569 146.729 50C146.729 48.3431 145.489 47 143.958 47Z" fill="#268BD2"/>
<g clip-path="url(#clip1_795_103)">
<path d="M213 20H209C208.448 20 208 20.4477 208 21V25C208 25.5523 208.448 26 209 26H213C213.552 26 214 25.5523 214 25V21C214 20.4477 213.552 20 213 20Z" fill="#839496"/>
</g>
<g clip-path="url(#clip2_795_103)">
<path d="M205 20H201C200.448 20 200 20.4477 200 21V25C200 25.5523 200.448 26 201 26H205C205.552 26 206 25.5523 206 25V21C206 20.4477 205.552 20 205 20Z" fill="#268BD2"/>
</g>
<path d="M213 9H187C185.343 9 184 10.3431 184 12C184 13.6569 185.343 15 187 15H213C214.657 15 216 13.6569 216 12C216 10.3431 214.657 9 213 9Z" fill="#586E75"/>
</g>
<defs>
<clipPath id="clip0_795_103">
<rect width="228" height="120" fill="white"/>
</clipPath>
<clipPath id="clip1_795_103">
<rect x="208" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
<clipPath id="clip2_795_103">
<rect x="200" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,29 @@
<svg width="228" height="120" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_795_89)">
<path d="M0 0H228V120H0V0Z" fill="#FDF6E3"/>
<path d="M75 39H47C45.8954 39 45 39.8954 45 41V73C45 74.1046 45.8954 75 47 75H75C76.1046 75 77 74.1046 77 73V41C77 39.8954 76.1046 39 75 39Z" fill="#EEE8D5"/>
<path d="M0 0H40V120H0V0Z" fill="#EEE8D5"/>
<path d="M90 20H48C46.3431 20 45 21.3431 45 23C45 24.6569 46.3431 26 48 26H90C91.6569 26 93 24.6569 93 23C93 21.3431 91.6569 20 90 20Z" fill="#DCD4C0"/>
<path d="M214.153 39H84.8472C83.827 39 83 40.132 83 41.5283V103.472C83 104.868 83.827 106 84.8472 106H214.153C215.173 106 216 104.868 216 103.472V41.5283C216 40.132 215.173 39 214.153 39Z" fill="#EEE8D5"/>
<path opacity="0.3" d="M216 44H83V56H216V44Z" fill="#268BD2"/>
<path d="M143.958 47H90.389C88.8587 47 87.6182 48.3431 87.6182 50C87.6182 51.6569 88.8587 53 90.389 53H143.958C145.489 53 146.729 51.6569 146.729 50C146.729 48.3431 145.489 47 143.958 47Z" fill="#268BD2"/>
<g clip-path="url(#clip1_795_89)">
<path d="M213 20H209C208.448 20 208 20.4477 208 21V25C208 25.5523 208.448 26 209 26H213C213.552 26 214 25.5523 214 25V21C214 20.4477 213.552 20 213 20Z" fill="#586E75"/>
</g>
<g clip-path="url(#clip2_795_89)">
<path d="M205 20H201C200.448 20 200 20.4477 200 21V25C200 25.5523 200.448 26 201 26H205C205.552 26 206 25.5523 206 25V21C206 20.4477 205.552 20 205 20Z" fill="#268BD2"/>
</g>
<path d="M213 9H187C185.343 9 184 10.3431 184 12C184 13.6569 185.343 15 187 15H213C214.657 15 216 13.6569 216 12C216 10.3431 214.657 9 213 9Z" fill="#DCD4C0"/>
</g>
<defs>
<clipPath id="clip0_795_89">
<rect width="228" height="120" fill="white"/>
</clipPath>
<clipPath id="clip1_795_89">
<rect x="208" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
<clipPath id="clip2_795_89">
<rect x="200" y="20" width="6" height="6" rx="3" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,285 @@
{% extends '@MauticCore/Default/content.html.twig' %}
{% block headerTitle %}{{ 'mautic.user.account.settings'|trans }}{% endblock %}
{% block mauticContent %}user{% endblock %}
{% block content %}
<!-- start: box layout -->
<div class="container">
<!-- step container -->
<div class="row">
<div class="col-md-3 height-auto">
{% if me.getId() %}
<div class="media">
<div class="pull-left">
<img class="img-circle mt-md mb-xs img-bordered media-object" src="{{ gravatarGetImage(me.getEmail()) }}"
alt="" width="65px">
</div>
<div class="media-body">
<h3 class="fw-sb">{{ me.getName() }}</h3>
<span class="text-secondary">{{ me.getPosition() }}</span>
</div>
</div>
<hr />
{% endif %}
<ul class="list-group list-group-tabs">
<li class="list-group-item active">
<a href="#profile" class="list-group-item-heading steps" data-toggle="tab">
{{ 'mautic.user.account.header.details'|trans }}
</a>
</li>
{% if permissions['apiAccess'] %}
<li class="list-group-item">
<a href="#clients" class="list-group-item-heading steps" data-toggle="tab">
{{ 'mautic.user.account.header.authorizedclients'|trans }}
</a>
</li>
{% endif %}
<li class="list-group-item">
<a href="#appearance" class="list-group-item-heading steps" data-toggle="tab">{{
'mautic.user.account.appearance'|trans }}</a>
</li>
<li class="list-group-item">
<a href="#accessibility" class="list-group-item-heading steps" data-toggle="tab">{{
'mautic.user.account.accessibility'|trans }}</a>
</li>
</ul>
</div>
<!--/ step container -->
<!-- container -->
<div class="col-md-9 height-auto">
<div class="tab-content">
<div class="tab-pane fade in active bdr-rds-0 bdr-w-0" id="profile">
{{ form_start(userForm) }}
<div class="row pa-md bdr-b">
<h4 class="fw-sb">{{ 'mautic.user.account.header.details'|trans }}</h4>
</div>
<div class="row">
<div class="col-md-6">
<h3 id="personal-info" class="pt-20 mb-xs">{{ 'mautic.user.config.title.get_to_know_you'|trans }}</h3>
<div class="text-secondary small pb-20">{{ 'mautic.user.config.personalize.interface.helper'|trans }}</div>
{{ permissions.editName ? form_row(userForm.firstName) : form_row(userForm.firstName_unbound) }}
{{ permissions.editName ? form_row(userForm.lastName) : form_row(userForm.lastName_unbound) }}
{{ permissions.editPosition ? form_row(userForm.position) : form_row(userForm.position_unbound) }}
{{ form_row(userForm.signature) }}
<h3 id="locale" class="pt-20 mb-xs">{{ 'mautic.user.config.title.locale'|trans }}</h3>
<div class="text-secondary small pb-20">{{ 'mautic.user.config.region.preferences.helper'|trans }}</div>
{{ form_row(userForm.timezone) }}
{{ form_row(userForm.locale) }}
</div>
<div class="col-md-6">
<h3 id="security" class="pt-20 mb-xs">{{ 'mautic.user.config.title.account_data_security'|trans }}</h3>
<div class="text-secondary small pb-20">{{ 'mautic.user.config.account.security.helper'|trans }}</div>
{{ permissions.editUsername ? form_row(userForm.username) : form_row(userForm.username_unbound) }}
{{ permissions.editEmail ? form_row(userForm.email) : form_row(userForm.email_unbound) }}
{% if not isSamlUser %}
{{ form_row(userForm.plainPassword.password) }}
{{ form_row(userForm.plainPassword.confirm) }}
{% endif %}
<h3 id="learning" class="pt-20 mb-xs">{{ 'mautic.user.config.title.experience_and_learning'|trans }}</h3>
<div class="text-secondary small pb-20">{{ 'mautic.user.config.title.experience_and_learning.description'|trans }}</div>
{% include '@MauticCore/Helper/button.html.twig' with {
buttons: [
{
label: 'mautic.user.config.title.experience_and_learning.reset_dismissed',
variant: 'tertiary',
size: 'sm',
icon: 'ri-refresh-line',
danger: true,
onclick: 'Mautic.resetDismissedElements()',
}
]
} %}
</div>
</div>
{{ form_row(userForm.preferences) }}
{{ form_end(userForm) }}
</div>
{% if permissions.apiAccess is defined and permissions.apiAccess %}
<div class="tab-pane fade bdr-rds-0 bdr-w-0" id="clients">
<div class="row pa-md bdr-b">
<h4 class="fw-sb">{{ 'mautic.user.account.header.authorizedclients'|trans }}</h4>
</div>
<div class="row">
{{ authorizedClients|raw }}
</div>
</div>
{% endif %}
<div class="tab-pane fade bdr-rds-0 bdr-w-0" id="appearance">
<div class="row pa-md bdr-b">
<h4 class="fw-sb">{{ 'mautic.user.account.appearance'|trans }}</h4>
</div>
<div class="row">
<div class="col-xs-12 mb-lg">
<h3 class="pt-20">
{{ 'mautic.user.account.appearance.theme_preferences'|trans }}
{% include '@MauticCore/Components/toggletip.html.twig' with {
title: 'mautic.user.account.appearance.theme_preferences.popover.title',
content: 'mautic.user.account.appearance.theme_preferences.popover.content',
} %}
</h3>
<div class="help-block mb-md">{{ 'mautic.user.account.appearance.theme_help'|trans }}</div>
<div class="radio-group radio-cards row">
{{ include('@MauticUser/Helper/theme.html.twig', {
themes: [
{
id: 'light',
name: 'mautic.user.account.appearance.theme_light',
description: 'mautic.user.account.appearance.theme_light_description',
preview: '@MauticUser/Profile/images/_light_preview.html.twig',
checked: true
},
{
id: 'dark',
name: 'mautic.user.account.appearance.theme_dark',
description: 'mautic.user.account.appearance.theme_dark_description',
preview: '@MauticUser/Profile/images/_dark_preview.html.twig'
},
{
id: 'solarized-light',
name: 'mautic.user.account.appearance.theme_solarized_light',
description: 'mautic.user.account.appearance.theme_solarized_light_description',
preview: 'app/bundles/UserBundle/Resources/views/Profile/images/_solarized_light_preview.svg'
},
{
id: 'solarized-dark',
name: 'mautic.user.account.appearance.theme_solarized_dark',
description: 'mautic.user.account.appearance.theme_solarized_dark_description',
preview: 'app/bundles/UserBundle/Resources/views/Profile/images/_solarized_dark_preview.svg'
},
{
id: 'dark-freire',
name: 'mautic.user.account.appearance.theme_freire',
description: 'mautic.user.account.appearance.theme_freire_description',
preview: 'app/bundles/UserBundle/Resources/views/Profile/images/_freire_preview.svg'
}
]
}) }}
</div>
</div>
</div>
</div>
<div class="tab-pane fade bdr-rds-0 bdr-w-0" id="accessibility">
<div class="row pa-md bdr-b">
<h4 class="fw-sb">{{ 'mautic.user.account.accessibility'|trans }}</h4>
</div>
<div class="row">
<div class="col-xs-12 mb-lg">
<h3 class="pt-20 mb-md">{{ 'mautic.user.account.accessibility.appearance'|trans }}</h3>
<h4>{{ 'mautic.user.account.accessibility.smooth_color_transitions'|trans }}</h4>
<div class="help-block">{{ 'mautic.user.account.accessibility.smooth_color_transitions_help'|trans }}</div>
<div class="radio-group">
<div class="radio-option">
<input type="radio" id="transitions-enabled" name="reduce-motion" value="false"
data-attribute-toggle="reduce-motion" data-attribute-value="false" checked>
<label for="transitions-enabled">
<strong>{{ 'mautic.user.account.accessibility.enabled'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.transitions_enabled_description'|trans }}
</div>
</label>
</div>
<div class="radio-option">
<input type="radio" id="transitions-disabled" name="reduce-motion" value="true"
data-attribute-toggle="reduce-motion" data-attribute-value="true">
<label for="transitions-disabled">
<strong>{{ 'mautic.user.account.accessibility.disabled'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.transitions_disabled_description'|trans }}</div>
</label>
</div>
</div>
<hr>
<h4>{{ 'mautic.user.account.accessibility.borders_outline_style'|trans }}</h4>
<div class="help-block">{{ 'mautic.user.account.accessibility.borders_outline_style_help'|trans }}</div>
<div class="radio-group">
<div class="radio-option">
<input type="radio" id="borders-disabled" name="contrast-borders" value="false"
data-attribute-toggle="contrast-borders" data-attribute-value="false" checked>
<label for="borders-disabled">
<strong>{{ 'mautic.user.account.accessibility.disabled'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.borders_disabled_description'|trans }}
</div>
</label>
</div>
<div class="radio-option">
<input type="radio" id="borders-enabled" name="contrast-borders" value="true"
data-attribute-toggle="contrast-borders" data-attribute-value="true">
<label for="borders-enabled">
<strong>{{ 'mautic.user.account.accessibility.enabled'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.borders_enabled_description'|trans }}
</div>
</label>
</div>
</div>
<hr>
<h4>{{ 'mautic.user.account.accessibility.reduce_transparency_blur'|trans }}</h4>
<div class="help-block">{{ 'mautic.user.account.accessibility.reduce_transparency_blur_help'|trans }}</div>
<div class="radio-group">
<div class="radio-option">
<input type="radio" id="transparency-normal" name="reduce-transparency"
value="false" data-attribute-toggle="reduce-transparency"
data-attribute-value="false" checked>
<label for="transparency-normal">
<strong>{{ 'mautic.user.account.accessibility.normal'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.transparency_normal_description'|trans }}
</div>
</label>
</div>
<div class="radio-option">
<input type="radio" id="transparency-reduced" name="reduce-transparency"
value="true" data-attribute-toggle="reduce-transparency"
data-attribute-value="true">
<label for="transparency-reduced">
<strong>{{ 'mautic.user.account.accessibility.reduced'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.transparency_reduced_description'|trans }}</div>
</label>
</div>
</div>
<hr>
<h3 class="pt-20 mb-md">{{ 'mautic.user.account.accessibility.content'|trans }}</h3>
<h4>{{ 'mautic.user.account.accessibility.link_underlines'|trans }}</h4>
<div class="help-block">{{ 'mautic.user.account.accessibility.link_underlines_help'|trans }}
</div>
<div class="radio-group">
<div class="radio-option">
<input type="radio" id="underlines-disabled" name="enable-underlines" value="false"
data-attribute-toggle="enable-underlines" data-attribute-value="false" checked>
<label for="underlines-disabled">
<strong>{{ 'mautic.user.account.accessibility.disabled'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.underlines_disabled_description'|trans }}
</div>
</label>
</div>
<div class="radio-option">
<input type="radio" id="underlines-enabled" name="enable-underlines" value="true"
data-attribute-toggle="enable-underlines" data-attribute-value="true">
<label for="underlines-enabled">
<strong>{{ 'mautic.user.account.accessibility.enabled'|trans }}</strong>
<div class="text-help">{{ 'mautic.user.account.accessibility.underlines_enabled_description'|trans }}
</div>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!--/ end: container -->
</div>
{% endblock %}

View File

@@ -0,0 +1,105 @@
{% extends '@MauticCore/Default/content.html.twig' %}
{% block mauticContent %}role{% endblock %}
{% do assetAddScriptDeclaration('MauticVars.permissionList = ' ~ (permissionsConfig['list']|json_encode), 'bodyClose') %}
{% set objectId = form.vars.data.getId() %}
{% if objectId is not empty %}
{% set name = form.vars.data.getName() %}
{% set header = 'mautic.user.role.header.edit'|trans({'%name%' : name}) %}
{% else %}
{% set header = 'mautic.user.role.header.new'|trans %}
{% endif %}
{% block headerTitle %}{{ header }}{% endblock %}
{% block content %}
{{ form_start(form) }}
<div class="box-layout">
<div class="col-xs-12 height-auto">
<!-- tabs controls -->
<ul class="nav nav-tabs nav-tabs-contained">
<li class="active"><a href="#details-container" role="tab" data-toggle="tab">{% trans %}mautic.core.details{% endtrans %}</a></li>
<li class="" id="permissions-tab"><a href="#permissions-container" role="tab" data-toggle="tab">{% trans %}mautic.user.role.permissions{% endtrans %}</a></li>
</ul>
<!--/ tabs controls -->
<div class="tab-content pa-md">
<div class="tab-pane fade in active bdr-w-0 height-auto" id="details-container">
<div class="row">
<div class="pa-md">
<div class="col-md-6">
{{ form_row(form.name) }}
</div>
<div class="col-md-6">
{{ form_row(form.isAdmin) }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="pa-md">
{{ form_row(form.description) }}
</div>
</div>
</div>
</div>
{% set hidePerms = form.isAdmin.vars.data %}
<div class="tab-pane fade bdr-w-0" id="permissions-container">
<div id="rolePermissions"{% if hidePerms %}class="hide"{% endif %}>
<!-- start: box layout -->
<div class="box-layout">
<!-- step container -->
<div class="col-md-5 height-auto">
<div class="pr-lg pl-lg pt-md pb-md">
<!-- Nav tabs -->
<ul class="list-group list-group-tabs" role="tablist">
{% for bundle, config in permissionsConfig['config'] %}
<li role="presentation" class="list-group-item {{ loop.index0 is same as(0) ? 'in active' : '' }}">
<a href="#{{ bundle }}PermissionTab" aria-controls="{{ bundle }}PermissionTab" role="tab" data-toggle="tab" class="list-group-item-heading steps">
<span>{{ config['label'] }}</span>
<span class="permission-ratio"> (<span class="{{ bundle }}_granted">{{ config['ratio'][0] }}</span> / <span class="{{ bundle }}_total">{{ config['ratio'][1] }}</span>)</span>
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
<!-- container -->
<div class="col-md-7 height-auto bdr-l">
<div class="tab-content">
{% set permissions = form.permissions.children %}
{% for child in permissions %}
{% if 'newbundle' == child.vars.value %}
{% if loop.index0 > 0 %}
{# // Close tab panel #}
</div>{{ "\n" }}</div>{{ "\n" }}
{% endif %}
<div role="tabpanel" class="tab-pane fade{{ 0 is same as(loop.index0) ? ' in active' : '' }} bdr-w-0" id="{{ child.vars.name }}PermissionTab">{{ "\n" }}
<div class="pt-md pr-md pl-md pb-md"> {{ "\n" }}
{% do child.setRendered() %}
{% else %}
{{ form_row(child) }}
{% endif %}
{% endfor %}
{# //close last tab #}
</div>{{ "\n" }}
{% do form.permissions.setRendered() %}
</div>
</div>
</div>
</div>
<div id="isAdminMessage"{% if not hidePerms %} class="hide"{% endif %}>
<div class="alert alert-warning">
<h4>{% trans %}mautic.user.role.permission.isadmin.header{% endtrans %}</h4>
<p>{% trans %}mautic.user.role.permission.isadmin.message{% endtrans %}</p>
</div>
</div>
</div>
</div>
</div>
</div>
{{ form_end(form) }}
{% endblock %}

View File

@@ -0,0 +1,150 @@
{% set isIndex = tmpl == 'index' ? true : false %}
{% set tmpl = 'list' %}
{% extends isIndex ? '@MauticCore/Default/content.html.twig' : '@MauticCore/Default/raw_output.html.twig' %}
{% block mauticContent %}role{% endblock %}
{% block headerTitle %}{% trans %}mautic.user.roles{% endtrans %}{% endblock %}
{% block content %}
{% if isIndex %}
<div id="page-list-wrapper" class="panel panel-default">
{{- include('@MauticCore/Helper/list_toolbar.html.twig', {
'searchValue': searchValue,
'action': currentRoute,
'page_actions': {
'templateButtons': {
'new': permissions['create'],
},
'routeBase': 'role',
'langVar': 'user.role',
},
'bulk_actions': {
'routeBase': 'role',
'langVar': 'user.role',
'templateButtons': {
'delete': permissions['delete']
}
},
'quickFilters': [
{
'search': 'mautic.user.user.searchcommand.isadmin',
'label': 'mautic.user.role.form.isadmin',
'tooltip': 'mautic.core.search.quickfilter.is_admin',
'icon': 'ri-admin-line'
}
]
}) -}}
<div class="page-list">
{{ block('listResults') }}
</div>
</div>
{% else %}
{{ block('listResults') }}
{% endif %}
{% endblock %}
{% block listResults %}
<div class="table-responsive">
<table class="table table-hover role-list" id="roleTable">
<thead>
<tr>
{{- include('@MauticCore/Helper/tableheader.html.twig',
{
'checkall' : 'true',
'target' : '#roleTable'
}
) -}}
{{- include(
'@MauticCore/Helper/tableheader.html.twig',
{
'sessionVar' : 'role',
'orderBy' : 'r.name',
'text' : 'mautic.core.name',
'class' : 'col-role-name',
'default' : true,
}
) -}}
{{- include(
'@MauticCore/Helper/tableheader.html.twig',
{
'sessionVar' : 'role',
'orderBy' : 'r.description',
'text' : 'mautic.core.description',
'class' : 'visible-md visible-lg col-role-desc',
}
) -}}
<th class="visible-md visible-lg col-rolelist-usercount">
{% trans %}mautic.user.role.list.thead.usercount{% endtrans %}
</th>
{{- include('@MauticCore/Helper/tableheader.html.twig',
{
'sessionVar' : 'role',
'orderBy' : 'r.id',
'text' : 'mautic.core.id',
'class' : 'visible-md visible-lg col-role-id',
}
) -}}
</tr>
</thead>
<tbody>
{% for item in items %}
{% set mauticTemplateVars = _context|merge({'item' : item}) %}
<tr>
<td>
{{- include('@MauticCore/Helper/list_actions.html.twig',
{
'item' : item,
'templateButtons' : {
'edit' : permissions['edit'],
'delete' : permissions['delete'],
},
'routeBase' : 'role',
'langVar' : 'user.role',
'pull' : 'left',
}) -}}
</td>
<td>
{% if permissions['edit'] %}
<a href="{{ path('mautic_role_action',
{'objectAction' : 'edit', 'objectId' : item.getId()}) }}" data-toggle="ajax">
{{ item.getName() }}
{{ customContent('role.name', mauticTemplateVars) }}
</a>
{% else %}
{{ item.getName() }}
{% endif %}
</td>
<td class="visible-md visible-lg">
{{ item.getDescription()|purify }}
</td>
<td class="visible-md visible-lg">
<a size="sm" class="label label-gray" href="{{ path('mautic_user_index',
{'search' : ('mautic.user.user.searchcommand.role'|trans) ~ ':&quot;' ~ item.getName() ~ '&quot;'}) }}" data-toggle="ajax"{{ userCounts[item.getId()] == 0 ? 'disabled=disabled' : '' }}>
{{ 'mautic.user.role.list.viewusers_count'|trans(
{'%count%' : userCounts[item.getId()]}
) }}
</a>
</td>
<td class="visible-md visible-lg">
{{ item.getId() }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="panel-footer">
{{- include('@MauticCore/Helper/pagination.html.twig',
{
'totalItems' : items|length,
'page' : page,
'limit' : limit,
'baseUrl' : path('mautic_role_index'),
'sessionVar' : 'role',
}
) -}}
</div>
{% endblock %}

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block pageTitle %}Mautic{% endblock %}</title>
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="icon" type="image/x-icon" href="{{ getOverridableUrl('images/favicon.ico') }}" />
<link rel="apple-touch-icon" href="{{ getOverridableUrl('images/apple-touch-icon.png') }}" />
{{ outputSystemStylesheets() }}
{{- include('@MauticCore/Default/script.html.twig') -}}
{{ outputHeadDeclarations() }}
</head>
<body>
<section id="main" role="main">
<div class="container ml-a mr-a" style="margin-top:100px;">
<div class="row">
<div class="col-lg-4 col-lg-offset-4">
<div class="panel" name="form-login">
<div class="panel-body">
<div class="mautic-logo img-circle mb-md text-center">
{{ source('@MauticCore/Assets/images/logo--minimized.svg') }}
</div>
<div id="main-panel-flash-msgs">
{{- include('@MauticCore/Notification/flashes.html.twig') -}}
</div>
{% block content %}{% endblock %}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-4 col-lg-offset-4 text-center text-secondary">
{{ 'mautic.core.copyright'|trans({'%date%' : date('Y').format('Y') }) }}
</div>
</div>
</div>
</section>
{{ securityGetAuthenticationContext() }}
</body>
</html>

View File

@@ -0,0 +1,69 @@
{% extends app.request.xmlHttpRequest ? '@MauticCore/Default/content.html.twig' : '@MauticUser/Security/base.html.twig' %}
{% block header %}{% trans %}mautic.user.auth.header{% endtrans %}{% endblock %}
{% block headerTitle %}{% trans %}mautic.user.auth.expired.header{% endtrans %}{% endblock %}
{% block content %}
{% if app.request.xmlHttpRequest %}
<div class="row">
<div class="col-xs-12 col-sm-8 col-md-6 inline-login">
{{ block('mainContent') }}
</div>
</div>
{% else %}
{{ block('mainContent') }}
{% endif %}
{% endblock %}
{% block mainContent %}
<form class="form-group login-form" name="login" data-toggle="ajax" role="form" action="{{ path('mautic_user_logincheck') }}" method="post">
<div class="input-group mb-md">
<span class="input-group-addon">
<i class="ri-user-6-fill"></i>
</span>
<label for="username" class="sr-only">{% trans %}mautic.user.auth.form.loginusername{% endtrans %}</label>
<input type="text" id="username" name="_username" class="form-control input-lg" value="{{ last_username|escape }}" required autofocus placeholder="{% trans %}mautic.user.auth.form.loginusername{% endtrans %}"/>
</div>
<div class="input-group mb-md">
<span class="input-group-addon">
<i class="ri-key-2-line"></i>
</span>
<label for="password" class="sr-only">{% trans %}mautic.core.password{% endtrans %}:</label>
<input type="password" id="password" name="_password" class="form-control input-lg" required placeholder="{% trans %}mautic.core.password{% endtrans %}"/>
</div>
<div class="checkbox-inline custom-primary pull-left mb-md">
<label for="remember_me">
<input type="checkbox" id="remember_me" name="_remember_me"/>
<span></span>
{% trans %}mautic.user.auth.form.rememberme{% endtrans %}
</label>
</div>
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate')|escape }}"/>
{% include '@MauticCore/Helper/button.html.twig' with {
buttons: [
{
label: 'mautic.user.auth.form.loginbtn',
variant: 'primary',
size: 'lg',
wide: true
}
]
} %}
<div class="mt-sm text-right">
<a href="{{ path('mautic_user_passwordreset') }}">{% trans %}mautic.user.user.passwordreset.link{% endtrans %}</a>
</div>
</form>
{% if integrations is not empty %}
<ul class="list-group">
{% for sso in integrations %}
<a href="{{ path('mautic_sso_login', {'integration' : sso.getName()}) }}" class="list-group-item">
<img class="pull-left mr-xs" style="height: 16px;" src="{{ getAssetUrl(sso.getIcon()) }}">
<p class="list-group-item-heading">{{ ('mautic.integration.sso.' ~ sso.getName())|trans }}</p>
</a>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,12 @@
{% extends app.request.xmlHttpRequest ? '@MauticCore/Default/content.html.twig' : '@MauticUser/Security/base.html.twig' %}
{% block content %}
<div class="alert alert-warning">{% trans %}mautic.user.user.passwordreset.info{% endtrans %}</div>
{{ form_start(form) }}
{{ form_row(form.identifier) }}
{{ form_widget(form.submit) }}
{{ form_end(form) }}
<div class="mt-sm">
<a href="{{ path('login') }}">{% trans %}mautic.user.user.passwordreset.back{% endtrans %}</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,15 @@
{% extends app.request.xmlHttpRequest ? '@MauticCore/Default/content.html.twig' : '@MauticUser/Security/base.html.twig' %}
{% block content %}
<div class="alert alert-warning">{% trans %}mautic.user.user.passwordresetconfirm.info{% endtrans %}</div>
{{ form_start(form) }}
{{ form_row(form.identifier) }}
{{ form_row(form.plainPassword.password) }}
{{ form_row(form.plainPassword.confirm) }}
{{ form_widget(form.submit) }}
{{ form_end(form) }}
<div class="mt-sm">
<a href="{{ path('login') }}">{% trans %}mautic.user.user.passwordreset.back{% endtrans %}</a>
</div>
{% endblock %}

View File

@@ -0,0 +1,6 @@
{% extends app.request.xmlHttpRequest ? '@MauticCore/Default/content.html.twig' : '@MauticUser/Security/base.html.twig' %}
{% block content %}
<a class="btn btn-lg btn-primary btn-block" href="{{ loginRoute }}">
{{ 'mautic.user.auth.form.loginbtn'|trans }}
</a>
{% endblock %}

View File

@@ -0,0 +1,10 @@
{% if showMore is defined and showMore is not empty %}
<a href="{{ url('mautic_role_index', {'filter-user' : searchString}) }}" data-toggle="ajax">
<span>{{ 'mautic.core.search.more'|trans({'%count%' : remaining}) }}</span>
</a>
{% else %}
<a href="{{ url('mautic_role_action', {'objectAction' : 'edit', 'objectId' : item.getId()}) }}">
<span class="fw-sb">{{ item.name }}</span>
<span class="ml-4 mr-sm">#{{ item.id }}</span>
</a>
{% endif %}

View File

@@ -0,0 +1,25 @@
{% if showMore is defined and showMore is not empty %}
<a href="{{ url('mautic_user_index', {'filter-user' : searchString}) }}" data-toggle="ajax">
<span>{{ 'mautic.core.search.more'|trans({'%count%' : remaining}) }}</span>
</a>
{% else %}
<div class="d-flex ai-center">
<span class="pull-left mr-sm pt-xs" style="width:36px">
<span class="img-wrapper img-rounded"><img src="{{ gravatarGetImage(item.getEmail(), '100') }}" /></span>
</span>
<div class="d-flex fd-column">
<div>
<a class="fw-sb mr-4" href="{{ url('mautic_user_action', {'objectAction' : 'edit', 'objectId' : item.getId()}) }}">
{{ item.getName() }}
</a>
{{- include('@MauticCore/Helper/publishstatus_badge.html.twig', {
'entity': item,
'status': 'active',
'simplified': 'true'
}) -}}
</div>
<div class="small text-muted">{{ item.getPosition() }}</div>
</div>
<div class="clearfix"></div>
</div>
{% endif %}

View File

@@ -0,0 +1,11 @@
{% extends '@MauticCore/Default/content.html.twig' %}
{% block mauticContent %}user{% endblock %}
{% block headerTitle %}{{ 'mautic.user.user.header.contact'|trans({'%name%': user.getName()}) }}{% endblock %}
{% block content %}
<div class="panel">
<div class="panel-body pa-md">
{{ form(form) }}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,94 @@
{% extends '@MauticCore/Default/content.html.twig' %}
{% block mauticContent %}user
{% endblock %}
{% set userId = form.vars.data.getId() %}
{% if userId is not empty %}
{% set user = form.vars.data.getName() %}
{% set header = 'mautic.user.user.header.edit'|trans({'%name%': user}) %}
{% else %}
{% set header = 'mautic.user.user.header.new'|trans %}
{% endif %}
{% block headerTitle %}
{{ header }}
{% endblock %}
{% block content %}
<!-- start: box layout -->
<div
class="box-layout">
<!-- container -->
{{ form_start(form) }}
<div class="col-md-9 height-auto bdr-r">
<div class="pa-md">
<div class="form-group mb-0">
<div class="row">
<div class="col-sm-6{{ form.firstName.vars.errors|length ? ' has-error' : '' }}">
<h3 class="mb-lg mt-lg">{{ 'mautic.user.config.title.personal_information'|trans }}</h3>
<div class="form-group">
<label class="control-label mb-xs">{{ form_label(form.firstName) }}</label>
{{ form_widget(form.firstName, {'attr' : {'placeholder' : form.firstName.vars.label }}) }}
{{ form_errors(form.firstName) }}
</div>
<div class="form-group{{ form.lastName.vars.errors|length ? ' has-error' : '' }}">
<label class="control-label mb-xs">{{ form_label(form.lastName) }}</label>
{{ form_widget(form.lastName, {'attr' : {'placeholder' : form.lastName.vars.label }}) }}
{{ form_errors(form.lastName) }}
</div>
<div class="form-group{{ form.role.vars.errors|length ? ' has-error' : '' }}">
<label class="control-label mb-xs">{{ form_label(form.role) }}</label>
{{ form_widget(form.role, {'attr' : {'placeholder' : form.role.vars.label }}) }}
{{ form_errors(form.role) }}
</div>
<div class="form-group pb-lg{{ form.position.vars.errors|length ? ' has-error' : '' }}">
<label class="control-label mb-xs">{{ form_label(form.position) }}</label>
{{ form_widget(form.position, {'attr' : {'placeholder' : form.position.vars.label }}) }}
{{ form_errors(form.position) }}
</div>
<div class="form-group pt-md{{ form.signature.vars.errors|length ? ' has-error' : '' }}">
<label class="control-label mb-xs">{{ form_label(form.signature) }}</label>
{{ form_widget(form.signature, {'attr' : {'placeholder' : form.signature.vars.label }}) }}
{{ form_errors(form.signature) }}
<p class="help-text">{{ 'mautic.user.config.signature.admin.helper'|trans }} </p>
</div>
</div>
<div class="col-sm-6">
<h3 class="mb-lg mt-lg">{{ 'mautic.user.config.title.account_data_security'|trans }}</h3>
<div class="form-group{{ form.username.vars.errors|length ? ' has-error' : '' }}">
{{ form_label(form.username) }}
{{ form_widget(form.username, {'attr' : {'placeholder' : form.username.vars.label }}) }}
{{ form_errors(form.username) }}
</div>
<div class="form-group{{ form.email.vars.errors|length ? ' has-error' : '' }}">
{{ form_label(form.email) }}
{{ form_widget(form.email, {'attr' : {'placeholder' : form.email.vars.label }}) }}
{{ form_errors(form.email) }}
</div>
{% if isSamlUser is empty %}
{{ form_widget(form.plainPassword, {'attr' : {'placeholder' : form.plainPassword.vars.label }}) }}
{% endif %}
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3 height-auto">
<div class="pr-lg pl-lg pt-md pb-md">
<h3 class="mb-lg mt-lg">{{ 'mautic.user.config.title.locale'|trans }}</h3>
{{ form_rest(form) }}
</div>
</div>
{% if editAction is defined and editAction == true %}
{{- include('@MauticUser/User/recent_activity.html.twig', {
'logs' : logs,
'users' : users,
'roles' : roles,
}) -}}
{% endif %}
{{ form_end(form) }}
</div>
{% endblock %}

View File

@@ -0,0 +1,174 @@
{% set isIndex = tmpl == 'index' ? true : false %}
{% set tmpl = 'list' %}
{% extends isIndex ? '@MauticCore/Default/content.html.twig' : '@MauticCore/Default/raw_output.html.twig' %}
{% block mauticContent %}user
{% endblock %}
{% block headerTitle %}
{% trans %}mautic.user.users{% endtrans %}
{% endblock %}
{% block content %}
{% if isIndex %}
<div id="page-list-wrapper" class="panel panel-default">
{{- include('@MauticCore/Helper/list_toolbar.html.twig', {
'searchValue': searchValue,
'action': currentRoute,
'page_actions': {
'templateButtons': {
'new': permissions['create'],
},
'routeBase': 'user',
'langVar': 'user.user',
},
'bulk_actions': {
'routeBase': 'user',
'langVar': 'user.user',
'templateButtons': {
'delete': permissions['delete']
}
},
'quickFilters': [
{
'search': 'mautic.user.user.searchcommand.isadmin',
'label': 'mautic.user.role.form.isadmin',
'tooltip': 'mautic.core.search.quickfilter.is_admin',
'icon': 'ri-admin-line'
},
{
'search': 'mautic.core.searchcommand.ispublished',
'label': 'mautic.core.form.active',
'tooltip': 'mautic.core.search.quickfilter.is_published',
'icon': 'ri-check-line'
},
{
'search': 'mautic.core.searchcommand.isunpublished',
'label': 'mautic.core.form.inactive',
'tooltip': 'mautic.core.search.quickfilter.is_unpublished',
'icon': 'ri-close-line'
}
]
}) -}}
<div class="page-list">
{{ block('listResults') }}
</div>
</div>
{% else %}
{{ block('listResults') }}
{% endif %}
{% endblock %}
{% block listResults %}
<div class="table-responsive">
<table class="table table-hover user-list" id="userTable">
<thead>
<tr>
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'checkall' : 'true',
'target' : '#userTable'
}) -}}
<th class="visible-md visible-lg col-user-avatar"></th>
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'sessionVar' : 'user',
'orderBy' : 'u.lastName, u.firstName, u.username',
'text' : 'mautic.core.name',
'class' : 'col-user-name',
'default' : true,
}) -}}
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'sessionVar' : 'user',
'orderBy' : 'u.username',
'text' : 'mautic.core.username',
'class' : 'col-user-username',
}) -}}
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'sessionVar' : 'user',
'orderBy' : 'u.email',
'text' : 'mautic.core.type.email',
'class' : 'visible-md visible-lg col-user-email',
}) -}}
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'sessionVar' : 'user',
'orderBy' : 'r.name',
'text' : 'mautic.user.role',
'class' : 'visible-md visible-lg col-user-role',
}) -}}
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'sessionVar' : 'user',
'orderBy' : 'u.lastLogin',
'text' : 'mautic.user.lastlogin',
'class' : 'visible-md visible-lg col-user-lastlogin',
}) -}}
{{- include('@MauticCore/Helper/tableheader.html.twig', {
'sessionVar' : 'user',
'orderBy' : 'u.id',
'text' : 'mautic.core.id',
'class' : 'visible-md visible-lg col-user-id',
}) -}}
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td>
{{- include('@MauticCore/Helper/list_actions.html.twig', {
'item' : item,
'templateButtons' : {
'edit' : permissions['edit'],
'delete' : permissions['delete'],
},
'routeBase' : 'user',
'langVar' : 'user.user',
'pull' : 'left',
}) -}}
</td>
<td class="visible-md visible-lg">
<img class="img img-responsive img-thumbnail w-44" src="{{ gravatarGetImage(item.getEmail(), '50') }}"/>
</td>
<td>
<div>
{% if item.getId() != currentUserId %}
{{- include('@MauticCore/Helper/publishstatus_icon.html.twig', {
'item' : item,
'model' : 'user',
}) -}}
{% endif %}
{% if permissions['edit'] %}
<a href="{{ path( 'mautic_user_action', {'objectAction' : 'edit', 'objectId' : item.getId()} ) }}" data-toggle="ajax">
{{ item.getName(true) }}
</a>
{% else %}
{{ item.getName(true) }}
{% endif %}
</div>
<div class="small">
<em>{{ item.getPosition() }}</em>
</div>
</td>
<td>{{ item.getUsername() }}</td>
<td class="visible-md visible-lg">
<a href="mailto: {{ item.getEmail() }}">{{ item.getEmail() }}</a>
</td>
<td class="visible-md visible-lg">{{ item.getRole().getName() }}</td>
<td class="visible-md visible-lg">{{ dateToText(item.getLastLogin(), 'local', 'Y-m-d H:i:s', true) }}</td>
<td class="visible-md visible-lg">{{ item.getId() }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="panel-footer">
{{- include('@MauticCore/Helper/pagination.html.twig', {
'totalItems' : items|length,
'page' : page,
'limit' : limit,
'baseUrl' : path('mautic_user_index'),
'sessionVar' : 'user',
}) -}}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,195 @@
<!-- Recent activity block(audit_log table) -->
<div class="col-md-3 height-auto">
{{ customContent('right.section.top', _context) }}
<div class="panel shd-none bdr-rds-0 bdr-w-0 mb-0">
<div class="panel-heading">
<div class="panel-title">{% trans %}mautic.core.recent.activity{% endtrans %}</div>
</div>
<div class="panel-body pt-xs">
{% if logs is defined and logs is not empty %}
<ul class="media-list media-list-feed">
{% for log in logs %}
{% if log.action == 'create' and log.object == 'user' %}
{% set userPath = [] %}
{% set user_id = '1' %}
{% set usersEmail = log.details['email'][1] %}
{% set emailIsMatch = false %}
{% set usernameIsMatch = false %}
{% for user in users %}
{% if usersEmail is defined and usersEmail is not empty and user.email == usersEmail %}
{% set emailIsMatch = true %}
{% set user_id = user.id %}
{% else %}
{% set usernameIsMatch = true %}
{% set user_id = user.id %}
{% endif %}
{% endfor %}
{% if log.details['username'][1] is defined and log.details['username'][1] is not empty %}
{% if usernameIsMatch == true or emailIsMatch == true %}
{% set userPath = userPath|merge([user_id, log.details['username'][1]]) %}
{% endif %}
{% endif %}
{% elseif log.action == 'create' and log.object == 'role' %}
{% set role_id = '1' %}
{% set roleName = log.details['name'][1] %}
{% set roleIsMatch = false %}
{% for role in roles %}
{% if role.name == roleName %}
{% set roleIsMatch = true %}
{% set role_id = role.id %}
{% endif %}
{% endfor %}
{% if roleIsMatch == true %}
{% set rolePath = []|merge([role_id, roleName]) %}
{% endif %}
{% elseif log.action == 'update' and log.object == 'user' %}
{% set userPath = [] %}
{% set usersUsername, usersEmail, usersFirstName, usersLastName, usersRole, usersPosition, usersSignature = '', '', '', '', '', '', '' %}
{% set user_id = '1' %}
{% set user_username = 'admin' %}
{% set isMatch = false %}
{% for detail in log.details %}
{% if detail == 'username' %}
{% set usersUsername = detail[1] %}
{% elseif detail == 'email' %}
{% set usersEmail = detail[1] %}
{% elseif detail == 'firstname' %}
{% set usersFirstName = detail[1] %}
{% elseif detail == 'lastName' %}
{% set usersLastName = detail[1] %}
{% elseif detail == 'role' %}
{% set usersRole = detail[1] %}
{% elseif detail == 'position' %}
{% set usersPosition = detail[1] %}
{% elseif detail == 'signature' %}
{% set usersSignature = detail[1] %}
{% endif %}
{% endfor %}
{% for user in users %}
{% if user.email == usersEmail or user.userName == usersUsername or user.firstName == usersFirstName
or user.lastName == usersLastName or user.role == usersRole
or user.position == usersPosition or user.signature == usersSignature %}
{% set isMatch = true %}
{% set user_id = user.id %}
{% set user_username = user.userName %}
{% endif %}
{% endfor %}
{% if isMatch == true %}
{% set userPath = userPath|merge([user_id, user_username]) %}
{% endif %}
{% elseif log.action == 'update' and log.object == 'role' %}
{% set name, description, rowPermissions = '', '', '' %}
{% set role_id = '1' %}
{% set roleName = 'Admininstrator' %}
{% set isMatch = false %}
{% for detail in log.details %}
{% if detail == 'name' %}
{% set name = detail[1] %}
{% elseif detail == 'description' %}
{% set description = detail[1] %}
{% elseif detail == 'rawPermissions' %}
{% set rowPermissions = detail[1] %}
{% endif %}
{% endfor %}
{% for role in roles %}
{% if role.name == name or role.description == description or
role.rawPermissions == rowPermissions %}
{% set isMatch = true %}
{% set role_id = role.id %}
{% set roleName = role.name %}
{% endif %}
{% endfor %}
{% if isMatch == true %}
{% set rolePath = []|merge([role_id, roleName]) %}
{% endif %}
{% endif %}
<li class="media">
<div class="media-object pull-left">
{% if log.action == 'login' %}
<span class="figure featured">
<span class="ri-login-circle-line"></span>
</span>
{% elseif log.action == 'update' %}
<span class="figure"></span>
{% else %}
<span class="figure"></span>
{% endif %}
</div>
<div class="media-body">
{% if log.object == 'user' %}
{% if log.action == 'update' %}
{{ 'mautic.user.user.form.user'|trans }}
<a href="{{ path('mautic_user_action', {objectAction: 'edit', objectId: userPath[0]}) }}" data-toggle="ajax">
{{ userPath[1] }}</a>
{{ 'mautic.user.role.form.updated_by'|trans }}
{% elseif log.action == 'create' %}
<a href="{{ path('mautic_user_action', {objectAction: 'edit', objectId: userPath[0]}) }}" data-toggle="ajax">
{{ userPath[1] }}</a>
{{ 'mautic.user.user.form.created_by'|trans }}
{% endif %}
{% elseif log.object == 'role' %}
{% if log.action == 'create' %}
{{ 'mautic.role.role'|trans }}
<a href="{{ path('mautic_role_action', {objectAction: 'edit', objectId: rolePath[0]}) }}" data-toggle="ajax">
{{ rolePath[1] }}</a>
{{ 'mautic.user.user.form.created_by'|trans }}
{% elseif log.action == 'update' %}
{{ 'mautic.role.role'|trans }}
<a href="{{ path('mautic_role_action', {objectAction: 'edit', objectId: rolePath[0]}) }}" data-toggle="ajax">
{{ rolePath[1] }}</a>
{{ 'mautic.user.role.form.updated_by'|trans }}
{% endif %}
{% elseif log.object == 'security' %}
{% if log.action == 'login' %}
{{ 'mautic.user.user.form.user'|trans }}
{% elseif log.action == 'update' %}
{{ 'mautic.user.user.form.updated_by'|trans }}
{% endif %}
{% endif %}
{% if log.userId is defined and log.userId is not empty %}
<a href="{{ path('mautic_user_action', {objectAction: 'edit', objectId: log.userId}) }}" data-toggle="ajax">{{ log.userName }}</a>
{% if log.action == 'login' %}{{ 'mautic.user.user.form.login_by'|trans }}{% endif %}
{% else %}
{{ log.userName }}
{% endif %}
<p class="fs-12 dark-sm">
<small>
{{ dateToFull(log.dateAdded) }}</small>
</p>
</div>
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{{ customContent('right.section.bottom', _context) }}
</div>
<!-- Recent activity block(audit_log table) -->