Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"license": "OSL-3.0",
"require": {
"php": ">=8.4",
"forumify/forumify-platform": "^1.2",
"forumify/forumify-platform": "^1.2.x-dev",
"league/commonmark": "^2.5"
},
"require-dev": {
Expand Down
81 changes: 81 additions & 0 deletions src/Components/SubmissionStatusForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace Forumify\Milhq\Components;

use Forumify\Core\Form\EntityType;
use Forumify\Core\Security\VoterAttribute;
use Forumify\Milhq\Admin\Service\SubmissionStatusUpdateService;
use Forumify\Milhq\Entity\FormSubmission;
use Forumify\Milhq\Entity\Status;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormInterface;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveAction;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\ComponentToolsTrait;
use Symfony\UX\LiveComponent\ComponentWithFormTrait;
use Symfony\UX\LiveComponent\DefaultActionTrait;

#[AsLiveComponent('Milhq\\SubmissionStatusForm', '@ForumifyMilhqPlugin/frontend/components/submission_status_form.html.twig')]
class SubmissionStatusForm extends AbstractController
{
use DefaultActionTrait;
use ComponentWithFormTrait;
use ComponentToolsTrait;

#[LiveProp]
public FormSubmission $submission;

public bool $success = false;

public function __construct(
private readonly SubmissionStatusUpdateService $submissionStatusUpdateService,
) {
}

protected function instantiateForm(): FormInterface
{
return $this->createFormBuilder()
->add('status', EntityType::class, [
'choice_label' => 'name',
'class' => Status::class,
])
->add('reason', TextareaType::class, [
'empty_data' => '',
'required' => false,
])
->getForm()
;
}

// @phpstan-ignore-next-line
private function getDataModelValue(): ?string
{
return 'norender|*';
}

#[LiveAction]
public function save(): void
{
if (!$this->isGranted(VoterAttribute::ACL->value, [
'permission' => 'supervisor_manage_submissions',
'entity' => $this->submission->getForm(),
])) {
return;
}

$this->submitForm();

$statusRecord = $this->getForm()->getData();
$statusRecord['sendNotification'] = true;
$this->submissionStatusUpdateService->createStatusRecord($this->submission, $statusRecord);

$this->success = true;
$this->resetForm();

$this->emitUp('milhq:submission:status_updated');
}
}
61 changes: 61 additions & 0 deletions src/Components/SupervisorSubmissionList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace Forumify\Milhq\Components;

use Doctrine\ORM\QueryBuilder;
use Forumify\Core\Component\List\AbstractDoctrineList;
use Forumify\Milhq\Entity\FormSubmission;
use Forumify\Milhq\Repository\FormRepository;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveListener;
use Symfony\UX\LiveComponent\Attribute\LiveProp;

#[AsLiveComponent('Milhq\\SupervisorSubmissionList', '@ForumifyMilhqPlugin/frontend/components/supervisor_submission_list.html.twig')]
class SupervisorSubmissionList extends AbstractDoctrineList
{
#[LiveProp]
public int $soldierId;

/** @var array<int> */
#[LiveProp]
public array $supervisedUnits;

public function __construct(
private readonly FormRepository $formRepository,
) {
}

protected function getEntityClass(): string
{
return FormSubmission::class;
}

protected function getQuery(): QueryBuilder
{
$qb = parent::getQuery();
if (empty($this->supervisedUnits)) {
return $qb->andWhere('1 = 0');
}

$qb
->join('e.soldier', 's')
->join('s.unit', 'u')
->join('e.form', 'f')
->andWhere('s.id != :self')
->andWhere('u.id IN (:units)')
->orderBy('e.createdAt', 'DESC')
->setParameter('units', $this->supervisedUnits)
->setParameter('self', $this->soldierId)
;
$this->formRepository->addACLToQuery($qb, 'supervisor_manage_submissions', FormSubmission::class, 'f');
return $qb;
}

#[LiveListener('milhq:submission:status_updated')]
public function refresh(): void
{
// no-op, re-rendering the component is enough to refresh the list with the current pagination
}
}
3 changes: 3 additions & 0 deletions src/Controller/OperationsCenterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Forumify\Core\Repository\SettingRepository;
use Forumify\Milhq\Repository\FormRepository;
use Forumify\Milhq\Repository\UnitRepository;
use Forumify\Milhq\Service\SoldierService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -19,6 +20,7 @@ public function __construct(
private readonly SoldierService $soldierService,
private readonly SettingRepository $settingRepository,
private readonly FormRepository $formRepository,
private readonly UnitRepository $unitRepository,
) {
}

Expand All @@ -41,6 +43,7 @@ public function __invoke(): Response
'forms' => $this->formRepository->findAllSubmissionsAllowed(),
'soldier' => $soldier,
'milsimUnitsId' => $this->getMilsimUnitsId(),
'supervisedUnits' => $this->unitRepository->findBySoldierIsSupervisor($soldier),
]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Entity/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public function removeField(FormField $field): void

public function getACLPermissions(): array
{
return ['create_submissions', 'view_submissions', 'manage_submissions'];
return ['create_submissions', 'view_submissions', 'manage_submissions', 'supervisor_manage_submissions'];
}

public function getACLParameters(): ACLParameters
Expand Down
14 changes: 14 additions & 0 deletions src/Repository/UnitRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Forumify\Milhq\Repository;

use Forumify\Core\Repository\AbstractRepository;
use Forumify\Milhq\Entity\Soldier;
use Forumify\Milhq\Entity\Unit;

/**
Expand All @@ -16,4 +17,17 @@ public static function getEntityClass(): string
{
return Unit::class;
}

public function findBySoldierIsSupervisor(Soldier|int $soldier): array
{
$soldierId = $soldier instanceof Soldier ? $soldier->getId() : $soldier;

return $this->createQueryBuilder('e')
->innerJoin('e.supervisors', 'supervisor')
->innerJoin(Soldier::class, 'soldier', 'WITH', 'soldier.position = supervisor AND soldier.unit = e')
->where('soldier.id = :soldierId')
->setParameter('soldierId', $soldierId)
->getQuery()
->getResult();
}
}
16 changes: 16 additions & 0 deletions templates/frontend/components/submission_status_form.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div {{ attributes }}>
{{ form_start(form, {
attr: {
'data-action': 'live#action:prevent',
'data-live-action-param': 'save',
}
}) }}
{{ form_row(form.status) }}
{{ form_row(form.reason) }}
<div class="flex justify-center">
<button class="btn-primary">
{{ 'save'|trans }}
</button>
</div>
{{ form_end(form) }}
</div>
48 changes: 48 additions & 0 deletions templates/frontend/components/supervisor_submission_list.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{% extends '@Forumify/components/list.html.twig' %}
{% block row %}
<li class="mb-2 flex items-center justify-between">
<div>
{% embed '@Forumify/components/modal.html.twig' %}
{% block modalOpenButton %}
<a>{{ item.soldier.name }} - {{ item.form.name }}</a>
{% endblock %}
{% block modalContent %}
<div class="box">
<div>
<h2>{{ item.form.name }}</h2>
{% include '@ForumifyMilhqPlugin/components/submission.html.twig' with {
submission: item
} %}
</div>
{% if item.status %}
<h3 class="mt-4">Status</h3>
<div>
{% include '@ForumifyMilhqPlugin/frontend/roster/components/status.html.twig' with {
status: item.status,
class: 'text-small'
} only %}
</div>
{% endif %}
{% if item.statusReason %}
<h3 class="mt-4">Reason</h3>
<p>{{ item.statusReason }}</p>
{% endif %}
<div class="mt-4">
{{ component('Milhq\\SubmissionStatusForm', { submission: item }) }}
</div>
</div>
{% endblock %}
{% endembed %}
<p class="text-small">{{ item.createdAt|format_date }}</p>
</div>
{% if item.status %}
{% include '@ForumifyMilhqPlugin/frontend/roster/components/status.html.twig' with {
status: item.status,
class: 'text-small'
} only %}
{% endif %}
</li>
{% endblock %}
{% block empty %}
{{ 'table.no_entries'|trans }}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
{% endblock %}
{% embed '@Forumify/components/tabs.html.twig' %}
{% block tabs %}
<button class="btn-link" data-tab-id="submissions">{{ 'milhq.opcenter.submissions'|trans }}</button>
<button class="btn-link" data-tab-id="dashboard">{{ 'milhq.opcenter.dashboard'|trans }}</button>
{% if plugin_version('forumify/forumify-milhq-plugin', 'premium') %}
<button class="btn-link" data-tab-id="operations">{{ 'milhq.opcenter.operations'|trans }}</button>
{% if is_granted('milhq.frontend.attendance_sheet.view') %}
Expand All @@ -48,7 +48,7 @@
{% endif %}
{% endblock %}
{% block tabpanels %}
{% include '@ForumifyMilhqPlugin/frontend/operations_center/tabs/submissions.html.twig' %}
{% include '@ForumifyMilhqPlugin/frontend/operations_center/tabs/dashboard.html.twig' %}
{% if plugin_version('forumify/forumify-milhq-plugin', 'premium') %}
{% include '@ForumifyMilhqPlugin/frontend/operations_center/tabs/operations.html.twig' %}
{% if is_granted('milhq.frontend.attendance_sheet.view') %}
Expand Down
46 changes: 46 additions & 0 deletions templates/frontend/operations_center/tabs/dashboard.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<div id="dashboard" class="grid-12 gap-4">
<div class="col-xs-12 col-md-7">
{% if supervisedUnits is not empty %}
{% embed '@Forumify/components/tabs.html.twig' %}
{% block tabs %}
<button class="btn-link" data-tab-id="submissions">{{ 'milhq.opcenter.submissions'|trans }}</button>
<button class="btn-link" data-tab-id="unit-submissions">{{ 'milhq.opcenter.unit_submissions'|trans }}</button>
{% endblock %}
{% block tabpanels %}
<div id="submissions">
{{ component('Milhq\\SubmissionList', { soldierId: soldier.id }) }}
</div>
<div id="unit-submissions">
{{ component('Milhq\\SupervisorSubmissionList', {
soldierId: soldier.id,
supervisedUnits: supervisedUnits|map(u => u.id),
}) }}
</div>
{% endblock %}
{% endembed %}
{% else %}
{{ component('Milhq\\SubmissionList', { soldierId: soldier.id }) }}
{% endif %}
</div>
<div class="col-xs-12 col-md-5 flex flex-col gap-2">
{% if milsimUnitsId is not empty %}
<div class="mb-2 w-100">
<iframe
height="60"
width="100%"
src="https://milsimunits.com/embed/{{ milsimUnitsId }}"
frameborder="0"
></iframe>
</div>
{% endif %}
{% if plugin_version('forumify/forumify-milhq-plugin', 'premium') and setting('milhq.report_in.enabled') %}
{{ component('Milhq\\ReportInButton') }}
{% endif %}
{% for form in forms %}
<a href="{{ path('milhq_form_submission_create', { id: form.id }) }}" class="btn-outlined w-100 justify-start">
<i class="ph ph-arrow-elbow-down-right"></i>
{{ form.name }}
</a>
{% endfor %}
</div>
</div>
26 changes: 0 additions & 26 deletions templates/frontend/operations_center/tabs/submissions.html.twig

This file was deleted.

1 change: 1 addition & 0 deletions tests/PluginTestKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function registerBundles(): iterable
new \Zenstruck\Foundry\ZenstruckFoundryBundle(),
new \Forumify\Milhq\ForumifyMilhqPlugin(),
new \ApiPlatform\Symfony\Bundle\ApiPlatformBundle(),
new \Liip\ImagineBundle\LiipImagineBundle(),
];

if (class_exists(\Forumify\Calendar\ForumifyCalendarPlugin::class)) {
Expand Down
Loading
Loading