Merge pull request #3425 from alchemy-fr/PHRAS-3006_Port41_Front_delete_3_by_3

PHRAS-3006 #comment merge Port to 41 :  front delete 3 by 3
This commit is contained in:
Nicolas Maillat
2020-04-06 10:48:31 +02:00
committed by GitHub
10 changed files with 726 additions and 617 deletions

View File

@@ -7,6 +7,7 @@
* For the full copyright and license information, please view the LICENSE * For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Alchemy\Phrasea\Controller\Prod; namespace Alchemy\Phrasea\Controller\Prod;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
@@ -24,6 +25,7 @@ use Alchemy\Phrasea\Model\Repositories\StoryWZRepository;
use Alchemy\Phrasea\SearchEngine\SearchEngineOptions; use Alchemy\Phrasea\SearchEngine\SearchEngineOptions;
use Alchemy\Phrasea\Twig\Fit; use Alchemy\Phrasea\Twig\Fit;
use Alchemy\Phrasea\Twig\PhraseanetExtension; use Alchemy\Phrasea\Twig\PhraseanetExtension;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
@@ -36,7 +38,7 @@ class RecordController extends Controller
* *
* @param Request $request * @param Request $request
* *
* @return Response * @return \Symfony\Component\HttpFoundation\JsonResponse
*/ */
public function getRecord(Request $request) public function getRecord(Request $request)
{ {
@@ -194,7 +196,8 @@ class RecordController extends Controller
$flatten = (bool)($request->request->get('del_children')) ? RecordsRequest::FLATTEN_YES_PRESERVE_STORIES : RecordsRequest::FLATTEN_NO; $flatten = (bool)($request->request->get('del_children')) ? RecordsRequest::FLATTEN_YES_PRESERVE_STORIES : RecordsRequest::FLATTEN_NO;
$records = RecordsRequest::fromRequest( $records = RecordsRequest::fromRequest(
$this->app, $this->app,
$request,$flatten, $request,
$flatten,
[\ACL::CANDELETERECORD] [\ACL::CANDELETERECORD]
); );
@@ -224,16 +227,16 @@ class RecordController extends Controller
$manager->remove($attachedStory); $manager->remove($attachedStory);
} }
foreach($record->get_grouping_parents() as $story) { foreach ($record->get_grouping_parents() as $story) {
$this->getEventDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story)); $this->getEventDispatcher()->dispatch(PhraseaEvents::RECORD_EDIT, new RecordEdit($story));
} }
$sbasId = $record->getDatabox()->get_sbas_id(); $sbasId = $record->getDatabox()->get_sbas_id();
if(!array_key_exists($sbasId, $trashCollectionsBySbasId)) { if (!array_key_exists($sbasId, $trashCollectionsBySbasId)) {
$trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection(); $trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection();
} }
$deleted[] = $record->getId(); $deleted[] = $record->getId();
if($trashCollectionsBySbasId[$sbasId] !== null) { if ($trashCollectionsBySbasId[$sbasId] !== null) {
if($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) { if($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
// record is already in trash so delete it // record is already in trash so delete it
$this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record)); $this->getEventDispatcher()->dispatch(RecordEvents::DELETE, new DeleteEvent($record));
@@ -280,35 +283,69 @@ class RecordController extends Controller
* Delete a record or a list of records * Delete a record or a list of records
* *
* @param Request $request * @param Request $request
* @return Response * @return string html
*/ */
public function whatCanIDelete(Request $request) public function whatCanIDelete(Request $request)
{ {
$viewParms = [];
// pre-count records that would be trashed/deleted when the "deleted children" will be un-checked
$records = RecordsRequest::fromRequest( $records = RecordsRequest::fromRequest(
$this->app, $this->app,
$request, $request,
!!$request->request->get('del_children'), RecordsRequest::FLATTEN_NO,
[\ACL::CANDELETERECORD] [\ACL::CANDELETERECORD]
); );
$filteredRecord = $this->filterRecordToDelete($records); $filteredRecords = $this->filterRecordToDelete($records);
return $this->app->json([ $viewParms['parents_only'] = [
'renderView' => $this->render('prod/actions/delete_records_confirm.html.twig', [ 'records' => $records,
'records' => $records, 'trashableCount' => count($filteredRecords['trash']),
'filteredRecord' => $filteredRecord 'deletableCount' => count($filteredRecords['delete'])
]), ];
'filteredRecord' => $filteredRecord
]); // pre-count records that would be trashed/deleted when the "deleted children" will be checked
//
$records = RecordsRequest::fromRequest(
$this->app,
$request,
RecordsRequest::FLATTEN_YES_PRESERVE_STORIES,
[\ACL::CANDELETERECORD]
);
$filteredRecords = $this->filterRecordToDelete($records);
$viewParms['with_children'] = [
'records' => $records,
'trashableCount' => count($filteredRecords['trash']),
'deletableCount' => count($filteredRecords['delete'])
];
return $this->render(
'prod/actions/delete_records_confirm.html.twig',
$viewParms
);
} }
/**
* classifies records in two groups (does NOT delete anything)
* - 'trash' : the record can go to trash because the db has a "_TRASH_" coll, and the record is not already into it
* - 'delete' : the record would be deleted because the db has no trash, or the record is already trashed
*
* @param RecordsRequest $records
* @return array
*/
private function filterRecordToDelete(RecordsRequest $records) private function filterRecordToDelete(RecordsRequest $records)
{ {
$ret = [
'trash' => [],
'delete' => []
];
$trashCollectionsBySbasId = []; $trashCollectionsBySbasId = [];
$goingToTrash = [];
$delete = [];
foreach ($records as $record) { foreach ($records as $record) {
/** @var \record_adapter $record */
$sbasId = $record->getDatabox()->get_sbas_id(); $sbasId = $record->getDatabox()->get_sbas_id();
if (!array_key_exists($sbasId, $trashCollectionsBySbasId)) { if (!array_key_exists($sbasId, $trashCollectionsBySbasId)) {
$trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection(); $trashCollectionsBySbasId[$sbasId] = $record->getDatabox()->getTrashCollection();
@@ -316,21 +353,20 @@ class RecordController extends Controller
if ($trashCollectionsBySbasId[$sbasId] !== null) { if ($trashCollectionsBySbasId[$sbasId] !== null) {
if ($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) { if ($record->getCollection()->get_coll_id() == $trashCollectionsBySbasId[$sbasId]->get_coll_id()) {
// record is already in trash // record is already in trash
$delete[] = $record; $ret['delete'][] = $record;
} }
else { else {
// will be moved to trash // will be moved to trash
$goingToTrash[] = $record; $ret['trash'][] = $record;
} }
} }
else { else {
// trash does not exist // trash does not exist
$delete[] = $record; $ret['delete'][] = $record;
} }
} }
//check if all values in array are true
//return (!in_array(false, $goingToTrash, true)); return $ret;
return ['trash' => $goingToTrash, 'delete' => $delete];
} }
/** /**
@@ -338,7 +374,8 @@ class RecordController extends Controller
* *
* @param Request $request * @param Request $request
* *
* @return Response * @return \Symfony\Component\HttpFoundation\JsonResponse
* @throws \Alchemy\Phrasea\Cache\Exception
*/ */
public function renewUrl(Request $request) public function renewUrl(Request $request)
{ {

View File

@@ -11,6 +11,7 @@
namespace Alchemy\Phrasea\Controller; namespace Alchemy\Phrasea\Controller;
use Alchemy\Phrasea\Model\Converter\BasketConverter;
use Alchemy\Phrasea\Model\Entities\Basket; use Alchemy\Phrasea\Model\Entities\Basket;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Alchemy\Phrasea\Application; use Alchemy\Phrasea\Application;
@@ -21,6 +22,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class RecordsRequest extends ArrayCollection class RecordsRequest extends ArrayCollection
{ {
protected $isSingleStory = false; protected $isSingleStory = false;
protected $rejected;
protected $received; protected $received;
protected $basket; protected $basket;
protected $databoxes; protected $databoxes;
@@ -31,30 +33,38 @@ class RecordsRequest extends ArrayCollection
const FLATTEN_YES_PRESERVE_STORIES = 'preserve'; const FLATTEN_YES_PRESERVE_STORIES = 'preserve';
/** /**
* Constructor * RecordsRequest Constructor
* *
* @param array $elements * @param array $elements
* @param ArrayCollection $rejected
* @param ArrayCollection $received * @param ArrayCollection $received
* @param Basket $basket * @param Basket|null $basket
* @param Boolean $flatten * @param Boolean $flatten
*/ */
public function __construct(array $elements, ArrayCollection $received, Basket $basket = null, $flatten = self::FLATTEN_NO) public function __construct(array $elements, ArrayCollection $rejected, ArrayCollection $received, Basket $basket = null, $flatten = self::FLATTEN_NO)
{ {
parent::__construct($elements); parent::__construct($elements);
$this->received = $received; $this->received = $received;
$this->rejected = $rejected;
$this->basket = $basket; $this->basket = $basket;
$this->isSingleStory = ($flatten !== self::FLATTEN_YES && 1 === count($this) && $this->first()->isStory()); $this->isSingleStory = ($flatten !== self::FLATTEN_YES && count($this) === 1 && $this->first()->isStory());
if (self::FLATTEN_NO !== $flatten) { if ($flatten !== self::FLATTEN_NO) {
$to_remove = []; $to_remove = [];
/** @var record_adapter $record */ /** @var record_adapter $record */
foreach ($this as $key => $record) { foreach ($this as $key => $record) {
if ($record->isStory()) { if ($record->isStory()) {
if (self::FLATTEN_YES === $flatten) { if ($flatten === self::FLATTEN_YES) {
// simple flatten : remove the story
$to_remove[] = $key; $to_remove[] = $key;
} }
foreach ($record->getChildren() as $child) {
$this->set($child->getId(), $child); try {
foreach ($record->getChildren() as $child) {
$this->set($child->getId(), $child);
}
} catch (\Exception $e) {
// getChildren will no fail since record IS a story
} }
} }
} }
@@ -106,7 +116,7 @@ class RecordsRequest extends ArrayCollection
/** @var \record_adapter $record */ /** @var \record_adapter $record */
foreach ($this as $record) { foreach ($this as $record) {
if (! isset($this->collections[$record->getBaseId()])) { if (! isset($this->collections[$record->getBaseId()])) {
$this->collections[$record->getBaseId()] = $record->get_collection(); $this->collections[$record->getBaseId()] = $record->getCollection();
} }
} }
@@ -126,6 +136,16 @@ class RecordsRequest extends ArrayCollection
return $this->received; return $this->received;
} }
/**
* Return all rejected records
*
* @return \record_adapter[]|ArrayCollection
*/
public function rejected()
{
return $this->rejected;
}
/** /**
* Return basket entity if provided, null otherwise * Return basket entity if provided, null otherwise
* *
@@ -201,15 +221,18 @@ class RecordsRequest extends ArrayCollection
* @param boolean $flattenStories * @param boolean $flattenStories
* @param array $rightsColl * @param array $rightsColl
* @param array $rightsDatabox * @param array $rightsDatabox
* @return RecordsRequest|\record_adapter[] * @return RecordsRequest
* @throws \Alchemy\Phrasea\Cache\Exception
*/ */
public static function fromRequest(Application $app, Request $request, $flattenStories = self::FLATTEN_NO, array $rightsColl = [], array $rightsDatabox = []) public static function fromRequest(Application $app, Request $request, $flattenStories = self::FLATTEN_NO, array $rightsColl = [], array $rightsDatabox = [])
{ {
$elements = $received = []; $received = [];
$basket = null; $basket = null;
if ($request->get('ssel')) { if ($request->get('ssel')) {
$basket = $app['converter.basket']->convert($request->get('ssel')); /** @var BasketConverter $basketConverter */
$basketConverter = $app['converter.basket'];
$basket = $basketConverter->convert($request->get('ssel'));
$app['acl.basket']->hasAccess($basket, $app->getAuthenticatedUser()); $app['acl.basket']->hasAccess($basket, $app->getAuthenticatedUser());
foreach ($basket->getElements() as $basket_element) { foreach ($basket->getElements() as $basket_element) {
@@ -240,35 +263,56 @@ class RecordsRequest extends ArrayCollection
} }
} }
// fill an array with records from flattened stories
$elements = $received; $elements = $received;
$to_remove = []; if ($flattenStories !== self::FLATTEN_NO) {
/** @var record_adapter $record */
foreach ($elements as $id => $record) { foreach ($received as $key => $record) {
if (!$app->getAclForUser($app->getAuthenticatedUser())->has_access_to_record($record)) { if ($record->isStory()) {
$to_remove[] = $id; if ($flattenStories === self::FLATTEN_YES) {
continue; // simple flatten : remove the story from elements
} unset($elements[$key]);
}
foreach ($rightsColl as $right) { foreach ($record->getChildren() as $child) {
if (!$app->getAclForUser($app->getAuthenticatedUser())->has_right_on_base($record->get_base_id(), $right)) { $elements[$child->getId()] = $child;
$to_remove[] = $id; }
continue;
}
}
foreach ($rightsDatabox as $right) {
if (!$app->getAclForUser($app->getAuthenticatedUser())->has_right_on_sbas($record->get_sbas_id(), $right)) {
$to_remove[] = $id;
continue;
} }
} }
} }
foreach ($to_remove as $id) { // apply rights filter, remove from elements if no rights
unset($elements[$id]); $rejected = [];
$acl = $app->getAclForUser($app->getAuthenticatedUser());
foreach ($elements as $key => $record) {
// any false or unknown right will throw exception and the record will be rejected
try {
if (!$acl->has_access_to_record($record)) {
throw new \Exception();
}
foreach ($rightsColl as $right) {
if (!$acl->has_right_on_base($record->getBaseId(), $right)) {
throw new \Exception();
}
}
foreach ($rightsDatabox as $right) {
if (!$acl->has_right_on_sbas($record->getDataboxId(), $right)) {
throw new \Exception();
}
}
}
catch (\Exception $e) {
$rejected[$key] = $record;
}
}
// remove rejected from elements
foreach ($rejected as $key => $record) {
unset($elements[$key]);
} }
return new static($elements, new ArrayCollection($received), $basket, $flattenStories); // flattening is already done
return new static($elements, new ArrayCollection($rejected), new ArrayCollection($received), $basket, self::FLATTEN_NO);
} }
} }

View File

@@ -31,7 +31,8 @@ class BasketConverter implements ConverterInterface
*/ */
public function convert($id) public function convert($id)
{ {
if (null === $basket = $this->repository->find((int) $id)) { /** @var Basket $basket */
if ( ($basket = $this->repository->find((int) $id)) === null) {
throw new NotFoundHttpException(sprintf('Basket %s not found.', $id)); throw new NotFoundHttpException(sprintf('Basket %s not found.', $id));
} }

View File

@@ -47,6 +47,10 @@ class ApiOrderController extends BaseOrderController
use FilesystemAware; use FilesystemAware;
use JsonBodyAware; use JsonBodyAware;
/**
* @param Request $request
* @return Response
*/
public function createAction(Request $request) public function createAction(Request $request)
{ {
$data = $this->decodeJsonBody($request, 'orders.json#/definitions/order_request'); $data = $this->decodeJsonBody($request, 'orders.json#/definitions/order_request');
@@ -54,7 +58,13 @@ class ApiOrderController extends BaseOrderController
$availableRecords = $this->toRequestedRecords($data->data->records); $availableRecords = $this->toRequestedRecords($data->data->records);
$records = $this->filterOrderableRecords($availableRecords); $records = $this->filterOrderableRecords($availableRecords);
$recordRequest = new RecordsRequest($records, new ArrayCollection($availableRecords), null, RecordsRequest::FLATTEN_YES); $recordRequest = new RecordsRequest(
$records, // orderable records
new ArrayCollection([]), // rejected (rights)
new ArrayCollection($availableRecords), // all records from request
null, // basket
RecordsRequest::FLATTEN_YES // orderable records is stories + children
);
$filler = new OrderFiller($this->app['repo.collection-references'], $this->app['orm.em']); $filler = new OrderFiller($this->app['repo.collection-references'], $this->app['orm.em']);
@@ -62,7 +72,13 @@ class ApiOrderController extends BaseOrderController
$order = new Order(); $order = new Order();
$order->setUser($this->getAuthenticatedUser()); $order->setUser($this->getAuthenticatedUser());
$order->setDeadline(new \DateTime($data->data->deadline, new \DateTimeZone('UTC'))); try {
$order->setDeadline(new \DateTime()); // safe value in case of data->deadline is invalid
$order->setDeadline(new \DateTime($data->data->deadline, new \DateTimeZone('UTC')));
}
catch (\Exception $e) {
// no-op, will end-up with safe value
}
$order->setOrderUsage($data->data->usage); $order->setOrderUsage($data->data->usage);
$order->setNotificationMethod(Order::NOTIFY_WEBHOOK); $order->setNotificationMethod(Order::NOTIFY_WEBHOOK);
@@ -139,8 +155,9 @@ class ApiOrderController extends BaseOrderController
} }
/** /**
* @param int $orderId * @param $orderId
* @return Response * @return Response
* @throws \Exception
*/ */
public function getArchiveAction($orderId) public function getArchiveAction($orderId)
{ {
@@ -162,7 +179,12 @@ class ApiOrderController extends BaseOrderController
$user = $this->getAuthenticatedUser(); $user = $this->getAuthenticatedUser();
$subdefs = $this->findDataboxSubdefNames(); $subdefs = $this->findDataboxSubdefNames();
$exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true); try {
$exportData = $export->prepare_export($user, $this->getFilesystem(), $subdefs, true, true);
}
catch (\Exception $e) {
throw new NotFoundHttpException(sprintf('No archive could be downloaded for Order "%d"', $order->getId()));
}
/** @var Token $token */ /** @var Token $token */
$token = $this->app['manipulator.token']->createDownloadToken($user, serialize($exportData)); $token = $this->app['manipulator.token']->createDownloadToken($user, serialize($exportData));
@@ -248,8 +270,13 @@ class ApiOrderController extends BaseOrderController
$filtered = []; $filtered = [];
foreach ($records as $index => $record) { foreach ($records as $index => $record) {
if (!$record->isStory() && $acl->has_right_on_base($record->getBaseId(), \ACL::CANCMD)) { try {
$filtered[$index] = $record; if ($acl->has_right_on_base($record->getBaseId(), \ACL::CANCMD)) {
$filtered[$index] = $record;
}
}
catch (\Exception $e) {
// will NOT happen since \ACL::CANCMD IS a known right
} }
} }

View File

@@ -65,7 +65,7 @@
"normalize-css": "^2.1.0", "normalize-css": "^2.1.0",
"npm": "^6.0.0", "npm": "^6.0.0",
"npm-modernizr": "^2.8.3", "npm-modernizr": "^2.8.3",
"phraseanet-production-client": "0.34.160-d", "phraseanet-production-client": "0.34.162-d",
"requirejs": "^2.3.5", "requirejs": "^2.3.5",
"tinymce": "^4.0.28", "tinymce": "^4.0.28",
"underscore": "^1.8.3", "underscore": "^1.8.3",

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2"> <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
<file date="2020-03-17T12:44:42Z" source-language="en" target-language="de" datatype="plaintext" original="not.available"> <file date="2020-04-03T07:42:51Z" source-language="en" target-language="de" datatype="plaintext" original="not.available">
<header> <header>
<tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/> <tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
<note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note> <note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
@@ -9,9 +9,9 @@
<trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes"> <trans-unit id="96f0767cb7ea65a7f86c8c9432e80d16cf9d8680" resname="Please provide the same passwords." approved="yes">
<source>Please provide the same passwords.</source> <source>Please provide the same passwords.</source>
<target state="translated">Bitte geben Sie diesselbe Passwörter ein.</target> <target state="translated">Bitte geben Sie diesselbe Passwörter ein.</target>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
<jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file> <jms:reference-file line="44">Form/Login/PhraseaRecoverPasswordForm.php</jms:reference-file>
<jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file> <jms:reference-file line="49">Form/Login/PhraseaRegisterForm.php</jms:reference-file>
<jms:reference-file line="36">Form/Login/PhraseaRenewPasswordForm.php</jms:reference-file>
</trans-unit> </trans-unit>
<trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes"> <trans-unit id="90b8c9717bb7ed061dbf20fe1986c8b8593d43d4" resname="The token provided is not valid anymore" approved="yes">
<source>The token provided is not valid anymore</source> <source>The token provided is not valid anymore</source>

View File

@@ -1,67 +1,14 @@
{% set nbReceived = records.received().count() %} {% if with_children.records.stories().count() > 0 %}
{% set nbEligibleDocuments = records.count() %} <label class="checkbox">
<input type="checkbox" id="del_children" name="del_children"
value="1"> {{ "Also delete records that rely on groupings." | trans }}
</label>
{% endif %}
{% set nbTrash = filteredRecord.trash|length %} <div id="delete_records_parent_only">
{% set nbDelete = filteredRecord.delete|length %} {{ include('prod/actions/delete_records_confirm_form.html.twig', parents_only) }}
</div>
{% if nbEligibleDocuments > 0 %} <div id="delete_records_with_children">
{% if nbReceived != records.count() %} {{ include('prod/actions/delete_records_confirm_form.html.twig', with_children) }}
<div class="well-small" style="text-align:center;"> </div>
<span class="label label-info">{{ "You do not have rights to remove all selected documents. Are you sure ?" | trans }}</span>
</div>
{% endif %}
<form id="delete-record-form" style="margin: 0;" method="POST" action="{{ path('record_delete') }}">
<input type="hidden" value="{{ records.serializedList() }}" name="lst" />
{% if nbTrash > 0 %}
<div class="well-small label-important"
style="background-color: #ffef22;">
<div class="dialog-left-section">
<img src="/assets/common/images/icons/icon_collection_bin.png"/>
</div>
<div class="dialog-right-section" style="margin-top: 8px;">
<span>{{ nbTrash }} {{ "prod:app trash: record-move-to-trash" | trans }}</span>
</div>
{% if records.stories().count() %}
<label class="checkbox story">
<input type="checkbox" id="del_children" name="del_children"
value="1"> {{ "prod:app trash: also-move-record" | trans }}
</label>
{% endif %}
</div>
{% endif %}
{% if nbDelete > 0 %}
<div class="well-small label-important"
style="background-color: #ed1c24;">
<div class="dialog-left-section">
<img src="/assets/common/images/icons/icon_empty_bin.png"/>
</div>
<div class="dialog-right-section">
<span>{{ nbDelete }} {{ "prod:app trash: record-delete" | trans }}</span>
</div>
{% if records.stories().count() %}
<label class="checkbox story">
<input type="checkbox" id="del_children" name="del_children"
value="1"> {{ "Also delete records that rely on groupings." | trans }}
</label>
{% endif %}
</div>
{% endif %}
<div class="form-actions" style="background-color:transparent;">
<button type="button" class="btn btn-danger submiter">{{ "Ok" | trans }}</button>
<button type="button" class="btn cancel">{{ "Cancel" | trans }}</button>
<span class="form-action-loader" style="display:none;">
<img src="/assets/common/images/icons/loader000.gif"/>
</span>
</div>
</form>
{% elseif nbReceived == 0 %}
<div class="well-small" style="text-align:center;">
<span class="label label-important">{{ "No document selected" | trans }}</span>
</div>
{% else %}
<div class="well-small" style="text-align:center;">
<span class="label label-info">{{ "You do not have rights to remove selected documents" | trans }}</span>
</div>
{% endif %}

View File

@@ -0,0 +1,48 @@
{% if records.count() > 0 %}
{% if records.rejected().count() > 0 %}
<div class="well-small" style="text-align:center;">
{{ "You do not have rights to remove all selected documents. Are you sure ?" | trans }}
</div>
{% endif %}
<form id="delete-record-form" style="margin: 0;" method="POST" action="{{ path('record_delete') }}">
<input type="hidden" value="{{ records.serializedList() }}" name="lst"/>
{% if trashableCount > 0 %}
<div class="well-small label-important"
style="background-color: #ffef22;">
<div class="dialog-left-section">
<img src="/assets/common/images/icons/icon_collection_bin.png"/>
</div>
<div class="dialog-right-section" style="margin-top: 8px;">
<span class="to_trash_count">{{ trashableCount }}</span> {{ "prod:app trash: record-move-to-trash" | trans }}
</div>
</div>
{% endif %}
{% if deletableCount > 0 %}
<div class="well-small label-important"
style="background-color: #ed1c24;">
<div class="dialog-left-section">
<img src="/assets/common/images/icons/icon_empty_bin.png"/>
</div>
<div class="dialog-right-section">
<span class="to_delete_count">{{ deletableCount }}</span> {{ "prod:app trash: record-to-delete" | trans }}
</div>
</div>
{% endif %}
<div class="form-actions" style="background-color:transparent;">
<button type="button" class="btn btn-danger submiter">{{ "Ok" | trans }}</button>
<button type="button" class="btn cancel">{{ "Cancel" | trans }}</button>
<span class="form-action-loader" style="display:none;">
<img src="/assets/common/images/icons/loader000.gif"/>
</span>
</div>
</form>
{% elseif records.received().count() == 0 %}
<div class="well-small" style="text-align:center;">
<span class="label label-important">{{ "No document selected" | trans }}</span>
</div>
{% else %}
<div class="well-small" style="text-align:center;">
<span class="label label-info">{{ "You do not have rights to remove selected documents" | trans }}</span>
</div>
{% endif %}

View File

@@ -7577,10 +7577,10 @@ phraseanet-common@^0.4.5-d:
js-cookie "^2.1.0" js-cookie "^2.1.0"
pym.js "^1.3.1" pym.js "^1.3.1"
phraseanet-production-client@0.34.160-d: phraseanet-production-client@0.34.162-d:
version "0.34.160-d" version "0.34.162-d"
resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.160-d.tgz#3deb3387b54e56aec73b073cae8cc013cc316999" resolved "https://registry.yarnpkg.com/phraseanet-production-client/-/phraseanet-production-client-0.34.162-d.tgz#4bfbb6998bae864f5be2eefba87b07ef06f7e4e6"
integrity sha512-00jnCOCDrLowL8TE+h8mH+Lg4P0+EQPSDOXN2Lq6KF577GGu0OWQRh2YmUeXkacHTUT4N0u39IsBkkBYqorVnQ== integrity sha512-FVXzj0Qi6DQSJnv3LrCiIaEUZ0A1DoOn3kUGPBpgws+EzXS13tFC6W0eLz/gDgw/L9Y82S60gI9s778fadwoew==
dependencies: dependencies:
"@mapbox/mapbox-gl-language" "^0.9.2" "@mapbox/mapbox-gl-language" "^0.9.2"
"@turf/turf" "^5.1.6" "@turf/turf" "^5.1.6"