mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-08-20 14:43:49 +00:00
Merge branch 'master' into testing
This commit is contained in:
@@ -22,6 +22,7 @@ use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Chill\MainBundle\Repository\LocationRepository;
|
||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
|
||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||
@@ -57,6 +58,8 @@ final class ActivityController extends AbstractController
|
||||
|
||||
private ActivityTypeRepository $activityTypeRepository;
|
||||
|
||||
private CenterResolverManagerInterface $centerResolver;
|
||||
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
private EventDispatcherInterface $eventDispatcher;
|
||||
@@ -86,7 +89,8 @@ final class ActivityController extends AbstractController
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
LoggerInterface $logger,
|
||||
SerializerInterface $serializer,
|
||||
UserRepositoryInterface $userRepository
|
||||
UserRepositoryInterface $userRepository,
|
||||
CenterResolverManagerInterface $centerResolver
|
||||
) {
|
||||
$this->activityACLAwareRepository = $activityACLAwareRepository;
|
||||
$this->activityTypeRepository = $activityTypeRepository;
|
||||
@@ -101,6 +105,7 @@ final class ActivityController extends AbstractController
|
||||
$this->logger = $logger;
|
||||
$this->serializer = $serializer;
|
||||
$this->userRepository = $userRepository;
|
||||
$this->centerResolver = $centerResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,7 +208,7 @@ final class ActivityController extends AbstractController
|
||||
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_UPDATE', $entity);
|
||||
|
||||
$form = $this->createForm(ActivityType::class, $entity, [
|
||||
'center' => $entity->getCenters()[0] ?? null,
|
||||
'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null,
|
||||
'role' => new Role('CHILL_ACTIVITY_UPDATE'),
|
||||
'activityType' => $entity->getActivityType(),
|
||||
'accompanyingPeriod' => $accompanyingPeriod,
|
||||
@@ -431,7 +436,7 @@ final class ActivityController extends AbstractController
|
||||
$this->denyAccessUnlessGranted(ActivityVoter::CREATE, $entity);
|
||||
|
||||
$form = $this->createForm(ActivityType::class, $entity, [
|
||||
'center' => $entity->getCenter(),
|
||||
'center' => $this->centerResolver->resolveCenters($entity)[0] ?? null,
|
||||
'role' => new Role('CHILL_ACTIVITY_CREATE'),
|
||||
'activityType' => $entity->getActivityType(),
|
||||
'accompanyingPeriod' => $accompanyingPeriod,
|
||||
|
@@ -306,14 +306,14 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac
|
||||
* get the center
|
||||
* center is extracted from person.
|
||||
*/
|
||||
public function getCenters(): array
|
||||
public function getCenters(): iterable
|
||||
{
|
||||
if ($this->person instanceof Person) {
|
||||
return [$this->person->getCenter()];
|
||||
}
|
||||
|
||||
if ($this->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
||||
return $this->getAccompanyingPeriod()->getCenters();
|
||||
return $this->getAccompanyingPeriod()->getCenters() ?? [];
|
||||
}
|
||||
|
||||
return [];
|
||||
|
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialActionRepository;
|
||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class BySocialActionAggregator implements AggregatorInterface
|
||||
{
|
||||
private SocialActionRender $actionRender;
|
||||
|
||||
private SocialActionRepository $actionRepository;
|
||||
|
||||
public function __construct(
|
||||
SocialActionRender $actionRender,
|
||||
SocialActionRepository $actionRepository
|
||||
) {
|
||||
$this->actionRender = $actionRender;
|
||||
$this->actionRepository = $actionRepository;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function($value) {
|
||||
if ('_header' === $value) {
|
||||
return 'Social action';
|
||||
}
|
||||
|
||||
$sa = $this->actionRepository->find($value);
|
||||
|
||||
return $this->actionRender->renderString($sa, []);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['socialaction_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by linked socialaction';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if(!in_array('socialaction', $qb->getAllAliases())) {
|
||||
$qb->join('activity.socialActions', 'socialaction');
|
||||
}
|
||||
|
||||
$qb->addSelect('socialaction.id AS socialaction_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('socialaction_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('socialaction_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\PersonBundle\Repository\SocialWork\SocialIssueRepository;
|
||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class BySocialIssueAggregator implements AggregatorInterface
|
||||
{
|
||||
private SocialIssueRepository $issueRepository;
|
||||
|
||||
private SocialIssueRender $issueRender;
|
||||
|
||||
public function __construct(
|
||||
SocialIssueRepository $issueRepository,
|
||||
SocialIssueRender $issueRender
|
||||
) {
|
||||
$this->issueRepository = $issueRepository;
|
||||
$this->issueRender = $issueRender;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
|
||||
if ($value === '_header') {
|
||||
return 'Social issues';
|
||||
}
|
||||
|
||||
$i = $this->issueRepository->find($value);
|
||||
|
||||
return $this->issueRender->renderString($i, []);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['socialissue_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by linked socialissue';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('socialissue', $qb->getAllAliases())) {
|
||||
$qb->join('activity.socialIssues', 'socialissue');
|
||||
}
|
||||
|
||||
$qb->addSelect('socialissue.id AS socialissue_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('socialissue_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('socialissue_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
|
||||
use Chill\ThirdPartyBundle\Templating\Entity\ThirdPartyRender;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class ByThirdpartyAggregator implements AggregatorInterface
|
||||
{
|
||||
private ThirdPartyRepository $thirdPartyRepository;
|
||||
|
||||
private ThirdPartyRender $thirdPartyRender;
|
||||
|
||||
public function __construct(
|
||||
ThirdPartyRepository $thirdPartyRepository,
|
||||
ThirdPartyRender $thirdPartyRender
|
||||
) {
|
||||
$this->thirdPartyRepository = $thirdPartyRepository;
|
||||
$this->thirdPartyRender = $thirdPartyRender;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Accepted thirdparty';
|
||||
}
|
||||
|
||||
$tp = $this->thirdPartyRepository->find($value);
|
||||
|
||||
return $this->thirdPartyRender->renderString($tp, []);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['thirdparty_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by linked thirdparties';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('thirdparty', $qb->getAllAliases())) {
|
||||
$qb->join('activity.thirdParties', 'thirdparty');
|
||||
}
|
||||
|
||||
$qb->addSelect('thirdparty.id AS thirdparty_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('thirdparty_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('thirdparty_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class ByUserAggregator implements AggregatorInterface
|
||||
{
|
||||
private UserRepository $userRepository;
|
||||
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(
|
||||
UserRepository $userRepository,
|
||||
UserRender $userRender
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->userRender = $userRender;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Accepted users';
|
||||
}
|
||||
|
||||
$u = $this->userRepository->find($value);
|
||||
|
||||
return $this->userRender->renderString($u, []);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['users_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by linked users';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('user', $qb->getAllAliases())) {
|
||||
$qb->join('activity.users', 'user');
|
||||
}
|
||||
|
||||
$qb->addSelect('user.id AS users_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('users_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('users_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class DateAggregator implements AggregatorInterface
|
||||
{
|
||||
private const CHOICES = [
|
||||
'by month' => 'month',
|
||||
'by week' => 'week',
|
||||
'by year' => 'year',
|
||||
];
|
||||
|
||||
private CONST DEFAULT_CHOICE = 'year';
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(
|
||||
TranslatorInterface $translator
|
||||
) {
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value) use ($data): string {
|
||||
if ($value === '_header') {
|
||||
return 'by '. $data['frequency'];
|
||||
}
|
||||
switch ($data['frequency']) {
|
||||
case 'month':
|
||||
$month = \DateTime::createFromFormat('!m', $value);
|
||||
return sprintf(
|
||||
"%02d (%s)",
|
||||
$value,
|
||||
$month->format('M')
|
||||
);
|
||||
|
||||
case 'week':
|
||||
//return $this->translator->trans('for week') .' '. $value ;
|
||||
|
||||
case 'year':
|
||||
//return $this->translator->trans('in year') .' '. $value ;
|
||||
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['date_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('frequency', ChoiceType::class, [
|
||||
'choices' => self::CHOICES,
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'empty_data' => self::DEFAULT_CHOICE,
|
||||
'data' => self::DEFAULT_CHOICE,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by date';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$order = null;
|
||||
|
||||
switch ($data['frequency']) {
|
||||
case 'month':
|
||||
$fmt = 'MM'; break;
|
||||
|
||||
case 'week':
|
||||
$fmt = 'IW'; break;
|
||||
|
||||
case 'year':
|
||||
$fmt = 'YYYY'; $order = 'DESC'; break;
|
||||
|
||||
default:
|
||||
throw new RuntimeException(sprintf("The frequency data '%s' is invalid.", $data['frequency']));
|
||||
}
|
||||
|
||||
$qb->addSelect(sprintf("TO_CHAR(activity.date, '%s') AS date_aggregator", $fmt));
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('date_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('date_aggregator');
|
||||
}
|
||||
|
||||
$orderBy = $qb->getDQLPart('orderBy');
|
||||
|
||||
if (!empty($orderBy)) {
|
||||
$qb->addOrderBy('date_aggregator', $order);
|
||||
} else {
|
||||
$qb->orderBy('date_aggregator', $order);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\LocationTypeRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class LocationTypeAggregator implements AggregatorInterface
|
||||
{
|
||||
private LocationTypeRepository $locationTypeRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
LocationTypeRepository $locationTypeRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->locationTypeRepository = $locationTypeRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Accepted locationtype';
|
||||
}
|
||||
|
||||
$lt = $this->locationTypeRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize(
|
||||
$lt->getTitle()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['locationtype_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by locationtype';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('location', $qb->getAllAliases())) {
|
||||
$qb->join('activity.location', 'location');
|
||||
}
|
||||
|
||||
$qb->addSelect('IDENTITY(location.locationType) AS locationtype_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('locationtype_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('locationtype_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\ACPAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\ScopeRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserScopeAggregator implements AggregatorInterface
|
||||
{
|
||||
private ScopeRepository $scopeRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
ScopeRepository $scopeRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->scopeRepository = $scopeRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return function ($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Scope';
|
||||
}
|
||||
|
||||
$s = $this->scopeRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['userscope_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group activity by userscope';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('user', $qb->getAllAliases())) {
|
||||
$qb->join('activity.user', 'user');
|
||||
}
|
||||
|
||||
$qb->addSelect('IDENTITY(user.mainScope) AS userscope_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('userscope_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('userscope_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -11,6 +11,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
@@ -44,16 +45,24 @@ class ActivityTypeAggregator implements AggregatorInterface
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
// add select element
|
||||
$qb->addSelect(sprintf('IDENTITY(activity.type) AS %s', self::KEY));
|
||||
if (!in_array('type', $qb->getAllAliases())) {
|
||||
$qb->join('activity.activityType', 'type');
|
||||
}
|
||||
|
||||
// add the "group by" part
|
||||
$qb->addGroupBy(self::KEY);
|
||||
$qb->addSelect(sprintf('IDENTITY(activity.activityType) AS %s', self::KEY));
|
||||
|
||||
$groupby = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy(self::KEY);
|
||||
} else {
|
||||
$qb->groupBy(self::KEY);
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
public function applyOn(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
|
@@ -11,9 +11,11 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@@ -25,10 +27,14 @@ class ActivityUserAggregator implements AggregatorInterface
|
||||
|
||||
private UserRepository $userRepository;
|
||||
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(
|
||||
UserRepository $userRepository
|
||||
UserRepository $userRepository,
|
||||
UserRender $userRender
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->userRender = $userRender;
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
@@ -47,7 +53,7 @@ class ActivityUserAggregator implements AggregatorInterface
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
@@ -62,10 +68,12 @@ class ActivityUserAggregator implements AggregatorInterface
|
||||
|
||||
return function ($value) {
|
||||
if ('_header' === $value) {
|
||||
return 'activity user';
|
||||
return 'Activity user';
|
||||
}
|
||||
|
||||
return $this->userRepository->find($value)->getUsername();
|
||||
$u = $this->userRepository->find($value);
|
||||
|
||||
return $this->userRender->renderString($u, []);
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -9,8 +9,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Aggregator;
|
||||
namespace Chill\ActivityBundle\Export\Aggregator\PersonAggregators;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Repository\ActivityReasonCategoryRepository;
|
||||
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
@@ -104,9 +105,9 @@ class ActivityReasonAggregator implements AggregatorInterface, ExportElementVali
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
public function applyOn(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY_PERSON;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
24
src/Bundle/ChillActivityBundle/Export/Declarations.php
Normal file
24
src/Bundle/ChillActivityBundle/Export/Declarations.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export;
|
||||
|
||||
/**
|
||||
* This class declare constants used for the export framework.
|
||||
*/
|
||||
abstract class Declarations
|
||||
{
|
||||
public const ACTIVITY = 'activity';
|
||||
|
||||
public const ACTIVITY_ACP = "activity_linked_to_acp";
|
||||
|
||||
public const ACTIVITY_PERSON = "activity_linked_to_person";
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Closure;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class AvgActivityDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
protected EntityRepository $repository;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em
|
||||
) {
|
||||
$this->repository = $em->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// TODO: Implement buildForm() method.
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Average activity linked to an accompanying period duration';
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Average activities linked to an accompanying period duration by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_avg_activity_duration' !== $key) {
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
return static fn ($value) => '_header' === $value ? 'Average activities linked to an accompanying period duration' : $value;
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_avg_activity_duration'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('activity')
|
||||
->join('activity.accompanyingPeriod', 'acp')
|
||||
;
|
||||
|
||||
$qb->select('AVG(activity.durationTime) as export_avg_activity_duration');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(ActivityStatsVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_ACP,
|
||||
//PersonDeclarations::ACP_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to an accompanying period';
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Closure;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class AvgActivityVisitDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
protected EntityRepository $repository;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em
|
||||
) {
|
||||
$this->repository = $em->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// TODO: Implement buildForm() method.
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Average activity linked to an accompanying period visit duration';
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Average activities linked to an accompanying period visit duration by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_avg_activity_visit_duration' !== $key) {
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
return static fn ($value) => '_header' === $value ? 'Average activities linked to an accompanying period visit duration' : $value;
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_avg_activity_visit_duration'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('activity')
|
||||
->join('activity.accompanyingPeriod', 'acp')
|
||||
;
|
||||
|
||||
$qb->select('AVG(activity.travelTime) as export_avg_activity_visit_duration');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(ActivityStatsVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_ACP,
|
||||
//PersonDeclarations::ACP_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to an accompanying period';
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class CountActivity implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
protected EntityRepository $repository;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em
|
||||
) {
|
||||
$this->repository = $em->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Count activities linked to an accompanying period by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_count_activity' !== $key) {
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
return static fn ($value) => '_header' === $value ? 'Number of activities linked to an accompanying period' : $value;
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_count_activity'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Count activities linked to an accompanying period';
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('activity')
|
||||
->join('activity.accompanyingPeriod', 'acp')
|
||||
;
|
||||
|
||||
$qb->select('COUNT(activity.id) as export_count_activity');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(ActivityStatsVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_ACP,
|
||||
//PersonDeclarations::ACP_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to an accompanying period';
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Closure;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class SumActivityDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
protected EntityRepository $repository;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em
|
||||
) {
|
||||
$this->repository = $em->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// TODO: Implement buildForm() method.
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Sum activity linked to an accompanying period duration';
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Sum activities linked to an accompanying period duration by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_sum_activity_duration' !== $key) {
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
return static fn ($value) => '_header' === $value ? 'Sum activities linked to an accompanying period duration' : $value;
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_sum_activity_duration'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('activity')
|
||||
->join('activity.accompanyingPeriod', 'acp')
|
||||
;
|
||||
|
||||
$qb->select('SUM(activity.durationTime) as export_sum_activity_duration');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(ActivityStatsVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_ACP,
|
||||
//PersonDeclarations::ACP_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to an accompanying period';
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToACP;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Closure;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class SumActivityVisitDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
protected EntityRepository $repository;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em
|
||||
) {
|
||||
$this->repository = $em->getRepository(Activity::class);
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// TODO: Implement buildForm() method.
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Sum activity linked to an accompanying period visit duration';
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Sum activities linked to an accompanying period visit duration by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_sum_activity_visit_duration' !== $key) {
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
return static fn ($value) => '_header' === $value ? 'Sum activities linked to an accompanying period visit duration' : $value;
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_sum_activity_visit_duration'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$qb = $this->repository->createQueryBuilder('activity')
|
||||
->join('activity.accompanyingPeriod', 'acp')
|
||||
;
|
||||
|
||||
$qb->select('SUM(activity.travelTime) as export_sum_activity_visit_duration');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(ActivityStatsVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_ACP,
|
||||
//PersonDeclarations::ACP_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to an accompanying period';
|
||||
}
|
||||
}
|
@@ -9,18 +9,21 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export;
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToPerson;
|
||||
|
||||
use Chill\ActivityBundle\Repository\ActivityRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
|
||||
use Doctrine\ORM\Query;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class CountActivity implements ExportInterface
|
||||
class CountActivity implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
protected ActivityRepository $activityRepository;
|
||||
|
||||
@@ -41,7 +44,7 @@ class CountActivity implements ExportInterface
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return 'Count activities by various parameters.';
|
||||
return 'Count activities linked to a person by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
@@ -50,7 +53,7 @@ class CountActivity implements ExportInterface
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
return static fn ($value) => '_header' === $value ? 'Number of activities' : $value;
|
||||
return static fn ($value) => '_header' === $value ? 'Number of activities linked to a person' : $value;
|
||||
}
|
||||
|
||||
public function getQueryKeys($data)
|
||||
@@ -65,27 +68,28 @@ class CountActivity implements ExportInterface
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Count activities';
|
||||
return 'Count activities linked to a person';
|
||||
}
|
||||
|
||||
public function getType()
|
||||
public function getType(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
$qb = $this
|
||||
->activityRepository
|
||||
->createQueryBuilder('activity')
|
||||
->select('COUNT(activity.id) as export_count_activity')
|
||||
->join('activity.person', 'person');
|
||||
$qb = $this->activityRepository->createQueryBuilder('activity')
|
||||
->join('activity.person', 'person')
|
||||
;
|
||||
|
||||
$qb->select('COUNT(activity.id) as export_count_activity');
|
||||
|
||||
$qb
|
||||
->where($qb->expr()->in('person.center', ':centers'))
|
||||
->setParameter('centers', $centers);
|
||||
->setParameter('centers', $centers)
|
||||
;
|
||||
|
||||
return $qb;
|
||||
}
|
||||
@@ -97,6 +101,15 @@ class CountActivity implements ExportInterface
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return ['person', 'activity'];
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_PERSON,
|
||||
//PersonDeclarations::PERSON_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to a person';
|
||||
}
|
||||
}
|
@@ -9,12 +9,13 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export;
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToPerson;
|
||||
|
||||
use Chill\ActivityBundle\Entity\ActivityReason;
|
||||
use Chill\ActivityBundle\Repository\ActivityRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\MainBundle\Export\ListInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use DateTime;
|
||||
@@ -27,12 +28,14 @@ use Symfony\Component\Security\Core\Role\Role;
|
||||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
|
||||
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function in_array;
|
||||
|
||||
class ListActivity implements ListInterface
|
||||
class ListActivity implements ListInterface, GroupedExportInterface
|
||||
{
|
||||
protected EntityManagerInterface $entityManager;
|
||||
|
||||
@@ -94,7 +97,7 @@ class ListActivity implements ListInterface
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return 'List activities';
|
||||
return 'List activities linked to a person description';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
@@ -180,12 +183,12 @@ class ListActivity implements ListInterface
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'List activities';
|
||||
return 'List activity linked to a person';
|
||||
}
|
||||
|
||||
public function getType()
|
||||
public function getType(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
@@ -274,6 +277,15 @@ class ListActivity implements ListInterface
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return ['activity', 'person'];
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_PERSON,
|
||||
//PersonDeclarations::PERSON_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to a person';
|
||||
}
|
||||
}
|
@@ -9,12 +9,16 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Export;
|
||||
namespace Chill\ActivityBundle\Export\Export\LinkedToPerson;
|
||||
|
||||
use Chill\ActivityBundle\Repository\ActivityRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\PersonBundle\Export\Declarations as PersonDeclarations;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@@ -25,7 +29,7 @@ use Symfony\Component\Security\Core\Role\Role;
|
||||
*
|
||||
* The desired stat must be given in constructor.
|
||||
*/
|
||||
class StatActivityDuration implements ExportInterface
|
||||
class StatActivityDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
public const SUM = 'sum';
|
||||
|
||||
@@ -59,7 +63,7 @@ class StatActivityDuration implements ExportInterface
|
||||
public function getDescription()
|
||||
{
|
||||
if (self::SUM === $this->action) {
|
||||
return 'Sum activities duration by various parameters.';
|
||||
return 'Sum activities linked to a person duration by various parameters.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +73,7 @@ class StatActivityDuration implements ExportInterface
|
||||
throw new LogicException(sprintf('The key %s is not used by this export', $key));
|
||||
}
|
||||
|
||||
$header = self::SUM === $this->action ? 'Sum of activities duration' : false;
|
||||
$header = self::SUM === $this->action ? 'Sum activities linked to a person duration' : false;
|
||||
|
||||
return static fn (string $value) => '_header' === $value ? $header : $value;
|
||||
}
|
||||
@@ -87,19 +91,19 @@ class StatActivityDuration implements ExportInterface
|
||||
public function getTitle()
|
||||
{
|
||||
if (self::SUM === $this->action) {
|
||||
return 'Sum activity duration';
|
||||
return 'Sum activity linked to a person duration';
|
||||
}
|
||||
}
|
||||
|
||||
public function getType()
|
||||
public function getType(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
|
||||
{
|
||||
$centers = array_map(
|
||||
static fn (array $el): string => $el['center'],
|
||||
static fn (array $el): Center => $el['center'],
|
||||
$acl
|
||||
);
|
||||
|
||||
@@ -125,6 +129,15 @@ class StatActivityDuration implements ExportInterface
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return ['person', 'activity'];
|
||||
return [
|
||||
Declarations::ACTIVITY,
|
||||
Declarations::ACTIVITY_PERSON,
|
||||
//PersonDeclarations::PERSON_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of activities linked to a person';
|
||||
}
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialAction;
|
||||
use Chill\PersonBundle\Templating\Entity\SocialActionRender;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class BySocialActionFilter implements FilterInterface
|
||||
{
|
||||
private SocialActionRender $actionRender;
|
||||
|
||||
public function __construct(SocialActionRender $actionRender)
|
||||
{
|
||||
$this->actionRender = $actionRender;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_socialactions', EntityType::class, [
|
||||
'class' => SocialAction::class,
|
||||
'choice_label' => function (SocialAction $sa) {
|
||||
return $this->actionRender->renderString($sa, []);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by linked socialaction';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$actions = [];
|
||||
|
||||
foreach ($data['accepted_socialactions'] as $sa) {
|
||||
$actions[] = $this->actionRender->renderString($sa, []);
|
||||
}
|
||||
|
||||
return ['Filtered activity by linked socialaction: only %actions%', [
|
||||
'%actions%' => implode(", ou ", $actions)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
if (!in_array('socialaction', $qb->getAllAliases())) {
|
||||
$qb->join('activity.socialActions', 'socialaction');
|
||||
}
|
||||
|
||||
$clause = $qb->expr()->in('socialaction.id', ':socialactions');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('socialactions', $data['accepted_socialactions']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Entity\SocialWork\SocialIssue;
|
||||
use Chill\PersonBundle\Templating\Entity\SocialIssueRender;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class BySocialIssueFilter implements FilterInterface
|
||||
{
|
||||
private SocialIssueRender $issueRender;
|
||||
|
||||
public function __construct(SocialIssueRender $issueRender)
|
||||
{
|
||||
$this->issueRender = $issueRender;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_socialissues', EntityType::class, [
|
||||
'class' => SocialIssue::class,
|
||||
'choice_label' => function(SocialIssue $si) {
|
||||
return $this->issueRender->renderString($si, []);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by linked socialissue';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$issues = [];
|
||||
|
||||
foreach ($data['accepted_socialissues'] as $si) {
|
||||
$issues[] = $this->issueRender->renderString($si, []);
|
||||
}
|
||||
|
||||
return ['Filtered activity by linked socialissue: only %issues%', [
|
||||
'%issues%' => implode(", ou ", $issues)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
if (!in_array('socialissue', $qb->getAllAliases())) {
|
||||
$qb->join('activity.socialIssues', 'socialissue');
|
||||
}
|
||||
|
||||
$clause = $qb->expr()->in('socialissue.id', ':socialissues');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('socialissues', $data['accepted_socialissues']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class ByUserFilter implements FilterInterface
|
||||
{
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(UserRender $userRender)
|
||||
{
|
||||
$this->userRender = $userRender;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_users', EntityType::class, [
|
||||
'class' => User::class,
|
||||
'choice_label' => function (User $u) {
|
||||
return $this->userRender->renderString($u, []);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by linked users';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$users = [];
|
||||
|
||||
foreach ($data['accepted_users'] as $u) {
|
||||
$users[] = $this->userRender->renderString($u, []);
|
||||
}
|
||||
|
||||
return ['Filtered activity by linked users: only %users%', [
|
||||
'%users%' => implode(", ou ", $users)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
if (!in_array('user', $qb->getAllAliases())) {
|
||||
$qb->join('activity.users', 'user');
|
||||
}
|
||||
|
||||
$clause = $qb->expr()->in('user.id', ':users');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('users', $data['accepted_users']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class EmergencyFilter implements FilterInterface
|
||||
{
|
||||
private const CHOICES = [
|
||||
'activity is emergency' => true,
|
||||
'activity is not emergency' => false,
|
||||
];
|
||||
|
||||
private CONST DEFAULT_CHOICE = false;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_emergency', ChoiceType::class, [
|
||||
'choices' => self::CHOICES,
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'empty_data' => self::DEFAULT_CHOICE,
|
||||
'data' => self::DEFAULT_CHOICE,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by emergency';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
foreach (self::CHOICES as $k => $v) {
|
||||
if ($v === $data['accepted_emergency']) {
|
||||
$choice = $k;
|
||||
}
|
||||
}
|
||||
|
||||
return ['Filtered activity by emergency: only %emergency%', [
|
||||
'%emergency%' => $this->translator->trans($choice)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->eq('activity.emergency', ':emergency');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('emergency', $data['accepted_emergency']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\LocationType;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class LocationTypeFilter implements FilterInterface
|
||||
{
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
||||
{
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_locationtype', EntityType::class, [
|
||||
'class' => LocationType::class,
|
||||
'choice_label' => function(LocationType $type) {
|
||||
return $this->translatableStringHelper->localize($type->getTitle());
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by locationtype';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$types = [];
|
||||
|
||||
foreach ($data['accepted_locationtype'] as $type) {
|
||||
$types[] = $this->translatableStringHelper->localize(
|
||||
$type->getTitle()
|
||||
);
|
||||
}
|
||||
|
||||
return ['Filtered activity by locationtype: only %types%', [
|
||||
'%types%' => implode(", ou ", $types)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('location', $qb->getAllAliases())) {
|
||||
$qb->join('activity.location', 'location');
|
||||
}
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('location.locationType', ':locationtype');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('locationtype', $data['accepted_locationtype']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\ActivityBundle\Entity\Activity;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class SentReceivedFilter implements FilterInterface
|
||||
{
|
||||
private const CHOICES = [
|
||||
'is sent' => Activity::SENTRECEIVED_SENT,
|
||||
'is received' => Activity::SENTRECEIVED_RECEIVED,
|
||||
];
|
||||
|
||||
private CONST DEFAULT_CHOICE = Activity::SENTRECEIVED_SENT;
|
||||
|
||||
private TranslatorInterface $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_sentreceived', ChoiceType::class, [
|
||||
'choices' => self::CHOICES,
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'empty_data' => self::DEFAULT_CHOICE,
|
||||
'data' => self::DEFAULT_CHOICE,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by sentreceived';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$sentreceived = array_flip(self::CHOICES)[$data['accepted_sentreceived']];
|
||||
|
||||
return ['Filtered activity by sentreceived: only %sentreceived%', [
|
||||
'%sentreceived%' => $this->translator->trans($sentreceived)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->eq('activity.sentReceived', ':sentreceived');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('sentreceived', $data['accepted_sentreceived']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserFilter implements FilterInterface
|
||||
{
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(UserRender $userRender)
|
||||
{
|
||||
$this->userRender = $userRender;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_users', EntityType::class, [
|
||||
'class' => User::class,
|
||||
'choice_label' => function (User $u) {
|
||||
return $this->userRender->renderString($u, []);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'label' => 'Creators'
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by user';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$users = [];
|
||||
|
||||
foreach ($data['accepted_users'] as $u) {
|
||||
$users[] = $this->userRender->renderString($u, []);
|
||||
}
|
||||
|
||||
return ['Filtered activity by user: only %users%', [
|
||||
'%users%' => implode(", ou ", $users)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->in('activity.user', ':users');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('users', $data['accepted_users']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter\ACPFilters;
|
||||
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class UserScopeFilter implements FilterInterface
|
||||
{
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $translatableStringHelper)
|
||||
{
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_userscope', EntityType::class, [
|
||||
'class' => Scope::class,
|
||||
'choice_label' => function (Scope $s) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter activity by userscope';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$scopes = [];
|
||||
|
||||
foreach ($data['accepted_userscope'] as $s) {
|
||||
$scopes[] = $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
);
|
||||
}
|
||||
|
||||
return ['Filtered activity by userscope: only %scopes%', [
|
||||
'%scopes%' => implode(", ou ", $scopes)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
if (!in_array('user', $qb->getAllAliases())) {
|
||||
$qb->join('activity.user', 'user');
|
||||
}
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->in('user.mainScope', ':userscope');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('userscope', $data['accepted_userscope']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::ACTIVITY_ACP;
|
||||
}
|
||||
|
||||
}
|
@@ -11,12 +11,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter;
|
||||
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Chill\MainBundle\Form\Type\Export\FilterType;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\Query\Expr;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
@@ -57,36 +58,23 @@ class ActivityDateFilter implements FilterInterface
|
||||
$qb->setParameter('date_to', $data['date_to']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
public function applyOn(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add(
|
||||
'date_from',
|
||||
DateType::class,
|
||||
[
|
||||
$builder
|
||||
->add('date_from', ChillDateType::class, [
|
||||
'label' => 'Activities after this date',
|
||||
'data' => new DateTime(),
|
||||
'attr' => ['class' => 'datepicker'],
|
||||
'widget' => 'single_text',
|
||||
'format' => 'dd-MM-yyyy',
|
||||
]
|
||||
);
|
||||
|
||||
$builder->add(
|
||||
'date_to',
|
||||
DateType::class,
|
||||
[
|
||||
])
|
||||
->add('date_to', ChillDateType::class, [
|
||||
'label' => 'Activities before this date',
|
||||
'data' => new DateTime(),
|
||||
'attr' => ['class' => 'datepicker'],
|
||||
'widget' => 'single_text',
|
||||
'format' => 'dd-MM-yyyy',
|
||||
]
|
||||
);
|
||||
])
|
||||
;
|
||||
|
||||
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
|
||||
/** @var \Symfony\Component\Form\FormInterface $filterForm */
|
||||
|
@@ -12,6 +12,7 @@ declare(strict_types=1);
|
||||
namespace Chill\ActivityBundle\Export\Filter;
|
||||
|
||||
use Chill\ActivityBundle\Entity\ActivityType;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Repository\ActivityTypeRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||
@@ -49,7 +50,7 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('activity.type', ':selected_activity_types');
|
||||
$clause = $qb->expr()->in('activity.activityType', ':selected_activity_types');
|
||||
|
||||
if ($where instanceof Expr\Andx) {
|
||||
$where->add($clause);
|
||||
@@ -61,39 +62,33 @@ class ActivityTypeFilter implements ExportElementValidatedInterface, FilterInter
|
||||
$qb->setParameter('selected_activity_types', $data['types']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
public function applyOn(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add(
|
||||
'types',
|
||||
EntityType::class,
|
||||
[
|
||||
'class' => ActivityType::class,
|
||||
'choice_label' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
]
|
||||
);
|
||||
$builder->add('types', EntityType::class, [
|
||||
'class' => ActivityType::class,
|
||||
'choice_label' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getName()),
|
||||
'group_by' => fn (ActivityType $type) => $this->translatableStringHelper->localize($type->getCategory()->getName()),
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
// collect all the reasons'name used in this filter in one array
|
||||
$reasonsNames = array_map(
|
||||
fn (ActivityType $t): string => '"' . $this->translatableStringHelper->localize($t->getName()) . '"',
|
||||
fn (ActivityType $t): string => $this->translatableStringHelper->localize($t->getName()),
|
||||
$this->activityTypeRepository->findBy(['id' => $data['types']->toArray()])
|
||||
);
|
||||
|
||||
return [
|
||||
'Filtered by activity type: only %list%',
|
||||
[
|
||||
'%list%' => implode(', ', $reasonsNames),
|
||||
],
|
||||
];
|
||||
return ['Filtered by activity type: only %list%', [
|
||||
'%list%' => implode(', ou ', $reasonsNames),
|
||||
]];
|
||||
}
|
||||
|
||||
public function getTitle()
|
||||
|
@@ -9,9 +9,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter;
|
||||
namespace Chill\ActivityBundle\Export\Filter\PersonFilters;
|
||||
|
||||
use Chill\ActivityBundle\Entity\ActivityReason;
|
||||
use Chill\ActivityBundle\Export\Declarations;
|
||||
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
|
||||
use Chill\ActivityBundle\Security\Authorization\ActivityStatsVoter;
|
||||
use Chill\MainBundle\Export\ExportElementValidatedInterface;
|
||||
@@ -79,9 +80,9 @@ class ActivityReasonFilter implements ExportElementValidatedInterface, FilterInt
|
||||
$qb->setParameter('selected_activity_reasons', $data['reasons']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
public function applyOn(): string
|
||||
{
|
||||
return 'activity';
|
||||
return Declarations::ACTIVITY_PERSON;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
@@ -9,7 +9,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\ActivityBundle\Export\Filter;
|
||||
namespace Chill\ActivityBundle\Export\Filter\PersonFilters;
|
||||
|
||||
use Chill\ActivityBundle\Entity\ActivityReason;
|
||||
use Chill\ActivityBundle\Repository\ActivityReasonRepository;
|
||||
@@ -102,7 +102,7 @@ class PersonHavingActivityBetweenDateFilter implements ExportElementValidatedInt
|
||||
$qb->setParameter('person_having_activity_reasons', $data['reasons']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::PERSON_IMPLIED_IN;
|
||||
}
|
@@ -3,26 +3,48 @@ services:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
||||
chill.activity.export.count_activity:
|
||||
class: Chill\ActivityBundle\Export\Export\CountActivity
|
||||
## Indicators
|
||||
chill.activity.export.count_activity_linked_to_person:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\CountActivity
|
||||
tags:
|
||||
- { name: chill.export, alias: 'count_activity' }
|
||||
- { name: chill.export, alias: 'count_activity_linked_to_person' }
|
||||
|
||||
chill.activity.export.sum_activity_duration:
|
||||
class: Chill\ActivityBundle\Export\Export\StatActivityDuration
|
||||
chill.activity.export.sum_activity_duration_linked_to_person:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\StatActivityDuration
|
||||
tags:
|
||||
- { name: chill.export, alias: 'sum_activity_duration' }
|
||||
- { name: chill.export, alias: 'sum_activity_duration_linked_to_person' }
|
||||
|
||||
chill.activity.export.list_activity:
|
||||
class: Chill\ActivityBundle\Export\Export\ListActivity
|
||||
chill.activity.export.list_activity_linked_to_person:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToPerson\ListActivity
|
||||
tags:
|
||||
- { name: chill.export, alias: 'list_activity' }
|
||||
- { name: chill.export, alias: 'list_activity_linked_to_person' }
|
||||
|
||||
chill.activity.export.reason_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ActivityReasonFilter
|
||||
chill.activity.export.count_activity_linked_to_acp:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToACP\CountActivity
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_reason_filter' }
|
||||
- { name: chill.export, alias: 'count_activity_linked_to_acp' }
|
||||
|
||||
chill.activity.export.sum_activity_duration_linked_to_acp:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToACP\SumActivityDuration
|
||||
tags:
|
||||
- { name: chill.export, alias: 'sum_activity_duration_linked_to_acp' }
|
||||
|
||||
chill.activity.export.sum_activity_visit_duration_linked_to_acp:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToACP\SumActivityVisitDuration
|
||||
tags:
|
||||
- { name: chill.export, alias: 'sum_activity_visit_duration_linked_to_acp' }
|
||||
|
||||
chill.activity.export.avg_activity_duration_linked_to_acp:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToACP\AvgActivityDuration
|
||||
tags:
|
||||
- { name: chill.export, alias: 'avg_activity_duration_linked_to_acp' }
|
||||
|
||||
chill.activity.export.avg_activity_visit_duration_linked_to_acp:
|
||||
class: Chill\ActivityBundle\Export\Export\LinkedToACP\AvgActivityVisitDuration
|
||||
tags:
|
||||
- { name: chill.export, alias: 'avg_activity_visit_duration_linked_to_acp' }
|
||||
|
||||
## Filters
|
||||
chill.activity.export.type_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ActivityTypeFilter
|
||||
tags:
|
||||
@@ -33,15 +55,61 @@ services:
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_date_filter' }
|
||||
|
||||
chill.activity.export.reason_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\PersonFilters\ActivityReasonFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_reason_filter' }
|
||||
|
||||
chill.activity.export.person_having_an_activity_between_date_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\PersonHavingActivityBetweenDateFilter
|
||||
class: Chill\ActivityBundle\Export\Filter\PersonFilters\PersonHavingActivityBetweenDateFilter
|
||||
tags:
|
||||
- #0 register as a filter
|
||||
name: chill.export_filter
|
||||
alias: 'activity_person_having_ac_bw_date_filter'
|
||||
|
||||
chill.activity.export.locationtype_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\LocationTypeFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_locationtype_filter' }
|
||||
|
||||
chill.activity.export.byuser_filter: # TMS (M2M)
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\ByUserFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_byuser_filter' }
|
||||
|
||||
chill.activity.export.emergency_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\EmergencyFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_emergency_filter' }
|
||||
|
||||
chill.activity.export.sentreceived_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\SentReceivedFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_sentreceived_filter' }
|
||||
|
||||
chill.activity.export.bysocialaction_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\BySocialActionFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_bysocialaction_filter' }
|
||||
|
||||
chill.activity.export.bysocialissue_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\BySocialIssueFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_bysocialissue_filter' }
|
||||
|
||||
chill.activity.export.user_filter: # Creator (M2O)
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\UserFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_user_filter' }
|
||||
|
||||
chill.activity.export.userscope_filter:
|
||||
class: Chill\ActivityBundle\Export\Filter\ACPFilters\UserScopeFilter
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: 'activity_userscope_filter' }
|
||||
|
||||
## Aggregators
|
||||
chill.activity.export.reason_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ActivityReasonAggregator
|
||||
class: Chill\ActivityBundle\Export\Aggregator\PersonAggregators\ActivityReasonAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_reason_aggregator }
|
||||
|
||||
@@ -54,3 +122,38 @@ services:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ActivityUserAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_user_aggregator }
|
||||
|
||||
chill.activity.export.locationtype_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\LocationTypeAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_locationtype_aggregator }
|
||||
|
||||
chill.activity.export.date_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\DateAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_date_aggregator }
|
||||
|
||||
chill.activity.export.byuser_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByUserAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_byuser_aggregator }
|
||||
|
||||
chill.activity.export.bythirdparty_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\ByThirdpartyAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_bythirdparty_aggregator }
|
||||
|
||||
chill.activity.export.bysocialaction_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialActionAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_bysocialaction_aggregator }
|
||||
|
||||
chill.activity.export.bysocialissue_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\BySocialIssueAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_bysocialissue_aggregator }
|
||||
|
||||
chill.activity.export.userscope_aggregator:
|
||||
class: Chill\ActivityBundle\Export\Aggregator\ACPAggregators\UserScopeAggregator
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: activity_userscope_aggregator }
|
||||
|
@@ -203,18 +203,39 @@ Are you sure you want to remove the activity about "%name%" ?: Êtes-vous sûr d
|
||||
The activity has been successfully removed.: L'activité a été supprimée.
|
||||
|
||||
# exports
|
||||
Count activities: Nombre d'activités
|
||||
Count activities by various parameters.: Compte le nombre d'activités enregistrées en fonction de différents paramètres.
|
||||
Sum activity duration: Total de la durée des activités
|
||||
Sum activities duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres.
|
||||
List activities: Liste les activités
|
||||
Number of activities: Nombre d'activités
|
||||
Exports of activities linked to a person: Exports des activités liées à une personne
|
||||
Number of activities linked to a person: Nombre d'activités liées à une personne
|
||||
Count activities linked to a person: Nombre d'activités
|
||||
Count activities linked to a person by various parameters.: Compte le nombre d'activités enregistrées et liées à une personne en fonction de différents paramètres.
|
||||
Sum activity linked to a person duration: Durée des activités
|
||||
Sum activities linked to a person duration: Durée des activités liés à un usager
|
||||
Sum activities linked to a person duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres.
|
||||
List activity linked to a person: Liste les activités
|
||||
List activities linked to a person: Liste des activités liés à un usager
|
||||
List activities linked to a person description: Crée la liste des activités en fonction de différents paramètres.
|
||||
|
||||
Exports of activities linked to an accompanying period: Exports des activités liées à un parcours
|
||||
Number of activities linked to an accompanying period: Nombre d'activités liées à un parcours
|
||||
Count activities linked to an accompanying period: Nombre d'activités
|
||||
Count activities linked to an accompanying period by various parameters.: Compte le nombre d'activités enregistrées et liées à un parcours en fonction de différents paramètres.
|
||||
Sum activity linked to an accompanying period duration: Somme de la durée des activités
|
||||
Sum activities linked to an accompanying period duration: Somme de la durée des activités liées à un parcours
|
||||
Sum activities linked to an accompanying period duration by various parameters.: Additionne la durée des activités en fonction de différents paramètres.
|
||||
Sum activity linked to an accompanying period visit duration: Somme de la durée de déplacement des activités
|
||||
Sum activities linked to an accompanying period visit duration: Somme de la durée de déplacement des activités liées à un parcours
|
||||
Sum activities linked to an accompanying period visit duration by various parameters.: Additionne la durée de déplacement des activités en fonction de différents paramètres.
|
||||
Average activity linked to an accompanying period duration: Moyenne de la durée des activités
|
||||
Average activities linked to an accompanying period duration: Moyenne de la durée des activités liées à un parcours
|
||||
Average activities linked to an accompanying period duration by various parameters.: Moyenne de la durée des activités en fonction de différents paramètres.
|
||||
Average activity linked to an accompanying period visit duration: Moyenne de la durée de déplacement des activités
|
||||
Average activities linked to an accompanying period visit duration: Moyenne de la durée de déplacement des activités liées à un parcours
|
||||
Average activities linked to an accompanying period visit duration by various parameters.: Moyenne de la durée de déplacement des activités en fonction de différents paramètres.
|
||||
|
||||
#filters
|
||||
Filter by reason: Filtrer par sujet d'activité
|
||||
Filter by reason: Filtrer les activités par sujet
|
||||
'Filtered by reasons: only %list%': 'Filtré par sujet: seulement %list%'
|
||||
'Filtered by activity type: only %list%': "Filtré par type d'activity: seulement %list%"
|
||||
Filtered by date activity: Filtrer par date d'activité
|
||||
'Filtered by activity type: only %list%': "Filtré par type d'activité: uniquement %list%"
|
||||
Filtered by date activity: Filtrer les activités par date
|
||||
Activities after this date: Activités après cette date
|
||||
Activities before this date: Activités avant cette date
|
||||
"Filtered by date of activity: only between %date_from% and %date_to%": "Filtré par date de l'activité: uniquement entre %date_from% et %date_to%"
|
||||
@@ -226,18 +247,59 @@ Implied in an activity before this date: Impliqué dans une activité avant cett
|
||||
Filtered by person having an activity between %date_from% and %date_to% with reasons %reasons_name%: Filtré par personnes associées à une activité entre %date_from% et %date_to% avec les sujets %reasons_name%
|
||||
Activity reasons for those activities: Sujets de ces activités
|
||||
|
||||
Filter by activity type: Filtrer par type d'activité
|
||||
Filter by activity type: Filtrer les activités par type
|
||||
|
||||
Filter activity by locationtype: Filtrer les activités par type de localisation
|
||||
'Filtered activity by locationtype: only %types%': "Filtré par type de localisation: uniquement %types%"
|
||||
Accepted locationtype: Types de localisation
|
||||
Filter activity by linked users: Filtrer les activités par TMS
|
||||
'Filtered activity by linked users: only %users%': "Filtré par TMS: uniquement %users%"
|
||||
Accepted users: TMS(s)
|
||||
Filter activity by emergency: Filtrer les activités par urgence
|
||||
'Filtered activity by emergency: only %emergency%': "Filtré par urgence: uniquement si %emergency%"
|
||||
activity is emergency: l'activité est urgente
|
||||
activity is not emergency: l'activité n'est pas urgente
|
||||
Filter activity by sentreceived: Filtrer les activités par envoyé/reçu
|
||||
'Filtered activity by sentreceived: only %sentreceived%': "Filtré par envoyé/reçu: uniquement %sentreceived%"
|
||||
Accepted sentreceived: ''
|
||||
is sent: envoyé
|
||||
is received: reçu
|
||||
Filter activity by linked socialaction: Filtrer les activités par action liée
|
||||
'Filtered activity by linked socialaction: only %actions%': "Filtré par action liée: uniquement %actions%"
|
||||
Filter activity by linked socialissue: Filtrer les activités par problématique liée
|
||||
'Filtered activity by linked socialissue: only %issues%': "Filtré par problématique liée: uniquement %issues%"
|
||||
Filter activity by user: Filtrer les activités par créateur
|
||||
'Filtered activity by user: only %users%': "Filtré par créateur: uniquement %users%"
|
||||
Creators: Créateurs
|
||||
Filter activity by userscope: Filtrer les activités par service du créateur
|
||||
'Filtered activity by userscope: only %scopes%': "Filtré par service du créateur: uniquement %scopes%"
|
||||
Accepted userscope: Services
|
||||
|
||||
#aggregators
|
||||
Activity type: Type d'activité
|
||||
Activity user: Utilisateur lié à l'activity
|
||||
Activity user: Utilisateur lié à l'activité
|
||||
By reason: Par sujet
|
||||
By category of reason: Par catégorie de sujet
|
||||
Reason's level: Niveau du sujet
|
||||
Group by reasons: Sujet d'activité
|
||||
Aggregate by activity user: Aggréger par utilisateur lié à l'activité
|
||||
Aggregate by activity type: Aggréger par type d'activité
|
||||
Aggregate by activity reason: Aggréger par sujet de l'activité
|
||||
Aggregate by activity user: Grouper les activités par utilisateur
|
||||
Aggregate by activity type: Grouper les activités par type
|
||||
Aggregate by activity reason: Grouper les activités par sujet
|
||||
|
||||
Group activity by locationtype: Grouper les activités par type de localisation
|
||||
Group activity by date: Grouper les activités par date
|
||||
Frequency: Fréquence
|
||||
by month: Par mois
|
||||
by week: Par semaine
|
||||
for week: Semaine
|
||||
by year: Par année
|
||||
in year: En
|
||||
Group activity by linked users: Grouper les activités par TMS impliqué
|
||||
Group activity by linked thirdparties: Grouper les activités par tiers impliqué
|
||||
Accepted thirdparty: Tiers impliqué
|
||||
Group activity by linked socialaction: Grouper les activités par action liée
|
||||
Group activity by linked socialissue: Grouper les activités par problématique liée
|
||||
Group activity by userscope: Grouper les activités par service du créateur
|
||||
|
||||
Last activities: Les dernières activités
|
||||
|
||||
|
@@ -195,7 +195,7 @@ Number of activities: Nombre d'activités
|
||||
#filters
|
||||
Filter by reason: Filtrer par sujet d'activité
|
||||
'Filtered by reasons: only %list%': 'Filtré par sujet: seulement %list%'
|
||||
'Filtered by activity type: only %list%': "Filtré par type d'activity: seulement %list%"
|
||||
'Filtered by activity type: only %list%': "Filtré par type d'activity: uniquement %list%"
|
||||
Filtered by date activity: Filtrer par date d'activité
|
||||
Activities after this date: Activités après cette date
|
||||
Activities before this date: Activités avant cette date
|
||||
@@ -217,9 +217,9 @@ By reason: Par sujet
|
||||
By category of reason: Par catégorie de sujet
|
||||
Reason's level: Niveau du sujet
|
||||
Group by reasons: Sujet d'activité
|
||||
Aggregate by activity user: Aggréger par utilisateur lié à l'activité
|
||||
Aggregate by activity type: Aggréger par type d'activité
|
||||
Aggregate by activity reason: Aggréger par sujet de l'activité
|
||||
Aggregate by activity user: Grouper par utilisateur lié à l'activité
|
||||
Aggregate by activity type: Grouper par type d'activité
|
||||
Aggregate by activity reason: Grouper par sujet de l'activité
|
||||
|
||||
Last activities: Les dernières activités
|
||||
|
||||
|
@@ -32,6 +32,7 @@ class ChillCalendarExtension extends Extension implements PrependExtensionInterf
|
||||
|
||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
|
||||
$loader->load('services.yml');
|
||||
$loader->load('services/exports.yaml');
|
||||
$loader->load('services/controller.yml');
|
||||
$loader->load('services/fixtures.yml');
|
||||
$loader->load('services/form.yml');
|
||||
|
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\UserRepository;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final class AgentAggregator implements AggregatorInterface
|
||||
{
|
||||
private UserRepository $userRepository;
|
||||
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(
|
||||
UserRepository $userRepository,
|
||||
UserRender $userRender
|
||||
) {
|
||||
$this->userRepository = $userRepository;
|
||||
$this->userRender = $userRender;
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.user', 'u');
|
||||
|
||||
$qb->addSelect('u.id AS agent_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('agent_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('agent_aggregator');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
return function ($value): string {
|
||||
if ('_header' === $value) {
|
||||
return 'Agent';
|
||||
}
|
||||
|
||||
$r = $this->userRepository->find($value);
|
||||
|
||||
return $this->userRender->renderString($r, []);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['agent_aggregator'];
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by agent';
|
||||
}
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\CalendarBundle\Repository\CancelReasonRepository;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class CancelReasonAggregator implements AggregatorInterface
|
||||
{
|
||||
private CancelReasonRepository $cancelReasonRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
CancelReasonRepository $cancelReasonRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->cancelReasonRepository = $cancelReasonRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
return function($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Cancel reason';
|
||||
}
|
||||
|
||||
$j = $this->cancelReasonRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize(
|
||||
$j->getName()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['cancel_reason_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by cancel reason';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
// TODO: still needs to take into account appointments without a cancel reason somehow
|
||||
$qb->join('cal.cancelReason', 'cr');
|
||||
|
||||
$qb->addSelect('IDENTITY(cal.cancelReason) as cancel_reason_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('cancel_reason_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('cancel_reason_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\UserJobRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final class JobAggregator implements AggregatorInterface
|
||||
{
|
||||
private UserJobRepository $jobRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
UserJobRepository $jobRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->jobRepository = $jobRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
return function($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Job';
|
||||
}
|
||||
|
||||
$j = $this->jobRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize(
|
||||
$j->getLabel()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['job_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by agent job';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.user', 'u');
|
||||
|
||||
$qb->addSelect('IDENTITY(u.userJob) as job_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('job_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('job_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\LocationRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
final class LocationAggregator implements AggregatorInterface
|
||||
{
|
||||
private LocationRepository $locationRepository;
|
||||
|
||||
public function __construct(
|
||||
LocationRepository $locationRepository
|
||||
) {
|
||||
$this->locationRepository = $locationRepository;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
return function($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Location';
|
||||
}
|
||||
|
||||
$l = $this->locationRepository->find($value);
|
||||
|
||||
return $l->getName();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['location_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by location';
|
||||
}
|
||||
|
||||
public function addRole(): ?Role
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.location', 'l');
|
||||
$qb->addSelect('IDENTITY(cal.location) as location_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('location_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('location_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\LocationTypeRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final class LocationTypeAggregator implements AggregatorInterface
|
||||
{
|
||||
private LocationTypeRepository $locationTypeRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
LocationTypeRepository $locationTypeRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->locationTypeRepository = $locationTypeRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
return function($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Location type';
|
||||
}
|
||||
|
||||
$j = $this->locationTypeRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize(
|
||||
$j->getTitle()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['location_type_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by location type';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.location', 'l');
|
||||
|
||||
$qb->addSelect('IDENTITY(l.locationType) as location_type_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('location_type_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('location_type_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Closure;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class MonthYearAggregator implements AggregatorInterface
|
||||
{
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['month_year_aggregator'];
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): Closure
|
||||
{
|
||||
return function($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'by month and year';
|
||||
}
|
||||
|
||||
$month = substr($value,0, 2);
|
||||
$year = substr($value, 3, 4);
|
||||
|
||||
return strftime('%B %G', mktime(0, 0, 0, $month, '1', $year));
|
||||
};
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// No form needed
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by month and year';
|
||||
}
|
||||
|
||||
public function addRole(): ?Role
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->addSelect("to_char(cal.startDate, 'MM-YYYY') AS month_year_aggregator");
|
||||
// $qb->addSelect("extract(month from age(cal.startDate, cal.endDate)) AS month_aggregator");
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('month_year_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('month_year_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Aggregator;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\AggregatorInterface;
|
||||
use Chill\MainBundle\Repository\ScopeRepository;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
final class ScopeAggregator implements AggregatorInterface
|
||||
{
|
||||
private ScopeRepository $scopeRepository;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
ScopeRepository $scopeRepository,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->scopeRepository = $scopeRepository;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
return function ($value): string {
|
||||
if ($value === '_header') {
|
||||
return 'Scope';
|
||||
}
|
||||
|
||||
$s = $this->scopeRepository->find($value);
|
||||
|
||||
return $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['scope_aggregator'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// no form
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Group by agent scope';
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.user', 'u');
|
||||
|
||||
$qb->addSelect('IDENTITY(u.mainScope) as scope_aggregator');
|
||||
|
||||
$groupBy = $qb->getDQLPart('groupBy');
|
||||
|
||||
if (!empty($groupBy)) {
|
||||
$qb->addGroupBy('scope_aggregator');
|
||||
} else {
|
||||
$qb->groupBy('scope_aggregator');
|
||||
}
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
}
|
20
src/Bundle/ChillCalendarBundle/Export/Declarations.php
Normal file
20
src/Bundle/ChillCalendarBundle/Export/Declarations.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Export;
|
||||
|
||||
/**
|
||||
* This class declare constants used for the export framework.
|
||||
*/
|
||||
abstract class Declarations
|
||||
{
|
||||
public const CALENDAR_TYPE = 'calendar';
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Export;
|
||||
|
||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\PersonBundle\Security\Authorization\PersonVoter;
|
||||
use Doctrine\ORM\AbstractQuery;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Process\Exception\LogicException;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class CountAppointments implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
|
||||
private CalendarRepository $calendarRepository;
|
||||
|
||||
public function __construct(CalendarRepository $calendarRepository)
|
||||
{
|
||||
$this->calendarRepository = $calendarRepository;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
// No form necessary
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Count appointments by various parameters.';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data): \Closure
|
||||
{
|
||||
if ('export_result' !== $key) {
|
||||
throw new LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(AbstractQuery::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Count appointments';
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate the query.
|
||||
*/
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
|
||||
{
|
||||
$centers = array_map(static function ($el) {
|
||||
return $el['center'];
|
||||
}, $acl);
|
||||
|
||||
$qb = $this->calendarRepository->createQueryBuilder('cal');
|
||||
|
||||
$qb->select('COUNT(cal.id) AS export_result');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
|
||||
// which role should we give here?
|
||||
return new Role(PersonVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::CALENDAR_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of calendar';
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Export;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class StatAppointmentAvgDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
|
||||
private CalendarRepository $calendarRepository;
|
||||
|
||||
public function __construct(
|
||||
CalendarRepository $calendarRepository
|
||||
) {
|
||||
$this->calendarRepository = $calendarRepository;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
// no form needed
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Average appointment duration';
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Get the average of appointment duration according to various filters';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_result' !== $key) {
|
||||
throw new \LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
|
||||
{
|
||||
$qb = $this->calendarRepository->createQueryBuilder('cal');
|
||||
|
||||
$qb
|
||||
->select('AVG(cal.endDate - cal.startDate) AS export_result');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(AccompanyingPeriodVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::CALENDAR_TYPE
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of calendar';
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Export;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||
use Chill\MainBundle\Export\ExportInterface;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Security\Core\Role\Role;
|
||||
|
||||
class StatAppointmentSumDuration implements ExportInterface, GroupedExportInterface
|
||||
{
|
||||
private CalendarRepository $calendarRepository;
|
||||
|
||||
public function __construct(
|
||||
CalendarRepository $calendarRepository
|
||||
) {
|
||||
$this->calendarRepository = $calendarRepository;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
// no form needed
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Sum of appointment durations';
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_TABULAR];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Get the sum of appointment durations according to various filters';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
if ('export_result' !== $key) {
|
||||
throw new \LogicException("the key {$key} is not used by this export");
|
||||
}
|
||||
|
||||
$labels = array_combine($values, $values);
|
||||
$labels['_header'] = $this->getTitle();
|
||||
|
||||
return static function ($value) use ($labels) {
|
||||
return $labels[$value];
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys($data): array
|
||||
{
|
||||
return ['export_result'];
|
||||
}
|
||||
|
||||
public function getResult($qb, $data)
|
||||
{
|
||||
return $qb->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []): QueryBuilder
|
||||
{
|
||||
$qb = $this->calendarRepository->createQueryBuilder('cal');
|
||||
|
||||
$qb
|
||||
->select('SUM(cal.endDate - cal.startDate) AS export_result');
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): Role
|
||||
{
|
||||
return new Role(AccompanyingPeriodVoter::STATS);
|
||||
}
|
||||
|
||||
public function supportsModifiers(): array
|
||||
{
|
||||
return [
|
||||
Declarations::CALENDAR_TYPE
|
||||
];
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of calendar';
|
||||
}
|
||||
|
||||
}
|
79
src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php
Normal file
79
src/Bundle/ChillCalendarBundle/Export/Filter/AgentFilter.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Filter;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Templating\Entity\UserRender;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class AgentFilter implements FilterInterface
|
||||
{
|
||||
private UserRender $userRender;
|
||||
|
||||
public function __construct(UserRender $userRender)
|
||||
{
|
||||
$this->userRender = $userRender;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('accepted_agents', EntityType::class, [
|
||||
'class' => User::class,
|
||||
'choice_label' => function (User $u) {
|
||||
return $this->userRender->renderString($u, []);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter by agent';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$users = [];
|
||||
|
||||
foreach ($data['accepted_agents'] as $r) {
|
||||
$users[] = $r;
|
||||
}
|
||||
|
||||
return [
|
||||
'Filtered by agent: only %agents%', [
|
||||
'%agents' => implode(", ou ", $users)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('cal.user', ':agents');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('agents', $data['accepted_agents']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Filter;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Form\Type\ChillDateType;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class BetweenDatesFilter implements FilterInterface
|
||||
{
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder
|
||||
->add('date_from', ChillDateType::class, [
|
||||
'data' => new \DateTime(),
|
||||
])
|
||||
->add('date_to', ChillDateType::class, [
|
||||
'data' => new \DateTime(),
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter by appointments between certain dates';
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
return ['Filtered by appointments between %dateFrom% and %dateTo%', [
|
||||
'%dateFrom%' => $data['date_from']->format('d-m-Y'),
|
||||
'%dateTo%' => $data['date_to']->format('d-m-Y'),
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$where = $qb->getDQLPart('where');
|
||||
|
||||
$clause = $qb->expr()->andX(
|
||||
$qb->expr()->gte('cal.startDate', ':dateFrom'),
|
||||
$qb->expr()->lte('cal.endDate', ':dateTo')
|
||||
);
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('dateFrom', $data['date_from']);
|
||||
// modify dateTo so that entire day is also taken into account up until the beginning of the next day.
|
||||
$qb->setParameter('dateTo', $data['date_to']->modify('+1 day'));
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
}
|
99
src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php
Normal file
99
src/Bundle/ChillCalendarBundle/Export/Filter/JobFilter.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Filter;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Entity\UserJob;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class JobFilter implements FilterInterface
|
||||
{
|
||||
|
||||
protected TranslatorInterface $translator;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
TranslatorInterface $translator,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->translator = $translator;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('job', EntityType::class, [
|
||||
'class' => UserJob::class,
|
||||
'choice_label' => function (UserJob $j) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$j->getLabel()
|
||||
);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string'): array
|
||||
{
|
||||
$userJobs = [];
|
||||
|
||||
foreach ($data['job'] as $j) {
|
||||
$userJobs[] = $this->translatableStringHelper->localize(
|
||||
$j->getLabel());
|
||||
}
|
||||
|
||||
return ['Filtered by agent job: only %jobs%', [
|
||||
'%jobs%' => implode(', ou ', $userJobs)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.user', 'u');
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('u.userJob', ':job');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('job', $data['job']);
|
||||
}
|
||||
|
||||
public function applyOn(): string
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return 'Filter by agent job';
|
||||
}
|
||||
}
|
99
src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php
Normal file
99
src/Bundle/ChillCalendarBundle/Export/Filter/ScopeFilter.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\CalendarBundle\Export\Filter;
|
||||
|
||||
use Chill\CalendarBundle\Export\Declarations;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Export\FilterInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Doctrine\ORM\Query\Expr\Andx;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class ScopeFilter implements FilterInterface
|
||||
{
|
||||
|
||||
protected TranslatorInterface $translator;
|
||||
|
||||
private TranslatableStringHelper $translatableStringHelper;
|
||||
|
||||
public function __construct(
|
||||
TranslatorInterface $translator,
|
||||
TranslatableStringHelper $translatableStringHelper
|
||||
) {
|
||||
$this->translator = $translator;
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder)
|
||||
{
|
||||
$builder->add('scope', EntityType::class, [
|
||||
'class' => Scope::class,
|
||||
'choice_label' => function (Scope $s) {
|
||||
return $this->translatableStringHelper->localize(
|
||||
$s->getName()
|
||||
);
|
||||
},
|
||||
'multiple' => true,
|
||||
'expanded' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function describeAction($data, $format = 'string')
|
||||
{
|
||||
$scopes = [];
|
||||
|
||||
foreach ($data['scope'] as $s) {
|
||||
$scopes[] = $this->translatableStringHelper->localize(
|
||||
$s->getName());
|
||||
}
|
||||
|
||||
return ['Filtered by agent scope: only %scopes%', [
|
||||
'%scopes%' => implode(', ou ', $scopes)
|
||||
]];
|
||||
}
|
||||
|
||||
public function addRole()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function alterQuery(QueryBuilder $qb, $data)
|
||||
{
|
||||
$qb->join('cal.user', 'u');
|
||||
|
||||
$where = $qb->getDQLPart('where');
|
||||
$clause = $qb->expr()->in('u.mainScope', ':scope');
|
||||
|
||||
if ($where instanceof Andx) {
|
||||
$where->add($clause);
|
||||
} else {
|
||||
$where = $qb->expr()->andX($clause);
|
||||
}
|
||||
|
||||
$qb->add('where', $where);
|
||||
$qb->setParameter('scope', $data['scope']);
|
||||
}
|
||||
|
||||
public function applyOn()
|
||||
{
|
||||
return Declarations::CALENDAR_TYPE;
|
||||
}
|
||||
|
||||
|
||||
public function getTitle()
|
||||
{
|
||||
return 'Filter by agent scope';
|
||||
}
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
services:
|
||||
|
||||
## Indicators
|
||||
chill.calendar.export.count_appointments:
|
||||
class: Chill\CalendarBundle\Export\Export\CountAppointments
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export, alias: count_appointments }
|
||||
|
||||
chill.calendar.export.average_duration_appointments:
|
||||
class: Chill\CalendarBundle\Export\Export\StatAppointmentAvgDuration
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export, alias: average_duration_appointments }
|
||||
|
||||
chill.calendar.export.sum_duration_appointments:
|
||||
class: Chill\CalendarBundle\Export\Export\StatAppointmentSumDuration
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export, alias: sum_duration_appointments }
|
||||
|
||||
## Filters
|
||||
|
||||
chill.calendar.export.agent_filter:
|
||||
class: Chill\CalendarBundle\Export\Filter\AgentFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: agent_filter }
|
||||
|
||||
chill.calendar.export.job_filter:
|
||||
class: Chill\CalendarBundle\Export\Filter\JobFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: job_filter }
|
||||
|
||||
chill.calendar.export.scope_filter:
|
||||
class: Chill\CalendarBundle\Export\Filter\ScopeFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: scope_filter }
|
||||
|
||||
chill.calendar.export.between_dates_filter:
|
||||
class: Chill\CalendarBundle\Export\Filter\BetweenDatesFilter
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_filter, alias: between_dates_filter }
|
||||
|
||||
## Aggregator
|
||||
|
||||
chill.calendar.export.agent_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\AgentAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: agent_aggregator }
|
||||
|
||||
chill.calendar.export.job_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\JobAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: job_aggregator }
|
||||
|
||||
chill.calendar.export.scope_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\ScopeAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: scope_aggregator }
|
||||
|
||||
chill.calendar.export.location_type_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\LocationTypeAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: location_type_aggregator }
|
||||
|
||||
chill.calendar.export.location_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\LocationAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: location_aggregator }
|
||||
|
||||
chill.calendar.export.cancel_reason_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\CancelReasonAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: cancel_reason_aggregator }
|
||||
|
||||
chill.calendar.export.month_aggregator:
|
||||
class: Chill\CalendarBundle\Export\Aggregator\MonthYearAggregator
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
tags:
|
||||
- { name: chill.export_aggregator, alias: month_aggregator }
|
@@ -69,3 +69,36 @@ invite:
|
||||
declined: Refusé
|
||||
pending: En attente
|
||||
tentative: Accepté provisoirement
|
||||
|
||||
# exports
|
||||
Exports of calendar: Exports des rendez-vous
|
||||
Count appointments: Nombre de rendez-vous
|
||||
Count appointments by various parameters.: Compte le nombre de rendez-vous en fonction de différents paramètres.
|
||||
|
||||
Average appointment duration: Moyenne de la durée des rendez-vous
|
||||
Get the average of appointment duration according to various filters: Calcule la moyenne des durées des rendez-vous en fonction de différents paramètres.
|
||||
|
||||
Sum of appointment durations: Somme de la durée des rendez-vous
|
||||
Get the sum of appointment durations according to various filters: Calcule la somme des durées des rendez-vous en fonction de différents paramètres.
|
||||
|
||||
'Filtered by agent: only %agents%': "Filtré par agents: uniquement %agents%"
|
||||
Filter by agent: Filtrer par agents
|
||||
Filter by agent job: Filtrer par métiers des agents
|
||||
'Filtered by agent job: only %jobs%': 'Filtré par métiers des agents: uniquement les %jobs%'
|
||||
Filter by agent scope: Filtrer par services des agents
|
||||
'Filtered by agent scope: only %scopes%': 'Filtré par services des agents: uniquement les services %scopes%'
|
||||
Filter by appointments between certain dates: Filtrer par date du rendez-vous
|
||||
'Filtered by appointments between %dateFrom% and %dateTo%': 'Filtré par rendez-vous entre %dateFrom% et %dateTo%'
|
||||
|
||||
Group by agent: Grouper par agent
|
||||
Group by agent job: Grouper par métier de l'agent
|
||||
Group by agent scope: Grouper par service de l'agent
|
||||
Group by location type: Grouper par type de localisation
|
||||
Group by location: Grouper par lieu de rendez-vous
|
||||
Group by cancel reason: Grouper par motif d'annulation
|
||||
Group by month and year: Grouper par mois et année
|
||||
Scope: Service
|
||||
Job: Métier
|
||||
Location type: Type de localisation
|
||||
Location: Lieu de rendez-vous
|
||||
by month and year: Par mois et année
|
||||
|
@@ -188,7 +188,7 @@ class CustomFieldChoice extends AbstractCustomField
|
||||
$choices = [];
|
||||
|
||||
foreach ($cf->getOptions()[self::CHOICES] as $choice) {
|
||||
if (false === $choices['active']) {
|
||||
if (false === $choice['active']) {
|
||||
continue;
|
||||
}
|
||||
$choices[$choice['slug']] = $this->translatableStringHelper
|
||||
|
@@ -86,6 +86,9 @@ class ExportController extends AbstractController
|
||||
{
|
||||
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
|
||||
$exportManager = $this->exportManager;
|
||||
|
||||
$export = $exportManager->getExport($alias);
|
||||
|
||||
$key = $request->query->get('key', null);
|
||||
|
||||
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key);
|
||||
@@ -100,7 +103,8 @@ class ExportController extends AbstractController
|
||||
|
||||
$viewVariables = [
|
||||
'alias' => $alias,
|
||||
'export' => $exportManager->getExport($alias),
|
||||
'export' => $export,
|
||||
'export_group' => $this->getExportGroup($export),
|
||||
];
|
||||
|
||||
if ($formater instanceof \Chill\MainBundle\Export\Formatter\CSVListFormatter) {
|
||||
@@ -316,6 +320,7 @@ class ExportController extends AbstractController
|
||||
'form' => $form->createView(),
|
||||
'export_alias' => $alias,
|
||||
'export' => $export,
|
||||
'export_group' => $this->getExportGroup($export),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -371,6 +376,7 @@ class ExportController extends AbstractController
|
||||
[
|
||||
'form' => $form->createView(),
|
||||
'export' => $export,
|
||||
'export_group' => $this->getExportGroup($export),
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -514,6 +520,7 @@ class ExportController extends AbstractController
|
||||
[
|
||||
'form' => $form->createView(),
|
||||
'export' => $export,
|
||||
'export_group' => $this->getExportGroup($export),
|
||||
]
|
||||
);
|
||||
}
|
||||
@@ -565,4 +572,19 @@ class ExportController extends AbstractController
|
||||
throw new LogicException("the step {$step} is not defined.");
|
||||
}
|
||||
}
|
||||
|
||||
private function getExportGroup($target): string
|
||||
{
|
||||
$exportManager = $this->exportManager;
|
||||
|
||||
$groups = $exportManager->getExportsGrouped(true);
|
||||
|
||||
foreach ($groups as $group => $array) {
|
||||
foreach ($array as $alias => $export) {
|
||||
if ($export === $target) {
|
||||
return $group;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ use Chill\MainBundle\Controller\UserController;
|
||||
use Chill\MainBundle\Controller\UserJobApiController;
|
||||
use Chill\MainBundle\Controller\UserJobController;
|
||||
use Chill\MainBundle\DependencyInjection\Widget\Factory\WidgetFactoryInterface;
|
||||
use Chill\MainBundle\Doctrine\DQL\Extract;
|
||||
use Chill\MainBundle\Doctrine\DQL\GetJsonFieldByKey;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonAggregate;
|
||||
use Chill\MainBundle\Doctrine\DQL\JsonbArrayLength;
|
||||
@@ -31,6 +32,7 @@ use Chill\MainBundle\Doctrine\DQL\Replace;
|
||||
use Chill\MainBundle\Doctrine\DQL\Similarity;
|
||||
use Chill\MainBundle\Doctrine\DQL\STContains;
|
||||
use Chill\MainBundle\Doctrine\DQL\StrictWordSimilarityOPS;
|
||||
use Chill\MainBundle\Doctrine\DQL\ToChar;
|
||||
use Chill\MainBundle\Doctrine\DQL\Unaccent;
|
||||
use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator;
|
||||
use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType;
|
||||
@@ -241,6 +243,10 @@ class ChillMainExtension extends Extension implements
|
||||
'ST_CONTAINS' => STContains::class,
|
||||
'JSONB_ARRAY_LENGTH' => JsonbArrayLength::class,
|
||||
],
|
||||
'datetime_functions' => [
|
||||
'EXTRACT' => Extract::class,
|
||||
'TO_CHAR' => ToChar::class,
|
||||
],
|
||||
],
|
||||
'hydrators' => [
|
||||
'chill_flat_hierarchy_list' => FlatHierarchyEntityHydrator::class,
|
||||
|
54
src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php
Normal file
54
src/Bundle/ChillMainBundle/Doctrine/DQL/Extract.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\ORM\Query\AST\Functions\DateDiffFunction;
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\AST\PathExpression;
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
/**
|
||||
* Extract postgresql function
|
||||
* https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
|
||||
*
|
||||
* Usage : EXTRACT(field FROM timestamp)
|
||||
* TODO allow interval usage -> EXTRACT(field FROM interval)
|
||||
*/
|
||||
class Extract extends FunctionNode
|
||||
{
|
||||
private string $field;
|
||||
|
||||
private $value;
|
||||
//private PathExpression $value;
|
||||
//private FunctionNode $value;
|
||||
//private DateDiffFunction $value;
|
||||
|
||||
public function getSql(SqlWalker $sqlWalker)
|
||||
{
|
||||
return sprintf(
|
||||
'EXTRACT(%s FROM %s)',
|
||||
$this->field,
|
||||
$this->value->dispatch($sqlWalker)
|
||||
);
|
||||
}
|
||||
|
||||
public function parse(Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$this->field = $parser->getLexer()->token['value'];
|
||||
|
||||
$parser->match(Lexer::T_FROM);
|
||||
|
||||
//$this->value = $parser->ScalarExpression();
|
||||
$this->value = $parser->ArithmeticPrimary();
|
||||
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
}
|
38
src/Bundle/ChillMainBundle/Doctrine/DQL/ToChar.php
Normal file
38
src/Bundle/ChillMainBundle/Doctrine/DQL/ToChar.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Chill\MainBundle\Doctrine\DQL;
|
||||
|
||||
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
|
||||
use Doctrine\ORM\Query\Lexer;
|
||||
use Doctrine\ORM\Query\Parser;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
|
||||
/**
|
||||
* Usage : TO_CHAR(datetime, fmt)
|
||||
*/
|
||||
class ToChar extends FunctionNode
|
||||
{
|
||||
private $datetime;
|
||||
|
||||
private $fmt;
|
||||
|
||||
public function getSql(SqlWalker $sqlWalker)
|
||||
{
|
||||
return sprintf(
|
||||
'TO_CHAR(%s, %s)',
|
||||
$sqlWalker->walkArithmeticPrimary($this->datetime),
|
||||
$sqlWalker->walkArithmeticPrimary($this->fmt)
|
||||
);
|
||||
}
|
||||
|
||||
public function parse(Parser $parser)
|
||||
{
|
||||
$parser->match(Lexer::T_IDENTIFIER);
|
||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
||||
$this->datetime = $parser->ArithmeticExpression();
|
||||
$parser->match(Lexer::T_COMMA);
|
||||
$this->fmt = $parser->StringExpression();
|
||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
||||
}
|
||||
|
||||
}
|
72
src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php
Normal file
72
src/Bundle/ChillMainBundle/Entity/GeographicalUnit.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Chill\MainBundle\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Table(name="chill_main_geographical_unit")
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class GeographicalUnit
|
||||
{
|
||||
/**
|
||||
* @ORM\Column(type="text", nullable=true)
|
||||
*/
|
||||
private $geom;
|
||||
|
||||
/**
|
||||
* @ORM\Id
|
||||
* @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private ?int $id = null;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $layerName;
|
||||
|
||||
/**
|
||||
* @ORM\Column(type="string", length=255, nullable=true)
|
||||
*/
|
||||
private $unitName;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getLayerName(): ?string
|
||||
{
|
||||
return $this->layerName;
|
||||
}
|
||||
|
||||
public function getUnitName(): ?string
|
||||
{
|
||||
return $this->unitName;
|
||||
}
|
||||
|
||||
public function setLayerName(?string $layerName): self
|
||||
{
|
||||
$this->layerName = $layerName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setUnitName(?string $unitName): self
|
||||
{
|
||||
$this->unitName = $unitName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -568,6 +568,10 @@ class ExportManager
|
||||
'role' => $role->getRole(),
|
||||
]);
|
||||
|
||||
///// Bypasse les autorisations qui empêche d'afficher les nouveaux exports
|
||||
return true;
|
||||
///// TODO supprimer le return true
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -449,7 +449,9 @@ class SpreadSheetFormatter implements FormatterInterface
|
||||
|
||||
protected function getTitle()
|
||||
{
|
||||
return $this->translator->trans($this->export->getTitle());
|
||||
$title = $this->translator->trans($this->export->getTitle());
|
||||
|
||||
return substr($title, 0, 30) . '…';
|
||||
}
|
||||
|
||||
protected function initializeCache($key)
|
||||
|
@@ -59,7 +59,7 @@ class CommentType extends AbstractType
|
||||
$view->vars = array_replace(
|
||||
$view->vars,
|
||||
[
|
||||
'hideLabel' => true,
|
||||
'fullWidth' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@@ -46,7 +46,7 @@ class PrivateCommentType extends AbstractType
|
||||
|
||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
$view->vars['hideLabel'] = true;
|
||||
$view->vars['fullWidth'] = true;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
|
@@ -108,7 +108,7 @@ class ScopePickerType extends AbstractType
|
||||
$view->vars = array_replace(
|
||||
$view->vars,
|
||||
[
|
||||
'hideLabel' => true,
|
||||
'fullWidth' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ namespace Chill\MainBundle\Repository;
|
||||
use Chill\MainBundle\Entity\Country;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Doctrine\Persistence\ObjectRepository;
|
||||
|
||||
final class CountryRepository implements ObjectRepository
|
||||
@@ -25,6 +26,11 @@ final class CountryRepository implements ObjectRepository
|
||||
$this->repository = $entityManager->getRepository(Country::class);
|
||||
}
|
||||
|
||||
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
|
||||
{
|
||||
return $this->repository->createQueryBuilder($alias, $indexBy);
|
||||
}
|
||||
|
||||
public function find($id, $lockMode = null, $lockVersion = null): ?Country
|
||||
{
|
||||
return $this->repository->find($id, $lockMode, $lockVersion);
|
||||
|
@@ -46,7 +46,6 @@ require('../lib/collection/index.js');
|
||||
require('../lib/breadcrumb/index.js');
|
||||
require('../lib/download-report/index.js');
|
||||
require('../lib/select_interactive_loading/index.js');
|
||||
require('../lib/export-list/index.js');
|
||||
|
||||
//require('../lib/show_hide/index.js');
|
||||
//require('../lib/tabs/index.js');
|
||||
|
@@ -99,11 +99,14 @@ div.flex-table {
|
||||
div.item-bloc {
|
||||
flex-direction: column;
|
||||
|
||||
&:nth-child(even) {
|
||||
background-color: $gray-200;
|
||||
&:not(.no-altern) { // class to avoid even/odd
|
||||
|
||||
.chill-user-quote {
|
||||
background-color: shade-color($gray-200, 5%)
|
||||
&:nth-child(even) {
|
||||
background-color: $gray-200;
|
||||
|
||||
.chill-user-quote {
|
||||
background-color: shade-color($gray-200, 5%)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,20 +0,0 @@
|
||||
.container-export {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
|
||||
.export-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.export-list__element {
|
||||
min-width: 18rem;
|
||||
max-width: 20rem;
|
||||
padding: 1rem;
|
||||
margin: 1rem;
|
||||
flex-grow: 1;
|
||||
|
||||
border: 1px solid var(--chill-gray);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1 +0,0 @@
|
||||
require('./export-list.scss');
|
@@ -1,14 +1,23 @@
|
||||
// Configuration
|
||||
/*
|
||||
* This shared file is used in Chill sass sheets and Vue sass styles to use some bootstrap/chill variables.
|
||||
* Search on @import 'ChillMainAssets/module/bootstrap/shared';
|
||||
*/
|
||||
|
||||
// 1. Include functions first (so you can manipulate colors, SVGs, calc, etc)
|
||||
@import "bootstrap/scss/functions";
|
||||
|
||||
/*
|
||||
* Replaced by CHILL variables
|
||||
* it is necessary to keep the possibility of making a diff with original !
|
||||
* original: "bootstrap/scss/variables";
|
||||
*/
|
||||
// 2. Include any default variable overrides here
|
||||
@import "custom/_variables";
|
||||
|
||||
// 3. Include remainder of required Bootstrap stylesheets
|
||||
@import "bootstrap/scss/variables";
|
||||
|
||||
// 4. Include any default map overrides here
|
||||
@import "custom/_maps";
|
||||
|
||||
// 5. Include remainder of required parts
|
||||
@import "bootstrap/scss/mixins";
|
||||
@import "bootstrap/scss/utilities";
|
||||
@import "bootstrap/scss/root";
|
||||
|
||||
|
||||
|
||||
|
@@ -1,18 +1,8 @@
|
||||
/*!
|
||||
* Bootstrap v5.0.1 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2021 The Bootstrap Authors
|
||||
* Copyright 2011-2021 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*
|
||||
* Enable / disable bootstrap assets
|
||||
*/
|
||||
|
||||
// Bootstrap configuration files are shared with chill entrypoint
|
||||
// Some Bootstrap variables and configuration files are shared with chill entrypoint
|
||||
@import "shared";
|
||||
|
||||
// scss-docs-start import-stack
|
||||
// Layout & components
|
||||
@import "bootstrap/scss/root";
|
||||
// 6. Optionally include any other parts as needed
|
||||
@import "bootstrap/scss/utilities";
|
||||
@import "bootstrap/scss/reboot";
|
||||
@import "bootstrap/scss/type";
|
||||
@import "bootstrap/scss/images";
|
||||
@@ -42,14 +32,11 @@
|
||||
@import "bootstrap/scss/carousel";
|
||||
@import "bootstrap/scss/spinners";
|
||||
@import "bootstrap/scss/offcanvas";
|
||||
|
||||
// Helpers
|
||||
@import "bootstrap/scss/helpers";
|
||||
|
||||
// Utilities
|
||||
// 7. Optionally include utilities API last to generate classes based on the Sass map in
|
||||
@import "bootstrap/scss/utilities/api";
|
||||
// scss-docs-end import-stack
|
||||
|
||||
// CHILL custom
|
||||
// 8. Add additional custom code here
|
||||
@import "custom";
|
||||
@import "custom/_debug";
|
||||
|
@@ -0,0 +1,69 @@
|
||||
//// CHILL OVERRIDE DEFAULT BOOTSTRAP COLORS MAP
|
||||
|
||||
// 'beige' variations
|
||||
$beige-100: tint-color($beige, 80%);
|
||||
$beige-200: tint-color($beige, 60%);
|
||||
$beige-300: tint-color($beige, 40%);
|
||||
$beige-400: tint-color($beige, 20%);
|
||||
$beige-500: $beige;
|
||||
$beige-600: shade-color($beige, 20%);
|
||||
$beige-700: shade-color($beige, 40%);
|
||||
$beige-800: shade-color($beige, 60%);
|
||||
$beige-900: shade-color($beige, 80%);
|
||||
|
||||
$chill-blue: $blue;
|
||||
$chill-green: $green;
|
||||
$chill-green-dark: $green-600;
|
||||
$chill-orange: $orange;
|
||||
$chill-yellow: $yellow;
|
||||
$chill-red: $red;
|
||||
$chill-beige: $beige;
|
||||
$chill-pink: $pink;
|
||||
$chill-dark-gray: $gray-800;
|
||||
$chill-gray: $gray-600;
|
||||
$chill-l-gray: $gray-400;
|
||||
$chill-ll-gray: $gray-300;
|
||||
$chill-light-gray: $gray-200;
|
||||
$chill-llight-gray: $gray-100;
|
||||
|
||||
$colors: (
|
||||
"blue": $blue,
|
||||
"green": $green,
|
||||
"green-dark": $green-600,
|
||||
"yellow": $yellow,
|
||||
"orange": $orange,
|
||||
"red": $red,
|
||||
"pink": $pink,
|
||||
"beige": $beige,
|
||||
"white": $white,
|
||||
"gray": $gray-600,
|
||||
"dark": $gray-800,
|
||||
"black": $black
|
||||
);
|
||||
|
||||
$chill-colors: (
|
||||
"chill-blue": $chill-blue,
|
||||
"chill-green": $chill-green,
|
||||
"chill-green-dark": $chill-green-dark,
|
||||
"chill-orange": $chill-orange,
|
||||
"chill-yellow": $chill-yellow,
|
||||
"chill-red": $chill-red,
|
||||
"chill-beige": $chill-beige,
|
||||
"chill-pink": $chill-pink,
|
||||
"chill-dark-gray": $chill-dark-gray,
|
||||
"chill-gray": $chill-gray,
|
||||
"chill-l-gray": $chill-l-gray,
|
||||
"chill-ll-gray": $chill-ll-gray,
|
||||
"chill-light-gray": $chill-light-gray,
|
||||
"chill-llight-gray": $chill-llight-gray,
|
||||
);
|
||||
|
||||
// Merge the maps
|
||||
$theme-colors: map-merge($theme-colors, $chill-colors);
|
||||
|
||||
// Chill color classes
|
||||
@each $color, $value in $chill-colors {
|
||||
.#{$color} {
|
||||
color: $value;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,190 +0,0 @@
|
||||
/*
|
||||
* NOTE 2021.04
|
||||
* scss/chill.scss is the main sass file for the new chill.2
|
||||
* scratch will be replaced by bootstrap, please avoid to edit in modules/scratch/_custom.scss
|
||||
*/
|
||||
|
||||
// YOUR CUSTOM SCSS
|
||||
@import 'custom/config/colors';
|
||||
@import 'custom/config/variables';
|
||||
@import 'custom/fonts';
|
||||
@import 'custom/timeline';
|
||||
@import 'custom/mixins/entity';
|
||||
@import 'custom/report';
|
||||
@import 'custom/person';
|
||||
@import 'custom/pagination';
|
||||
@import 'custom/custom-fields';
|
||||
@import 'custom/address';
|
||||
@import 'custom/record_actions';
|
||||
@import 'custom/flash_messages';
|
||||
@import 'custom/box';
|
||||
|
||||
|
||||
html,body {
|
||||
min-height:100%;
|
||||
font-family: 'Open Sans';
|
||||
}
|
||||
|
||||
header {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#content_conainter {
|
||||
position: relative;
|
||||
min-height: calc(100% - 145px);
|
||||
}
|
||||
|
||||
#content_conainter:before {
|
||||
bottom: 0;
|
||||
content: "";
|
||||
left: 0;
|
||||
opacity: 0.1;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
//background-image: url('./../../img/background/desert.jpg');
|
||||
background-attachment: fixed;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
/* CUSTOM FIELDS -> */
|
||||
.cf-title {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.cf-subtitle {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
/* <- CUSTOM FIELDS */
|
||||
|
||||
@each $len in 11, 15 {
|
||||
ul.submenu.width-#{$len}-em {
|
||||
min-width: #{$len}em;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
.select2 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
ul.custom_fields.choice li {
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
.errors {
|
||||
color: $red;
|
||||
}
|
||||
|
||||
.footer {
|
||||
p {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
// inline time input
|
||||
.time_compound {
|
||||
input[type=text], select {
|
||||
width: 4em;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.separator {
|
||||
margin-left: 0.2em;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.open_sansbold {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
|
||||
dd {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-family: 'Open Sans';
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
/* INPUT CLASS -> */
|
||||
div.input_with_post_text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.input_with_post_text span.post_text {
|
||||
flex: 1;
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
div.input_with_post_text input {
|
||||
width: 70%;
|
||||
display: inline-block;
|
||||
flex: 2;
|
||||
}
|
||||
/* <- INPUT CLASS */
|
||||
|
||||
dl.chill_report_view_data,
|
||||
dl.chill_view_data {
|
||||
|
||||
dt {
|
||||
margin-top: 1.5em;
|
||||
color: $chill-blue;
|
||||
}
|
||||
|
||||
dd {
|
||||
padding-left: 1.5em;
|
||||
margin-top: 0.2em;
|
||||
|
||||
ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
blockquote.chill-user-quote,
|
||||
div.chill-user-quote {
|
||||
border-left: 10px solid $chill-yellow;
|
||||
margin: 1.5em 10px;
|
||||
padding: 0.5em 10px;
|
||||
quotes: "\201C""\201D""\2018""\2019";
|
||||
background-color: $chill-llight-gray;
|
||||
|
||||
blockquote {
|
||||
margin: 1.5em 10px;
|
||||
padding: 0.5em 10px;
|
||||
}
|
||||
|
||||
blockquote:before {
|
||||
color: #ccc;
|
||||
content: open-quote;
|
||||
font-size: 4em;
|
||||
line-height: 0.1em;
|
||||
margin-right: 0.25em;
|
||||
vertical-align: -0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.chill-no-data-statement {
|
||||
font-style: italic;
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
// Buttons
|
||||
$button-font-size : 15px !default;
|
||||
$button-text-color : #000 !default;
|
||||
$button-text-weight : 300 !default;
|
||||
$button-padding : 8px 12px !default;
|
||||
$button-background : #eee !default;
|
||||
$button-margin : 5px !default;
|
@@ -1,64 +0,0 @@
|
||||
// BODY
|
||||
$body-background : #fff !default;
|
||||
|
||||
// PLAIN TEXT
|
||||
$text-color : #555 !default;
|
||||
|
||||
// HEADINGS
|
||||
$headings-color : #404040 !default;
|
||||
|
||||
// LINKS
|
||||
$link-color : #6998C9 !default;
|
||||
$link-visited-color : #808080 !default;
|
||||
$link-active-color : shade(red,5%) !default;
|
||||
$link-hover-color : #007ED5 !default;
|
||||
$link-focus-color : $link-color !default;
|
||||
|
||||
$white : #fff !default;
|
||||
$black : #000 !default;
|
||||
$orange : #FF622C !default;
|
||||
$red : #C83D3D !default;
|
||||
$green : #27806f !default;
|
||||
$blue : #2980b9 !default;
|
||||
$yellow : #FFC82C !default;
|
||||
|
||||
$light-blue : #4995C7;
|
||||
$llight-blue : #72B0D9;
|
||||
$dark-blue : #096EB0 !default;
|
||||
$ddark-blue : #07507F !default;
|
||||
|
||||
$light-green : #419484 !default;
|
||||
$llight-green : #6CB3A5 !default;
|
||||
|
||||
$warning-bg : $orange !default;
|
||||
$caution-bg : $red !default;
|
||||
$error-bg : $red !default;
|
||||
$success-bg : $green !default;
|
||||
$info-bg : $blue !default;
|
||||
|
||||
$grey-95 : lighten($black, 5%) !default;
|
||||
$grey-90 : lighten($black, 10%) !default;
|
||||
$grey-85 : lighten($black, 15%) !default;
|
||||
$grey-80 : lighten($black, 20%) !default;
|
||||
$grey-75 : lighten($black, 25%) !default;
|
||||
$grey-70 : lighten($black, 30%) !default;
|
||||
$grey-65 : lighten($black, 35%) !default;
|
||||
$grey-60 : lighten($black, 40%) !default;
|
||||
$grey-55 : lighten($black, 45%) !default;
|
||||
$grey-50 : lighten($black, 50%) !default;
|
||||
$grey-45 : lighten($black, 55%) !default;
|
||||
$grey-40 : lighten($black, 60%) !default;
|
||||
$grey-35 : lighten($black, 65%) !default;
|
||||
$grey-30 : lighten($black, 70%) !default;
|
||||
$grey-25 : lighten($black, 75%) !default;
|
||||
$grey-20 : lighten($black, 80%) !default;
|
||||
$grey-15 : lighten($black, 85%) !default;
|
||||
$grey-10 : lighten($black, 90%) !default;
|
||||
$grey-5 : lighten($black, 95%) !default;
|
||||
|
||||
|
||||
$dark-grey: $grey-80; //#333;
|
||||
$medium-grey: $grey-50; //#999;
|
||||
$light-grey: $grey-20; //#DDD;
|
||||
|
||||
@import "../custom/config/colors";
|
@@ -1,115 +0,0 @@
|
||||
// Typography
|
||||
//$sans-serif: $helvetica;
|
||||
//$serif: $georgia;
|
||||
//$base-font-family: $sans-serif;
|
||||
//$header-font-family: $base-font-family;
|
||||
|
||||
// Font Sizes
|
||||
$base-font-size: 1em;
|
||||
$h1-font-size: $base-font-size * 2.25;
|
||||
$h2-font-size: $base-font-size * 2;
|
||||
$h3-font-size: $base-font-size * 1.75;
|
||||
$h4-font-size: $base-font-size * 1.5;
|
||||
$h5-font-size: $base-font-size * 1.25;
|
||||
$h6-font-size: $base-font-size;
|
||||
|
||||
// Line height
|
||||
$base-line-height: 1.5;
|
||||
$header-line-height: 1.25;
|
||||
|
||||
// Other Sizes
|
||||
$base-border-radius: 3px;
|
||||
$base-spacing: $base-line-height * 1em;
|
||||
$base-z-index: 0;
|
||||
|
||||
// Background Color
|
||||
$base-background-color: white;
|
||||
|
||||
// Font Colors
|
||||
$base-font-color: $dark-grey;
|
||||
$base-accent-color: $blue;
|
||||
|
||||
// Link Colors
|
||||
$base-link-color: $base-accent-color;
|
||||
$hover-link-color: darken($base-accent-color, 15);
|
||||
$base-button-color: $base-link-color;
|
||||
$hover-button-color: $hover-link-color;
|
||||
|
||||
/*
|
||||
// Flash Colors
|
||||
$alert-color: $light-yellow;
|
||||
$error-color: $light-red;
|
||||
$notice-color: lighten($base-accent-color, 40);
|
||||
$success-color: $light-green;
|
||||
*/
|
||||
|
||||
// Border color
|
||||
$base-border-color: $light-grey;
|
||||
$base-border: 1px solid $base-border-color;
|
||||
|
||||
// Footer
|
||||
$footer-background: $grey-50;//-blue;// desaturate(darken($base-accent-color, 20), 30);
|
||||
$footer-color: white;
|
||||
$footer-link-color: transparentize($footer-color, .6);
|
||||
$footer-disclaimer-color: transparentize($footer-color, .6);
|
||||
$footer-vertical-padding: 0;
|
||||
|
||||
// Forms
|
||||
$form-border-size: 1px;
|
||||
$form-border-color: $base-border-color;
|
||||
$form-border-color-hover: darken($base-border-color, 10);
|
||||
$form-border-color-focus: $base-accent-color;
|
||||
$form-border-radius: $base-border-radius;
|
||||
$form-box-shadow: inset 0 1px 3px rgba(black,0.06);
|
||||
$form-box-shadow-focus: $form-box-shadow, 0 0 5px rgba(darken($form-border-color-focus, 5), 0.7);
|
||||
$form-font-size: $base-font-size;
|
||||
//$form-font-family: $base-font-family;
|
||||
|
||||
// Navigation
|
||||
$navigation-background: $dark-grey;
|
||||
$navigation-color: transparentize(white, 0.3);
|
||||
$navigation-color-hover: white;
|
||||
$navigation-height: 60px;
|
||||
$navigation-active-link-color: transparentize(white, 0.5);
|
||||
$navigation-submenu-padding: 1em;
|
||||
$navigation-submenu-width: 12em;
|
||||
$navigation-border-radius: $base-border-radius;
|
||||
$navigation-first-padding-top: 1em;
|
||||
$navigation-last-padding-bottom: 0.7em;
|
||||
$navigation-more-pin: '\25BE';
|
||||
$navigation-more-pin-color: $navigation-color;
|
||||
$navigation-ul-submenu-top: 1.5em;
|
||||
$navigation-ul-submenu-padding-left: 0;
|
||||
$navigation-search-padding: .85em .6em;
|
||||
$navigation-border-bottom: 1px solid darken($navigation-background, 10);
|
||||
|
||||
//Table
|
||||
$table-width: 100%;
|
||||
|
||||
$table-head-bg-color: $orange;
|
||||
$table-head-td-border: unset;
|
||||
$table-head-td-text-align: center;
|
||||
$table-head-td-padding: 0.3em;
|
||||
$table-head-text-color: $white;
|
||||
|
||||
$table-body-tr-bg-color-even: $grey-5;
|
||||
$table-body-tr-bg-color-odd: unset;
|
||||
$table-body-td-border: unset;
|
||||
$table-body-td-text-align: left;
|
||||
$table-body-td-padding: 0.3em;
|
||||
$table-body-text-color: unset;
|
||||
|
||||
//Tabs
|
||||
$tabs-nav-margin-bottom: none;
|
||||
$tabs-nav-title-bg-color: $blue;
|
||||
$tabs-nav-title-text-color: $white;
|
||||
$tabs-nav-title-padding: 0.5em 0.5em 0.5em 1em;
|
||||
$tabs-nav-bg-color: none;
|
||||
$tabs-nav-text-color: inherit;
|
||||
$tabs-new-border: 3px solid transparent;
|
||||
$tabs-nav-hover-border: 3px solid $orange;
|
||||
$tabs-nav-hover-text-color: inherit;
|
||||
$tabs-nav-font-family: unset;
|
||||
$tabs-nav-padding: 0.5em 0.5em 0.5em 1.5em;
|
||||
|
||||
@import "../custom/config/variables";
|
@@ -1,411 +0,0 @@
|
||||
// The following features have been deprecated and will be removed in the next MAJOR version release
|
||||
|
||||
@mixin inline-block {
|
||||
display: inline-block;
|
||||
|
||||
@warn "The inline-block mixin is deprecated and will be removed in the next major version release";
|
||||
}
|
||||
|
||||
@mixin button ($style: simple, $base-color: #4294f0, $text-size: inherit, $padding: 7px 18px) {
|
||||
|
||||
@if type-of($style) == string and type-of($base-color) == color {
|
||||
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||
}
|
||||
|
||||
@if type-of($style) == string and type-of($base-color) == number {
|
||||
$padding: $text-size;
|
||||
$text-size: $base-color;
|
||||
$base-color: #4294f0;
|
||||
|
||||
@if $padding == inherit {
|
||||
$padding: 7px 18px;
|
||||
}
|
||||
|
||||
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||
}
|
||||
|
||||
@if type-of($style) == color and type-of($base-color) == color {
|
||||
$base-color: $style;
|
||||
$style: simple;
|
||||
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||
}
|
||||
|
||||
@if type-of($style) == color and type-of($base-color) == number {
|
||||
$padding: $text-size;
|
||||
$text-size: $base-color;
|
||||
$base-color: $style;
|
||||
$style: simple;
|
||||
|
||||
@if $padding == inherit {
|
||||
$padding: 7px 18px;
|
||||
}
|
||||
|
||||
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||
}
|
||||
|
||||
@if type-of($style) == number {
|
||||
$padding: $base-color;
|
||||
$text-size: $style;
|
||||
$base-color: #4294f0;
|
||||
$style: simple;
|
||||
|
||||
@if $padding == #4294f0 {
|
||||
$padding: 7px 18px;
|
||||
}
|
||||
|
||||
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@warn "The button mixin is deprecated and will be removed in the next major version release";
|
||||
}
|
||||
|
||||
// Selector Style Button
|
||||
@mixin buttonstyle($type, $b-color, $t-size, $pad) {
|
||||
// Grayscale button
|
||||
@if $type == simple and $b-color == grayscale($b-color) {
|
||||
@include simple($b-color, true, $t-size, $pad);
|
||||
}
|
||||
|
||||
@if $type == shiny and $b-color == grayscale($b-color) {
|
||||
@include shiny($b-color, true, $t-size, $pad);
|
||||
}
|
||||
|
||||
@if $type == pill and $b-color == grayscale($b-color) {
|
||||
@include pill($b-color, true, $t-size, $pad);
|
||||
}
|
||||
|
||||
@if $type == flat and $b-color == grayscale($b-color) {
|
||||
@include flat($b-color, true, $t-size, $pad);
|
||||
}
|
||||
|
||||
// Colored button
|
||||
@if $type == simple {
|
||||
@include simple($b-color, false, $t-size, $pad);
|
||||
}
|
||||
|
||||
@else if $type == shiny {
|
||||
@include shiny($b-color, false, $t-size, $pad);
|
||||
}
|
||||
|
||||
@else if $type == pill {
|
||||
@include pill($b-color, false, $t-size, $pad);
|
||||
}
|
||||
|
||||
@else if $type == flat {
|
||||
@include flat($b-color, false, $t-size, $pad);
|
||||
}
|
||||
}
|
||||
|
||||
// Simple Button
|
||||
@mixin simple($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||
$color: hsl(0, 0, 100%);
|
||||
$border: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
|
||||
$inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%);
|
||||
$stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%);
|
||||
$text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%);
|
||||
|
||||
@if is-light($base-color) {
|
||||
$color: hsl(0, 0, 20%);
|
||||
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||
}
|
||||
|
||||
@if $grayscale == true {
|
||||
$border: grayscale($border);
|
||||
$inset-shadow: grayscale($inset-shadow);
|
||||
$stop-gradient: grayscale($stop-gradient);
|
||||
$text-shadow: grayscale($text-shadow);
|
||||
}
|
||||
|
||||
border: 1px solid $border;
|
||||
border-radius: 3px;
|
||||
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||
color: $color;
|
||||
display: inline-block;
|
||||
font-size: $textsize;
|
||||
font-weight: bold;
|
||||
@include linear-gradient ($base-color, $stop-gradient);
|
||||
padding: $padding;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 0 $text-shadow;
|
||||
background-clip: padding-box;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
$base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
|
||||
$inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%);
|
||||
$stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%);
|
||||
|
||||
@if $grayscale == true {
|
||||
$base-color-hover: grayscale($base-color-hover);
|
||||
$inset-shadow-hover: grayscale($inset-shadow-hover);
|
||||
$stop-gradient-hover: grayscale($stop-gradient-hover);
|
||||
}
|
||||
|
||||
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
|
||||
|
||||
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active:not(:disabled),
|
||||
&:focus:not(:disabled) {
|
||||
$border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
|
||||
$inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%);
|
||||
|
||||
@if $grayscale == true {
|
||||
$border-active: grayscale($border-active);
|
||||
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||
}
|
||||
|
||||
border: 1px solid $border-active;
|
||||
box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active;
|
||||
}
|
||||
}
|
||||
|
||||
// Shiny Button
|
||||
@mixin shiny($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||
$color: hsl(0, 0, 100%);
|
||||
$border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81);
|
||||
$border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122);
|
||||
$fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46);
|
||||
$inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12);
|
||||
$second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33);
|
||||
$text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114);
|
||||
$third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48);
|
||||
|
||||
@if is-light($base-color) {
|
||||
$color: hsl(0, 0, 20%);
|
||||
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||
}
|
||||
|
||||
@if $grayscale == true {
|
||||
$border: grayscale($border);
|
||||
$border-bottom: grayscale($border-bottom);
|
||||
$fourth-stop: grayscale($fourth-stop);
|
||||
$inset-shadow: grayscale($inset-shadow);
|
||||
$second-stop: grayscale($second-stop);
|
||||
$text-shadow: grayscale($text-shadow);
|
||||
$third-stop: grayscale($third-stop);
|
||||
}
|
||||
|
||||
@include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%);
|
||||
|
||||
border: 1px solid $border;
|
||||
border-bottom: 1px solid $border-bottom;
|
||||
border-radius: 5px;
|
||||
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||
color: $color;
|
||||
display: inline-block;
|
||||
font-size: $textsize;
|
||||
font-weight: bold;
|
||||
padding: $padding;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 -1px 1px $text-shadow;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
$first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18);
|
||||
$second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51);
|
||||
$third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66);
|
||||
$fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63);
|
||||
|
||||
@if $grayscale == true {
|
||||
$first-stop-hover: grayscale($first-stop-hover);
|
||||
$second-stop-hover: grayscale($second-stop-hover);
|
||||
$third-stop-hover: grayscale($third-stop-hover);
|
||||
$fourth-stop-hover: grayscale($fourth-stop-hover);
|
||||
}
|
||||
|
||||
@include linear-gradient(top, $first-stop-hover 0%,
|
||||
$second-stop-hover 50%,
|
||||
$third-stop-hover 50%,
|
||||
$fourth-stop-hover 100%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active:not(:disabled),
|
||||
&:focus:not(:disabled) {
|
||||
$inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122);
|
||||
|
||||
@if $grayscale == true {
|
||||
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||
}
|
||||
|
||||
box-shadow: inset 0 0 20px 0 $inset-shadow-active;
|
||||
}
|
||||
}
|
||||
|
||||
// Pill Button
|
||||
@mixin pill($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||
$color: hsl(0, 0, 100%);
|
||||
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%);
|
||||
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%);
|
||||
$border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%);
|
||||
$inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%);
|
||||
$stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%);
|
||||
$text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%);
|
||||
|
||||
@if is-light($base-color) {
|
||||
$color: hsl(0, 0, 20%);
|
||||
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||
}
|
||||
|
||||
@if $grayscale == true {
|
||||
$border-bottom: grayscale($border-bottom);
|
||||
$border-sides: grayscale($border-sides);
|
||||
$border-top: grayscale($border-top);
|
||||
$inset-shadow: grayscale($inset-shadow);
|
||||
$stop-gradient: grayscale($stop-gradient);
|
||||
$text-shadow: grayscale($text-shadow);
|
||||
}
|
||||
|
||||
border: 1px solid $border-top;
|
||||
border-color: $border-top $border-sides $border-bottom;
|
||||
border-radius: 16px;
|
||||
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||
color: $color;
|
||||
display: inline-block;
|
||||
font-size: $textsize;
|
||||
font-weight: normal;
|
||||
line-height: 1;
|
||||
@include linear-gradient ($base-color, $stop-gradient);
|
||||
padding: $padding;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 -1px 1px $text-shadow;
|
||||
background-clip: padding-box;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
$base-color-hover: adjust-color($base-color, $lightness: -4.5%);
|
||||
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%);
|
||||
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%);
|
||||
$border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%);
|
||||
$inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%);
|
||||
$stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%);
|
||||
$text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%);
|
||||
|
||||
@if $grayscale == true {
|
||||
$base-color-hover: grayscale($base-color-hover);
|
||||
$border-bottom: grayscale($border-bottom);
|
||||
$border-sides: grayscale($border-sides);
|
||||
$border-top: grayscale($border-top);
|
||||
$inset-shadow-hover: grayscale($inset-shadow-hover);
|
||||
$stop-gradient-hover: grayscale($stop-gradient-hover);
|
||||
$text-shadow-hover: grayscale($text-shadow-hover);
|
||||
}
|
||||
|
||||
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
|
||||
|
||||
background-clip: padding-box;
|
||||
border: 1px solid $border-top;
|
||||
border-color: $border-top $border-sides $border-bottom;
|
||||
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
|
||||
cursor: pointer;
|
||||
text-shadow: 0 -1px 1px $text-shadow-hover;
|
||||
}
|
||||
|
||||
&:active:not(:disabled),
|
||||
&:focus:not(:disabled) {
|
||||
$active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%);
|
||||
$border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%);
|
||||
$border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%);
|
||||
$inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%);
|
||||
$text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%);
|
||||
|
||||
@if $grayscale == true {
|
||||
$active-color: grayscale($active-color);
|
||||
$border-active: grayscale($border-active);
|
||||
$border-bottom-active: grayscale($border-bottom-active);
|
||||
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||
$text-shadow-active: grayscale($text-shadow-active);
|
||||
}
|
||||
|
||||
background: $active-color;
|
||||
border: 1px solid $border-active;
|
||||
border-bottom: 1px solid $border-bottom-active;
|
||||
box-shadow: inset 0 0 6px 3px $inset-shadow-active;
|
||||
text-shadow: 0 -1px 1px $text-shadow-active;
|
||||
}
|
||||
}
|
||||
|
||||
// Flat Button
|
||||
@mixin flat($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||
$color: hsl(0, 0, 100%);
|
||||
|
||||
@if is-light($base-color) {
|
||||
$color: hsl(0, 0, 20%);
|
||||
}
|
||||
|
||||
background-color: $base-color;
|
||||
border-radius: 3px;
|
||||
border: 0;
|
||||
color: $color;
|
||||
display: inline-block;
|
||||
font-size: $textsize;
|
||||
font-weight: bold;
|
||||
padding: $padding;
|
||||
text-decoration: none;
|
||||
background-clip: padding-box;
|
||||
|
||||
&:hover:not(:disabled){
|
||||
$base-color-hover: adjust-color($base-color, $saturation: 4%, $lightness: 5%);
|
||||
|
||||
@if $grayscale == true {
|
||||
$base-color-hover: grayscale($base-color-hover);
|
||||
}
|
||||
|
||||
background-color: $base-color-hover;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active:not(:disabled),
|
||||
&:focus:not(:disabled) {
|
||||
$base-color-active: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
|
||||
|
||||
@if $grayscale == true {
|
||||
$base-color-active: grayscale($base-color-active);
|
||||
}
|
||||
|
||||
background-color: $base-color-active;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// Flexible grid
|
||||
@function flex-grid($columns, $container-columns: $fg-max-columns) {
|
||||
$width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
|
||||
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||
@return percentage($width / $container-width);
|
||||
|
||||
@warn "The flex-grid function is deprecated and will be removed in the next major version release";
|
||||
}
|
||||
|
||||
// Flexible gutter
|
||||
@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
|
||||
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||
@return percentage($gutter / $container-width);
|
||||
|
||||
@warn "The flex-gutter function is deprecated and will be removed in the next major version release";
|
||||
}
|
||||
|
||||
@function grid-width($n) {
|
||||
@return $n * $gw-column + ($n - 1) * $gw-gutter;
|
||||
|
||||
@warn "The grid-width function is deprecated and will be removed in the next major version release";
|
||||
}
|
||||
|
||||
@function golden-ratio($value, $increment) {
|
||||
@return modular-scale($increment, $value, $ratio: $golden);
|
||||
|
||||
@warn "The golden-ratio function is deprecated and will be removed in the next major version release. Please use the modular-scale function, instead.";
|
||||
}
|
||||
|
||||
@mixin box-sizing($box) {
|
||||
@include prefixer(box-sizing, $box, webkit moz spec);
|
||||
|
||||
@warn "The box-sizing mixin is deprecated and will be removed in the next major version release. This property can now be used un-prefixed.";
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
// Bourbon 4.2.6
|
||||
// http://bourbon.io
|
||||
// Copyright 2011-2015 thoughtbot, inc.
|
||||
// MIT License
|
||||
|
||||
@import "settings/prefixer";
|
||||
@import "settings/px-to-em";
|
||||
@import "settings/asset-pipeline";
|
||||
|
||||
@import "functions/assign-inputs";
|
||||
@import "functions/contains";
|
||||
@import "functions/contains-falsy";
|
||||
@import "functions/is-length";
|
||||
@import "functions/is-light";
|
||||
@import "functions/is-number";
|
||||
@import "functions/is-size";
|
||||
@import "functions/px-to-em";
|
||||
@import "functions/px-to-rem";
|
||||
@import "functions/shade";
|
||||
@import "functions/strip-units";
|
||||
@import "functions/tint";
|
||||
@import "functions/transition-property-name";
|
||||
@import "functions/unpack";
|
||||
@import "functions/modular-scale";
|
||||
|
||||
@import "helpers/convert-units";
|
||||
@import "helpers/directional-values";
|
||||
@import "helpers/font-source-declaration";
|
||||
@import "helpers/gradient-positions-parser";
|
||||
@import "helpers/linear-angle-parser";
|
||||
@import "helpers/linear-gradient-parser";
|
||||
@import "helpers/linear-positions-parser";
|
||||
@import "helpers/linear-side-corner-parser";
|
||||
@import "helpers/radial-arg-parser";
|
||||
@import "helpers/radial-positions-parser";
|
||||
@import "helpers/radial-gradient-parser";
|
||||
@import "helpers/render-gradients";
|
||||
@import "helpers/shape-size-stripper";
|
||||
@import "helpers/str-to-num";
|
||||
|
||||
@import "css3/animation";
|
||||
@import "css3/appearance";
|
||||
@import "css3/backface-visibility";
|
||||
@import "css3/background";
|
||||
@import "css3/background-image";
|
||||
@import "css3/border-image";
|
||||
@import "css3/calc";
|
||||
@import "css3/columns";
|
||||
@import "css3/filter";
|
||||
@import "css3/flex-box";
|
||||
@import "css3/font-face";
|
||||
@import "css3/font-feature-settings";
|
||||
@import "css3/hidpi-media-query";
|
||||
@import "css3/hyphens";
|
||||
@import "css3/image-rendering";
|
||||
@import "css3/keyframes";
|
||||
@import "css3/linear-gradient";
|
||||
@import "css3/perspective";
|
||||
@import "css3/placeholder";
|
||||
@import "css3/radial-gradient";
|
||||
@import "css3/selection";
|
||||
@import "css3/text-decoration";
|
||||
@import "css3/transform";
|
||||
@import "css3/transition";
|
||||
@import "css3/user-select";
|
||||
|
||||
@import "addons/border-color";
|
||||
@import "addons/border-radius";
|
||||
@import "addons/border-style";
|
||||
@import "addons/border-width";
|
||||
@import "addons/buttons";
|
||||
@import "addons/clearfix";
|
||||
@import "addons/ellipsis";
|
||||
@import "addons/font-stacks";
|
||||
@import "addons/hide-text";
|
||||
@import "addons/margin";
|
||||
@import "addons/padding";
|
||||
@import "addons/position";
|
||||
@import "addons/prefixer";
|
||||
@import "addons/retina-image";
|
||||
@import "addons/size";
|
||||
@import "addons/text-inputs";
|
||||
@import "addons/timing-functions";
|
||||
@import "addons/triangle";
|
||||
@import "addons/word-wrap";
|
||||
|
||||
@import "bourbon-deprecated-upcoming";
|
@@ -1,26 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for targeting `border-color` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||
///
|
||||
/// @param {Arglist} $vals
|
||||
/// List of arguments
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include border-color(#a60b55 #76cd9c null #e8ae1a);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// border-left-color: #e8ae1a;
|
||||
/// border-right-color: #76cd9c;
|
||||
/// border-top-color: #a60b55;
|
||||
/// }
|
||||
///
|
||||
/// @require {mixin} directional-property
|
||||
///
|
||||
/// @output `border-color`
|
||||
|
||||
@mixin border-color($vals...) {
|
||||
@include directional-property(border, color, $vals...);
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for targeting `border-radius` on both corners on the side of a box.
|
||||
///
|
||||
/// @param {Number} $radii
|
||||
/// List of arguments
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element-one {
|
||||
/// @include border-top-radius(5px);
|
||||
/// }
|
||||
///
|
||||
/// .element-two {
|
||||
/// @include border-left-radius(3px);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element-one {
|
||||
/// border-top-left-radius: 5px;
|
||||
/// border-top-right-radius: 5px;
|
||||
/// }
|
||||
///
|
||||
/// .element-two {
|
||||
/// border-bottom-left-radius: 3px;
|
||||
/// border-top-left-radius: 3px;
|
||||
/// }
|
||||
///
|
||||
/// @output `border-radius`
|
||||
|
||||
@mixin border-top-radius($radii) {
|
||||
border-top-left-radius: $radii;
|
||||
border-top-right-radius: $radii;
|
||||
}
|
||||
|
||||
@mixin border-right-radius($radii) {
|
||||
border-bottom-right-radius: $radii;
|
||||
border-top-right-radius: $radii;
|
||||
}
|
||||
|
||||
@mixin border-bottom-radius($radii) {
|
||||
border-bottom-left-radius: $radii;
|
||||
border-bottom-right-radius: $radii;
|
||||
}
|
||||
|
||||
@mixin border-left-radius($radii) {
|
||||
border-bottom-left-radius: $radii;
|
||||
border-top-left-radius: $radii;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for targeting `border-style` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||
///
|
||||
/// @param {Arglist} $vals
|
||||
/// List of arguments
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include border-style(dashed null solid);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// border-bottom-style: solid;
|
||||
/// border-top-style: dashed;
|
||||
/// }
|
||||
///
|
||||
/// @require {mixin} directional-property
|
||||
///
|
||||
/// @output `border-style`
|
||||
|
||||
@mixin border-style($vals...) {
|
||||
@include directional-property(border, style, $vals...);
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for targeting `border-width` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||
///
|
||||
/// @param {Arglist} $vals
|
||||
/// List of arguments
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include border-width(1em null 20px);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// border-bottom-width: 20px;
|
||||
/// border-top-width: 1em;
|
||||
/// }
|
||||
///
|
||||
/// @require {mixin} directional-property
|
||||
///
|
||||
/// @output `border-width`
|
||||
|
||||
@mixin border-width($vals...) {
|
||||
@include directional-property(border, width, $vals...);
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Generates variables for all buttons. Please note that you must use interpolation on the variable: `#{$all-buttons}`.
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// #{$all-buttons} {
|
||||
/// background-color: #f00;
|
||||
/// }
|
||||
///
|
||||
/// #{$all-buttons-focus},
|
||||
/// #{$all-buttons-hover} {
|
||||
/// background-color: #0f0;
|
||||
/// }
|
||||
///
|
||||
/// #{$all-buttons-active} {
|
||||
/// background-color: #00f;
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// button,
|
||||
/// input[type="button"],
|
||||
/// input[type="reset"],
|
||||
/// input[type="submit"] {
|
||||
/// background-color: #f00;
|
||||
/// }
|
||||
///
|
||||
/// button:focus,
|
||||
/// input[type="button"]:focus,
|
||||
/// input[type="reset"]:focus,
|
||||
/// input[type="submit"]:focus,
|
||||
/// button:hover,
|
||||
/// input[type="button"]:hover,
|
||||
/// input[type="reset"]:hover,
|
||||
/// input[type="submit"]:hover {
|
||||
/// background-color: #0f0;
|
||||
/// }
|
||||
///
|
||||
/// button:active,
|
||||
/// input[type="button"]:active,
|
||||
/// input[type="reset"]:active,
|
||||
/// input[type="submit"]:active {
|
||||
/// background-color: #00f;
|
||||
/// }
|
||||
///
|
||||
/// @require assign-inputs
|
||||
///
|
||||
/// @type List
|
||||
///
|
||||
/// @todo Remove double assigned variables (Lines 59–62) in v5.0.0
|
||||
|
||||
$buttons-list: 'button',
|
||||
'input[type="button"]',
|
||||
'input[type="reset"]',
|
||||
'input[type="submit"]';
|
||||
|
||||
$all-buttons: assign-inputs($buttons-list);
|
||||
$all-buttons-active: assign-inputs($buttons-list, active);
|
||||
$all-buttons-focus: assign-inputs($buttons-list, focus);
|
||||
$all-buttons-hover: assign-inputs($buttons-list, hover);
|
||||
|
||||
$all-button-inputs: $all-buttons;
|
||||
$all-button-inputs-active: $all-buttons-active;
|
||||
$all-button-inputs-focus: $all-buttons-focus;
|
||||
$all-button-inputs-hover: $all-buttons-hover;
|
@@ -1,25 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides an easy way to include a clearfix for containing floats.
|
||||
///
|
||||
/// @link http://cssmojo.com/latest_new_clearfix_so_far/
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include clearfix;
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element::after {
|
||||
/// clear: both;
|
||||
/// content: "";
|
||||
/// display: table;
|
||||
/// }
|
||||
|
||||
@mixin clearfix {
|
||||
&::after {
|
||||
clear: both;
|
||||
content: "";
|
||||
display: table;
|
||||
}
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Truncates text and adds an ellipsis to represent overflow.
|
||||
///
|
||||
/// @param {Number} $width [100%]
|
||||
/// Max-width for the string to respect before being truncated
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include ellipsis;
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// display: inline-block;
|
||||
/// max-width: 100%;
|
||||
/// overflow: hidden;
|
||||
/// text-overflow: ellipsis;
|
||||
/// white-space: nowrap;
|
||||
/// word-wrap: normal;
|
||||
/// }
|
||||
|
||||
@mixin ellipsis($width: 100%) {
|
||||
display: inline-block;
|
||||
max-width: $width;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Georgia font stack.
|
||||
///
|
||||
/// @type List
|
||||
|
||||
$georgia: "Georgia", "Cambria", "Times New Roman", "Times", serif;
|
||||
|
||||
/// Helvetica font stack.
|
||||
///
|
||||
/// @type List
|
||||
|
||||
$helvetica: "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
|
||||
|
||||
/// Lucida Grande font stack.
|
||||
///
|
||||
/// @type List
|
||||
|
||||
$lucida-grande: "Lucida Grande", "Tahoma", "Verdana", "Arial", sans-serif;
|
||||
|
||||
/// Monospace font stack.
|
||||
///
|
||||
/// @type List
|
||||
|
||||
$monospace: "Bitstream Vera Sans Mono", "Consolas", "Courier", monospace;
|
||||
|
||||
/// Verdana font stack.
|
||||
///
|
||||
/// @type List
|
||||
|
||||
$verdana: "Verdana", "Geneva", sans-serif;
|
@@ -1,27 +0,0 @@
|
||||
/// Hides the text in an element, commonly used to show an image. Some elements will need block-level styles applied.
|
||||
///
|
||||
/// @link http://zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include hide-text;
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// overflow: hidden;
|
||||
/// text-indent: 101%;
|
||||
/// white-space: nowrap;
|
||||
/// }
|
||||
///
|
||||
/// @todo Remove height argument in v5.0.0
|
||||
|
||||
@mixin hide-text($height: null) {
|
||||
overflow: hidden;
|
||||
text-indent: 101%;
|
||||
white-space: nowrap;
|
||||
|
||||
@if $height {
|
||||
@warn "The `hide-text` mixin has changed and no longer requires a height. The height argument will no longer be accepted in v5.0.0";
|
||||
}
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for targeting `margin` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||
///
|
||||
/// @param {Arglist} $vals
|
||||
/// List of arguments
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include margin(null 10px 3em 20vh);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// margin-bottom: 3em;
|
||||
/// margin-left: 20vh;
|
||||
/// margin-right: 10px;
|
||||
/// }
|
||||
///
|
||||
/// @require {mixin} directional-property
|
||||
///
|
||||
/// @output `margin`
|
||||
|
||||
@mixin margin($vals...) {
|
||||
@include directional-property(margin, false, $vals...);
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for targeting `padding` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||
///
|
||||
/// @param {Arglist} $vals
|
||||
/// List of arguments
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include padding(12vh null 10px 5%);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// padding-bottom: 10px;
|
||||
/// padding-left: 5%;
|
||||
/// padding-top: 12vh;
|
||||
/// }
|
||||
///
|
||||
/// @require {mixin} directional-property
|
||||
///
|
||||
/// @output `padding`
|
||||
|
||||
@mixin padding($vals...) {
|
||||
@include directional-property(padding, false, $vals...);
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides a quick method for setting an element’s position. Use a `null` value to “skip” a side.
|
||||
///
|
||||
/// @param {Position} $position [relative]
|
||||
/// A CSS position value
|
||||
///
|
||||
/// @param {Arglist} $coordinates [null null null null]
|
||||
/// List of values that correspond to the 4-value syntax for the edges of a box
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include position(absolute, 0 null null 10em);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// left: 10em;
|
||||
/// position: absolute;
|
||||
/// top: 0;
|
||||
/// }
|
||||
///
|
||||
/// @require {function} is-length
|
||||
/// @require {function} unpack
|
||||
|
||||
@mixin position($position: relative, $coordinates: null null null null) {
|
||||
@if type-of($position) == list {
|
||||
$coordinates: $position;
|
||||
$position: relative;
|
||||
}
|
||||
|
||||
$coordinates: unpack($coordinates);
|
||||
|
||||
$offsets: (
|
||||
top: nth($coordinates, 1),
|
||||
right: nth($coordinates, 2),
|
||||
bottom: nth($coordinates, 3),
|
||||
left: nth($coordinates, 4)
|
||||
);
|
||||
|
||||
position: $position;
|
||||
|
||||
@each $offset, $value in $offsets {
|
||||
@if is-length($value) {
|
||||
#{$offset}: $value;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,66 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// A mixin for generating vendor prefixes on non-standardized properties.
|
||||
///
|
||||
/// @param {String} $property
|
||||
/// Property to prefix
|
||||
///
|
||||
/// @param {*} $value
|
||||
/// Value to use
|
||||
///
|
||||
/// @param {List} $prefixes
|
||||
/// Prefixes to define
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .element {
|
||||
/// @include prefixer(border-radius, 10px, webkit ms spec);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .element {
|
||||
/// -webkit-border-radius: 10px;
|
||||
/// -moz-border-radius: 10px;
|
||||
/// border-radius: 10px;
|
||||
/// }
|
||||
///
|
||||
/// @require {variable} $prefix-for-webkit
|
||||
/// @require {variable} $prefix-for-mozilla
|
||||
/// @require {variable} $prefix-for-microsoft
|
||||
/// @require {variable} $prefix-for-opera
|
||||
/// @require {variable} $prefix-for-spec
|
||||
|
||||
@mixin prefixer($property, $value, $prefixes) {
|
||||
@each $prefix in $prefixes {
|
||||
@if $prefix == webkit {
|
||||
@if $prefix-for-webkit {
|
||||
-webkit-#{$property}: $value;
|
||||
}
|
||||
} @else if $prefix == moz {
|
||||
@if $prefix-for-mozilla {
|
||||
-moz-#{$property}: $value;
|
||||
}
|
||||
} @else if $prefix == ms {
|
||||
@if $prefix-for-microsoft {
|
||||
-ms-#{$property}: $value;
|
||||
}
|
||||
} @else if $prefix == o {
|
||||
@if $prefix-for-opera {
|
||||
-o-#{$property}: $value;
|
||||
}
|
||||
} @else if $prefix == spec {
|
||||
@if $prefix-for-spec {
|
||||
#{$property}: $value;
|
||||
}
|
||||
} @else {
|
||||
@warn "Unrecognized prefix: #{$prefix}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin disable-prefix-for-all() {
|
||||
$prefix-for-webkit: false !global;
|
||||
$prefix-for-mozilla: false !global;
|
||||
$prefix-for-microsoft: false !global;
|
||||
$prefix-for-opera: false !global;
|
||||
$prefix-for-spec: false !global;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
@mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $retina-suffix: _2x, $asset-pipeline: $asset-pipeline) {
|
||||
@if $asset-pipeline {
|
||||
background-image: image-url("#{$filename}.#{$extension}");
|
||||
} @else {
|
||||
background-image: url("#{$filename}.#{$extension}");
|
||||
}
|
||||
|
||||
@include hidpi {
|
||||
@if $asset-pipeline {
|
||||
@if $retina-filename {
|
||||
background-image: image-url("#{$retina-filename}.#{$extension}");
|
||||
} @else {
|
||||
background-image: image-url("#{$filename}#{$retina-suffix}.#{$extension}");
|
||||
}
|
||||
} @else {
|
||||
@if $retina-filename {
|
||||
background-image: url("#{$retina-filename}.#{$extension}");
|
||||
} @else {
|
||||
background-image: url("#{$filename}#{$retina-suffix}.#{$extension}");
|
||||
}
|
||||
}
|
||||
|
||||
background-size: $background-size;
|
||||
}
|
||||
}
|
@@ -1,51 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Sets the `width` and `height` of the element.
|
||||
///
|
||||
/// @param {List} $size
|
||||
/// A list of at most 2 size values.
|
||||
///
|
||||
/// If there is only a single value in `$size` it is used for both width and height. All units are supported.
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .first-element {
|
||||
/// @include size(2em);
|
||||
/// }
|
||||
///
|
||||
/// .second-element {
|
||||
/// @include size(auto 10em);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .first-element {
|
||||
/// width: 2em;
|
||||
/// height: 2em;
|
||||
/// }
|
||||
///
|
||||
/// .second-element {
|
||||
/// width: auto;
|
||||
/// height: 10em;
|
||||
/// }
|
||||
///
|
||||
/// @todo Refactor in 5.0.0 to use a comma-separated argument
|
||||
|
||||
@mixin size($value) {
|
||||
$width: nth($value, 1);
|
||||
$height: $width;
|
||||
|
||||
@if length($value) > 1 {
|
||||
$height: nth($value, 2);
|
||||
}
|
||||
|
||||
@if is-size($height) {
|
||||
height: $height;
|
||||
} @else {
|
||||
@warn "`#{$height}` is not a valid length for the `$height` parameter in the `size` mixin.";
|
||||
}
|
||||
|
||||
@if is-size($width) {
|
||||
width: $width;
|
||||
} @else {
|
||||
@warn "`#{$width}` is not a valid length for the `$width` parameter in the `size` mixin.";
|
||||
}
|
||||
}
|
@@ -1,113 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Generates variables for all text-based inputs. Please note that you must use interpolation on the variable: `#{$all-text-inputs}`.
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// #{$all-text-inputs} {
|
||||
/// border: 1px solid #f00;
|
||||
/// }
|
||||
///
|
||||
/// #{$all-text-inputs-focus},
|
||||
/// #{$all-text-inputs-hover} {
|
||||
/// border: 1px solid #0f0;
|
||||
/// }
|
||||
///
|
||||
/// #{$all-text-inputs-active} {
|
||||
/// border: 1px solid #00f;
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// input[type="color"],
|
||||
/// input[type="date"],
|
||||
/// input[type="datetime"],
|
||||
/// input[type="datetime-local"],
|
||||
/// input[type="email"],
|
||||
/// input[type="month"],
|
||||
/// input[type="number"],
|
||||
/// input[type="password"],
|
||||
/// input[type="search"],
|
||||
/// input[type="tel"],
|
||||
/// input[type="text"],
|
||||
/// input[type="time"],
|
||||
/// input[type="url"],
|
||||
/// input[type="week"],
|
||||
/// textarea {
|
||||
/// border: 1px solid #f00;
|
||||
/// }
|
||||
///
|
||||
/// input[type="color"]:focus,
|
||||
/// input[type="date"]:focus,
|
||||
/// input[type="datetime"]:focus,
|
||||
/// input[type="datetime-local"]:focus,
|
||||
/// input[type="email"]:focus,
|
||||
/// input[type="month"]:focus,
|
||||
/// input[type="number"]:focus,
|
||||
/// input[type="password"]:focus,
|
||||
/// input[type="search"]:focus,
|
||||
/// input[type="tel"]:focus,
|
||||
/// input[type="text"]:focus,
|
||||
/// input[type="time"]:focus,
|
||||
/// input[type="url"]:focus,
|
||||
/// input[type="week"]:focus,
|
||||
/// textarea:focus,
|
||||
/// input[type="color"]:hover,
|
||||
/// input[type="date"]:hover,
|
||||
/// input[type="datetime"]:hover,
|
||||
/// input[type="datetime-local"]:hover,
|
||||
/// input[type="email"]:hover,
|
||||
/// input[type="month"]:hover,
|
||||
/// input[type="number"]:hover,
|
||||
/// input[type="password"]:hover,
|
||||
/// input[type="search"]:hover,
|
||||
/// input[type="tel"]:hover,
|
||||
/// input[type="text"]:hover,
|
||||
/// input[type="time"]:hover,
|
||||
/// input[type="url"]:hover,
|
||||
/// input[type="week"]:hover,
|
||||
/// textarea:hover {
|
||||
/// border: 1px solid #0f0;
|
||||
/// }
|
||||
///
|
||||
/// input[type="color"]:active,
|
||||
/// input[type="date"]:active,
|
||||
/// input[type="datetime"]:active,
|
||||
/// input[type="datetime-local"]:active,
|
||||
/// input[type="email"]:active,
|
||||
/// input[type="month"]:active,
|
||||
/// input[type="number"]:active,
|
||||
/// input[type="password"]:active,
|
||||
/// input[type="search"]:active,
|
||||
/// input[type="tel"]:active,
|
||||
/// input[type="text"]:active,
|
||||
/// input[type="time"]:active,
|
||||
/// input[type="url"]:active,
|
||||
/// input[type="week"]:active,
|
||||
/// textarea:active {
|
||||
/// border: 1px solid #00f;
|
||||
/// }
|
||||
///
|
||||
/// @require assign-inputs
|
||||
///
|
||||
/// @type List
|
||||
|
||||
$text-inputs-list: 'input[type="color"]',
|
||||
'input[type="date"]',
|
||||
'input[type="datetime"]',
|
||||
'input[type="datetime-local"]',
|
||||
'input[type="email"]',
|
||||
'input[type="month"]',
|
||||
'input[type="number"]',
|
||||
'input[type="password"]',
|
||||
'input[type="search"]',
|
||||
'input[type="tel"]',
|
||||
'input[type="text"]',
|
||||
'input[type="time"]',
|
||||
'input[type="url"]',
|
||||
'input[type="week"]',
|
||||
'input:not([type])',
|
||||
'textarea';
|
||||
|
||||
$all-text-inputs: assign-inputs($text-inputs-list);
|
||||
$all-text-inputs-active: assign-inputs($text-inputs-list, active);
|
||||
$all-text-inputs-focus: assign-inputs($text-inputs-list, focus);
|
||||
$all-text-inputs-hover: assign-inputs($text-inputs-list, hover);
|
@@ -1,34 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie)
|
||||
///
|
||||
/// Timing functions are the same as demoed here: http://jqueryui.com/resources/demos/effect/easing.html
|
||||
///
|
||||
/// @type cubic-bezier
|
||||
|
||||
$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
|
||||
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
|
||||
$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
|
||||
$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
|
||||
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
|
||||
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
|
||||
$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
||||
|
||||
$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
|
||||
$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||
$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
|
||||
$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
|
||||
$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
|
||||
$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
|
||||
$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
|
||||
$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
||||
|
||||
$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
|
||||
$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||
$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
||||
$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
|
||||
$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
|
||||
$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
|
||||
$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
|
||||
$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);
|
@@ -1,63 +0,0 @@
|
||||
@mixin triangle($size, $color, $direction) {
|
||||
$width: nth($size, 1);
|
||||
$height: nth($size, length($size));
|
||||
$foreground-color: nth($color, 1);
|
||||
$background-color: if(length($color) == 2, nth($color, 2), transparent);
|
||||
height: 0;
|
||||
width: 0;
|
||||
|
||||
@if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) {
|
||||
$width: $width / 2;
|
||||
$height: if(length($size) > 1, $height, $height/2);
|
||||
|
||||
@if $direction == up {
|
||||
border-bottom: $height solid $foreground-color;
|
||||
border-left: $width solid $background-color;
|
||||
border-right: $width solid $background-color;
|
||||
} @else if $direction == right {
|
||||
border-bottom: $width solid $background-color;
|
||||
border-left: $height solid $foreground-color;
|
||||
border-top: $width solid $background-color;
|
||||
} @else if $direction == down {
|
||||
border-left: $width solid $background-color;
|
||||
border-right: $width solid $background-color;
|
||||
border-top: $height solid $foreground-color;
|
||||
} @else if $direction == left {
|
||||
border-bottom: $width solid $background-color;
|
||||
border-right: $height solid $foreground-color;
|
||||
border-top: $width solid $background-color;
|
||||
}
|
||||
} @else if ($direction == up-right) or ($direction == up-left) {
|
||||
border-top: $height solid $foreground-color;
|
||||
|
||||
@if $direction == up-right {
|
||||
border-left: $width solid $background-color;
|
||||
} @else if $direction == up-left {
|
||||
border-right: $width solid $background-color;
|
||||
}
|
||||
} @else if ($direction == down-right) or ($direction == down-left) {
|
||||
border-bottom: $height solid $foreground-color;
|
||||
|
||||
@if $direction == down-right {
|
||||
border-left: $width solid $background-color;
|
||||
} @else if $direction == down-left {
|
||||
border-right: $width solid $background-color;
|
||||
}
|
||||
} @else if ($direction == inset-up) {
|
||||
border-color: $background-color $background-color $foreground-color;
|
||||
border-style: solid;
|
||||
border-width: $height $width;
|
||||
} @else if ($direction == inset-down) {
|
||||
border-color: $foreground-color $background-color $background-color;
|
||||
border-style: solid;
|
||||
border-width: $height $width;
|
||||
} @else if ($direction == inset-right) {
|
||||
border-color: $background-color $background-color $background-color $foreground-color;
|
||||
border-style: solid;
|
||||
border-width: $width $height;
|
||||
} @else if ($direction == inset-left) {
|
||||
border-color: $background-color $foreground-color $background-color $background-color;
|
||||
border-style: solid;
|
||||
border-width: $width $height;
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/// Provides an easy way to change the `word-wrap` property.
|
||||
///
|
||||
/// @param {String} $wrap [break-word]
|
||||
/// Value for the `word-break` property.
|
||||
///
|
||||
/// @example scss - Usage
|
||||
/// .wrapper {
|
||||
/// @include word-wrap(break-word);
|
||||
/// }
|
||||
///
|
||||
/// @example css - CSS Output
|
||||
/// .wrapper {
|
||||
/// overflow-wrap: break-word;
|
||||
/// word-break: break-all;
|
||||
/// word-wrap: break-word;
|
||||
/// }
|
||||
|
||||
@mixin word-wrap($wrap: break-word) {
|
||||
overflow-wrap: $wrap;
|
||||
word-wrap: $wrap;
|
||||
|
||||
@if $wrap == break-word {
|
||||
word-break: break-all;
|
||||
} @else {
|
||||
word-break: $wrap;
|
||||
}
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
// http://www.w3.org/TR/css3-animations/#the-animation-name-property-
|
||||
// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
|
||||
|
||||
@mixin animation($animations...) {
|
||||
@include prefixer(animation, $animations, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-name($names...) {
|
||||
@include prefixer(animation-name, $names, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-duration($times...) {
|
||||
@include prefixer(animation-duration, $times, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-timing-function($motions...) {
|
||||
// ease | linear | ease-in | ease-out | ease-in-out
|
||||
@include prefixer(animation-timing-function, $motions, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-iteration-count($values...) {
|
||||
// infinite | <number>
|
||||
@include prefixer(animation-iteration-count, $values, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-direction($directions...) {
|
||||
// normal | alternate
|
||||
@include prefixer(animation-direction, $directions, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-play-state($states...) {
|
||||
// running | paused
|
||||
@include prefixer(animation-play-state, $states, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-delay($times...) {
|
||||
@include prefixer(animation-delay, $times, webkit moz spec);
|
||||
}
|
||||
|
||||
@mixin animation-fill-mode($modes...) {
|
||||
// none | forwards | backwards | both
|
||||
@include prefixer(animation-fill-mode, $modes, webkit moz spec);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user