Merge branch '3.0'
8
.gitignore
vendored
@ -1,3 +1,9 @@
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
transifexAuth.json
|
||||
**/css/bourbon
|
||||
**/.sass-cache
|
||||
**/.sass-cache
|
||||
node_modules/
|
29
LICENSE
Normal file
@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018, Thierry François (colymba)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
25
README.md
@ -3,7 +3,7 @@ GridField Bulk Editing Tools
|
||||
|
||||
[![Latest Stable Version](https://poser.pugx.org/colymba/gridfield-bulk-editing-tools/v/stable.svg)](https://github.com/colymba/GridFieldBulkEditingTools/releases)
|
||||
[![Latest Unstable Version](https://poser.pugx.org/colymba/gridfield-bulk-editing-tools/v/unstable.svg)](https://github.com/colymba/GridFieldBulkEditingTools/tree/master)
|
||||
[![License](https://poser.pugx.org/colymba/gridfield-bulk-editing-tools/license.svg)](#license-bsd-simplified)
|
||||
[![License](https://poser.pugx.org/colymba/gridfield-bulk-editing-tools/license.svg)](#license-and-copyright)
|
||||
|
||||
Set of SilverStripe 4 GridField components to facilitate bulk file upload & record editing.
|
||||
|
||||
@ -16,7 +16,7 @@ Set of SilverStripe 4 GridField components to facilitate bulk file upload & reco
|
||||
[More screenshots here.](screenshots)
|
||||
|
||||
## Requirements
|
||||
* SilverStripe 4.0 (version master / 3.+)
|
||||
* SilverStripe 4.0 (3.+)
|
||||
* SilverStripe 3.1 (version 2.+ / 1.+)
|
||||
* Silverstripe 3.0 (version [0.5](https://github.com/colymba/GridFieldBulkEditingTools/tree/0.5))
|
||||
|
||||
@ -44,7 +44,7 @@ Upload multiple images or files at once into DataObjects. Perfect for galleries
|
||||
$config->addComponent(new \Colymba\BulkUpload\BulkUploader());
|
||||
```
|
||||
|
||||
See [BULK_UPLOAD.md](bulkUpload/BULK_UPLOAD.md) for detailed configuration.
|
||||
See [BULK_UPLOAD.md](docs/en/BULK_UPLOAD.md) for detailed configuration.
|
||||
|
||||
## Bulk Manager
|
||||
Perform actions on multiple records straight from the GridField
|
||||
@ -53,14 +53,11 @@ Perform actions on multiple records straight from the GridField
|
||||
$config->addComponent(new \Colymba\BulkManager\BulkManager());
|
||||
```
|
||||
|
||||
See [BULK_MANAGER.md](bulkManager/BULK_MANAGER.md) for detailed configuration.
|
||||
See [BULK_MANAGER.md](docs/en//BULK_MANAGER.md) for detailed configuration.
|
||||
|
||||
## Interdependencies
|
||||
The `BulkUploader` component makes use of `BulkManager` to allow quick editing of the newly uploaded files. Although not nescessary for the component to work, adding `Colymba\BulkManager\BulkManager` too to your `GridFieldConfig` will give you this advantage.
|
||||
|
||||
#### @TODO
|
||||
* Add individual actions for each upload (update + cancel)
|
||||
* Handle and display errors better for: creation, update, cancel
|
||||
|
||||
## Translations
|
||||
|
||||
@ -68,16 +65,6 @@ Translations of the natural language strings are managed through a third party t
|
||||
|
||||
Please use [https://www.transifex.com/projects/p/gridfieldbulkeditingtools/](https://www.transifex.com/projects/p/gridfieldbulkeditingtools/) to contribute translations, rather than sending pull requests with YAML/JS files.
|
||||
|
||||
## License (BSD Simplified)
|
||||
## License and Copyright
|
||||
|
||||
Copyright (c) 2013, Thierry Francois (colymba)
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Thierry Francois, colymba nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
[BSD 3-clause license](LICENSE)
|
||||
|
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Colymba\BulkManager\BulkAction;
|
||||
|
||||
use Colymba\BulkManager\BulkAction\Handler;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
use SilverStripe\Core\Convert;
|
||||
|
||||
/**
|
||||
* Bulk action handler for deleting records.
|
||||
*
|
||||
* @author colymba
|
||||
*/
|
||||
class DeleteHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* RequestHandler allowed actions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $allowed_actions = array('delete');
|
||||
|
||||
/**
|
||||
* RequestHandler url => action map.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'delete' => 'delete',
|
||||
);
|
||||
|
||||
/**
|
||||
* Delete the selected records passed from the delete bulk action.
|
||||
*
|
||||
* @param HTTPRequest $request
|
||||
*
|
||||
* @return HTTPResponse List of deleted records ID
|
||||
*/
|
||||
public function delete(HTTPRequest $request)
|
||||
{
|
||||
$ids = array();
|
||||
|
||||
foreach ($this->getRecords() as $record) {
|
||||
array_push($ids, $record->ID);
|
||||
$record->delete();
|
||||
}
|
||||
|
||||
$response = new HTTPResponse(Convert::raw2json(array(
|
||||
'done' => true,
|
||||
'records' => $ids,
|
||||
)));
|
||||
$response->addHeader('Content-Type', 'text/json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -1,148 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Colymba\BulkManager\BulkAction;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\RequestHandler;
|
||||
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
|
||||
/**
|
||||
* Base class to extend for all custom bulk action handlers
|
||||
* Gives access to the GridField, Component and Controller
|
||||
* and implements useful functions like {@link getRecordIDList()} and {@link getRecords()}.
|
||||
*
|
||||
* @author colymba
|
||||
*/
|
||||
class Handler extends RequestHandler
|
||||
{
|
||||
/**
|
||||
* Related GridField instance.
|
||||
*
|
||||
* @var GridField
|
||||
*/
|
||||
protected $gridField;
|
||||
|
||||
/**
|
||||
* GridFieldBulkManager instance.
|
||||
*
|
||||
* @var GridFieldBulkManager
|
||||
*/
|
||||
protected $component;
|
||||
|
||||
/**
|
||||
* Current controller instance.
|
||||
*
|
||||
* @var Controller
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* @param GridField $gridField
|
||||
* @param GridField_URLHandler $component
|
||||
* @param Controller $controller
|
||||
*/
|
||||
public function __construct($gridField, $component, $controller)
|
||||
{
|
||||
$this->gridField = $gridField;
|
||||
$this->component = $component;
|
||||
$this->controller = $controller;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL for this RequestHandler.
|
||||
*
|
||||
* @author SilverStripe
|
||||
*
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
*
|
||||
* @param string $action
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Link($action = null)
|
||||
{
|
||||
return Controller::join_links($this->gridField->Link(), 'bulkAction', $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse up nested requests until we reach the first that's not a GridFieldDetailForm or GridFieldDetailForm_ItemRequest.
|
||||
* The opposite of {@link Controller::curr()}, required because
|
||||
* Controller::$controller_stack is not directly accessible.
|
||||
*
|
||||
* @return Controller
|
||||
*/
|
||||
protected function getToplevelController()
|
||||
{
|
||||
$c = $this->controller;
|
||||
while ($c && ($c instanceof GridFieldDetailForm_ItemRequest || $c instanceof GridFieldDetailForm)) {
|
||||
$c = $c->getController();
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edited version of the GridFieldEditForm function
|
||||
* adds the 'Bulk Upload' at the end of the crums.
|
||||
*
|
||||
* CMS-specific functionality: Passes through navigation breadcrumbs
|
||||
* to the template, and includes the currently edited record (if any).
|
||||
* see {@link LeftAndMain->Breadcrumbs()} for details.
|
||||
*
|
||||
* @author SilverStripe original Breadcrumbs() method
|
||||
*
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
*
|
||||
* @param bool $unlinked
|
||||
*
|
||||
* @return ArrayData
|
||||
*/
|
||||
public function Breadcrumbs($unlinked = false)
|
||||
{
|
||||
if (!$this->controller->hasMethod('Breadcrumbs')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$items = $this->controller->Breadcrumbs($unlinked);
|
||||
$items->push(new ArrayData(array(
|
||||
'Title' => 'Bulk Editing',
|
||||
'Link' => false,
|
||||
)));
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of record IDs selected in the front-end.
|
||||
*
|
||||
* @return array List of IDs
|
||||
*/
|
||||
public function getRecordIDList()
|
||||
{
|
||||
$vars = $this->request->requestVars();
|
||||
|
||||
return $vars['records'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataList of the records selected in the front-end.
|
||||
*
|
||||
* @return DataList List of records
|
||||
*/
|
||||
public function getRecords()
|
||||
{
|
||||
$ids = $this->getRecordIDList();
|
||||
|
||||
if ($ids) {
|
||||
$class = $this->gridField->list->dataClass;
|
||||
|
||||
return DataList::create($class)->byIDs($ids);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Colymba\BulkManager\BulkAction;
|
||||
|
||||
use Colymba\BulkManager\BulkAction\Handler;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
|
||||
/**
|
||||
* Bulk action handler for unlinking records.
|
||||
*
|
||||
* @author colymba
|
||||
*/
|
||||
class UnlinkHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* RequestHandler allowed actions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $allowed_actions = array('unLink');
|
||||
|
||||
/**
|
||||
* RequestHandler url => action map.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'unLink' => 'unLink',
|
||||
);
|
||||
|
||||
/**
|
||||
* Unlink the selected records passed from the unlink bulk action.
|
||||
*
|
||||
* @param HTTPRequest $request
|
||||
*
|
||||
* @return HTTPResponse List of affected records ID
|
||||
*/
|
||||
public function unLink(HTTPRequest $request)
|
||||
{
|
||||
$ids = $this->getRecordIDList();
|
||||
$this->gridField->list->removeMany($ids);
|
||||
|
||||
$response = new HTTPResponse(Convert::raw2json(array(
|
||||
'done' => true,
|
||||
'records' => $ids,
|
||||
)));
|
||||
$response->addHeader('Content-Type', 'text/json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
#bulkEditHeader {
|
||||
float: left;
|
||||
width: 70%;
|
||||
margin: 40px 0 20px 0;
|
||||
font-size: 30px;
|
||||
font-weight: bold; }
|
||||
|
||||
#bulkEditToggle {
|
||||
float: right;
|
||||
clear: right;
|
||||
width: 25%;
|
||||
margin: 40px 0 20px 0;
|
||||
text-decoration: underline;
|
||||
text-align: right;
|
||||
cursor: pointer; }
|
||||
|
||||
.bulkEditingFieldHolder {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 100%; }
|
||||
.bulkEditingFieldHolder.hasUpdate .ui-accordion-header {
|
||||
background-color: #f2ba11;
|
||||
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f2ba11), color-stop(100%, #df6e00));
|
||||
background-image: -webkit-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: -moz-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: -o-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: -ms-linear-gradient(top, #f2ba11 0%, #df6e00 100%);
|
||||
background-image: linear-gradient(top, #f2ba11 0%, #df6e00 100%); }
|
||||
.bulkEditingFieldHolder.hasUpdate .ui-accordion-header a {
|
||||
color: #fff;
|
||||
text-shadow: none; }
|
||||
.bulkEditingFieldHolder.updated .ui-accordion-header {
|
||||
background-color: #a4ca3a;
|
||||
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #a4ca3a), color-stop(100%, #59781D));
|
||||
background-image: -webkit-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: -moz-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: -o-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: -ms-linear-gradient(top, #a4ca3a 0%, #59781D 100%);
|
||||
background-image: linear-gradient(top, #a4ca3a 0%, #59781D 100%); }
|
||||
.bulkEditingFieldHolder.updated .ui-accordion-header a {
|
||||
color: #fff;
|
||||
text-shadow: none; }
|
||||
|
||||
/*# sourceMappingURL=GridFieldBulkEditingForm.css.map */
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AACA,eACA;EACC,KAAK,EAAE,IAAI;EACX,KAAK,EAAE,GAAG;EAEV,MAAM,EAAE,aAAa;EAErB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;;AAGlB,eACA;EACC,KAAK,EAAE,KAAK;EACZ,KAAK,EAAE,KAAK;EACZ,KAAK,EAAE,GAAG;EAEV,MAAM,EAAE,aAAa;EAErB,eAAe,EAAE,SAAS;EAC1B,UAAU,EAAE,KAAK;EACjB,MAAM,EAAE,OAAO;;AAGhB,uBACA;EACC,QAAQ,EAAE,QAAQ;EAClB,KAAK,EAAE,IAAI;EACX,KAAK,EAAE,IAAI;EAEX,sDACA;IACC,gBAAgB,EAAE,OAAO;IAEzB,gBAAgB,EAAE,8FAA8F;IAChH,gBAAgB,EAAE,sDAAsD;IACxE,gBAAgB,EAAE,mDAAmD;IACrE,gBAAgB,EAAE,iDAAiD;IACnE,gBAAgB,EAAE,kDAAkD;IACpE,gBAAgB,EAAE,8CAA8C;IAEhE,wDACA;MACC,KAAK,EAAE,IAAI;MACX,WAAW,EAAE,IAAI;EAInB,oDACA;IACC,gBAAgB,EAAE,OAAO;IAEzB,gBAAgB,EAAE,8FAA8F;IAChH,gBAAgB,EAAE,sDAAsD;IACxE,gBAAgB,EAAE,mDAAmD;IACrE,gBAAgB,EAAE,iDAAiD;IACnE,gBAAgB,EAAE,kDAAkD;IACpE,gBAAgB,EAAE,8CAA8C;IAEhE,sDACA;MACC,KAAK,EAAE,IAAI;MACX,WAAW,EAAE,IAAI",
|
||||
"sources": ["GridFieldBulkEditingForm.scss"],
|
||||
"names": [],
|
||||
"file": "GridFieldBulkEditingForm.css"
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
.cms table.grid-field__table tr.bulkManagerOptions th.bulkmanagerheading {
|
||||
padding-left: 40px; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions th.bulkmanagerselect {
|
||||
text-align: center; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions th.bulkmanagerselect input {
|
||||
margin-left: 0; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions .title {
|
||||
margin: 0 0 2px 2px; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions .dropdown {
|
||||
display: inline-block;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: #000;
|
||||
vertical-align: top; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions .doBulkActionButton .ui-button-text {
|
||||
padding: 6px 0 5px 2.1em; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions .doBulkActionButton .ui-button-text .ui-button-text {
|
||||
padding: 0; }
|
||||
.cms table.grid-field__table tr.bulkManagerOptions .doBulkActionButton .loading .ui-icon {
|
||||
background: transparent url(../../framework/images/network-save.gif) no-repeat 0 0; }
|
||||
.cms table.grid-field__table tbody .col-bulkSelect {
|
||||
width: 25px;
|
||||
text-align: center; }
|
||||
.cms table.grid-field__table tbody td a.tempDisabledEditLink {
|
||||
background: url("../../framework/admin/images/btn-icon/document--pencil.png") no-repeat 2px 0px;
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-indent: 119988px;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
background-position: 2px 0px;
|
||||
background-repeat: no-repeat no-repeat; }
|
||||
|
||||
/*# sourceMappingURL=GridFieldBulkManager.css.map */
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "AAII,wEAAsB;EAClB,YAAY,EAAE,IAAI;AAGtB,uEACA;EACE,UAAU,EAAE,MAAM;EAElB,6EACA;IACE,WAAW,EAAE,CAAC;AAIlB,yDACA;EACE,MAAM,EAAE,WAAW;AAGrB,4DACA;EACE,OAAO,EAAE,YAAY;EACrB,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,IAAI;EAEhB,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EAET,KAAK,EAAE,IAAI;EACX,cAAc,EAAE,GAAG;AAKnB,sFACA;EACE,OAAO,EAAE,eAAe;EAExB,sGACA;IACE,OAAO,EAAE,CAAC;AAId,wFACA;EACE,UAAU,EAAE,sEAAsE;AAOtF,kDACA;EACE,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,MAAM;EACf,UAAU,EAAE,MAAM;AAGpB,4DACA;EACE,UAAU,EAAE,mFAAmF;EAC/F,OAAO,EAAE,YAAY;EACrB,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,QAAQ;EACrB,QAAQ,EAAE,MAAM;EAChB,cAAc,EAAE,MAAM;EACtB,mBAAmB,EAAE,OAAO;EAC5B,iBAAiB,EAAE,mBAAmB",
|
||||
"sources": ["GridFieldBulkManager.scss"],
|
||||
"names": [],
|
||||
"file": "GridFieldBulkManager.css"
|
||||
}
|
Before Width: | Height: | Size: 24 KiB |
@ -1,153 +0,0 @@
|
||||
.bulkUpload {
|
||||
padding: 0 !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); }
|
||||
.bulkUpload:hover {
|
||||
background-color: #444546; }
|
||||
.bulkUpload .component {
|
||||
padding: 0 !important;
|
||||
color: #fff;
|
||||
background: #98aab6;
|
||||
border-top: 1px solid #a4b4bf;
|
||||
border-left: 1px solid #a4b4bf;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1); }
|
||||
.bulkUpload .component div.ss-uploadfield {
|
||||
position: relative;
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files {
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item {
|
||||
position: relative;
|
||||
float: left;
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
width: 98%;
|
||||
padding: 5px 1% 5px 1%;
|
||||
border: none;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-color: #eceff1; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item:nth-child(2n-1) {
|
||||
background-color: #e6eaed; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-preview {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 38px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info {
|
||||
height: 30px;
|
||||
margin-left: 40px;
|
||||
line-height: 30px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 50px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
line-height: 40px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .name {
|
||||
color: #343434; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .size {
|
||||
font-weight: normal; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status {
|
||||
float: left;
|
||||
width: auto;
|
||||
padding: 0 0 0 5px;
|
||||
text-align: left;
|
||||
max-width: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status.ui-state-warning-text {
|
||||
color: #f29500; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status.ui-state-success-text {
|
||||
color: #298530; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 5px 0 5px 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-progress {
|
||||
left: 50px;
|
||||
right: 35px;
|
||||
margin-top: 8px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions button {
|
||||
margin: 0 10px 0 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions button .ui-button-text {
|
||||
padding-top: 4px;
|
||||
padding-bottom: 3px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-cancel {
|
||||
position: relative;
|
||||
top: 7px;
|
||||
right: auto;
|
||||
float: right; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-cancel button {
|
||||
background: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-overwrite {
|
||||
position: relative;
|
||||
float: right;
|
||||
margin-top: 2px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile {
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 98%;
|
||||
padding: 1%; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile.borderTop {
|
||||
border: none; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-preview.ss-uploadfield-dropzone {
|
||||
float: right;
|
||||
width: 35%;
|
||||
height: 43px;
|
||||
margin: 0;
|
||||
line-height: 43px;
|
||||
color: #eee;
|
||||
background-color: #8898a3;
|
||||
border: 2px dashed #73818a;
|
||||
box-shadow: #73818a 0 0 10px 0 inset; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-preview.ss-uploadfield-dropzone.hover {
|
||||
color: #444546;
|
||||
background-color: #eee; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info {
|
||||
float: left;
|
||||
width: 60%;
|
||||
margin: 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-item-name {
|
||||
height: auto;
|
||||
margin-bottom: 5px !important; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-item-name small {
|
||||
font-weight: normal !important; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-ui-button .ui-button-text .ui-button-text {
|
||||
padding: 0px; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-fromcomputer {
|
||||
margin-bottom: 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-fromfiles {
|
||||
margin-bottom: 0;
|
||||
padding: .5px; }
|
||||
.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons {
|
||||
display: none;
|
||||
float: left;
|
||||
width: 98%;
|
||||
padding: 6px 1% 6px 1%;
|
||||
background-color: #8898a3; }
|
||||
.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button {
|
||||
float: left;
|
||||
margin: 0 6px 0 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button .ui-button-text .ui-button-text {
|
||||
padding: 0; }
|
||||
.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button.bulkUploadEditButton, .bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button.bulkUploadClearErrorButton {
|
||||
float: right;
|
||||
margin: 0 0 0 6px; }
|
||||
.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons .colymba-bulkupload-info {
|
||||
float: left;
|
||||
margin: 0 6px 0 6px;
|
||||
line-height: 28px;
|
||||
height: 28px;
|
||||
color: #ffffff;
|
||||
background-image: url(../../images/spinner.gif);
|
||||
background-position: 0 -50px;
|
||||
background-repeat: no-repeat;
|
||||
overflow: hidden; }
|
||||
.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons.loading .colymba-bulkupload-info {
|
||||
padding-left: 20px;
|
||||
background-position: 0 5px; }
|
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 59 KiB |
1
client/dist/js/bulkTools.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
!function(t){function e(i){if(n[i])return n[i].exports;var a=n[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,n){n(1),n(2),t.exports=n(3)},function(t,e){!function(t){t.entwine("ss",function(t){t.entwine("colymba",function(t){t(".bulkManagerOptions").entwine({onmatch:function(){var e=this.parents("thead"),n=e.find("tr"),i=[".filter-header",".sortable-header"],a=e.find(i.join(",")),s=n.index(this),o=n.length-1;a.each(function(t,e){var i=n.index(e);i<o&&(o=i)}),s>o&&n.eq(o).insertAfter(t(this))},onunmatch:function(){}}),t("td.col-bulkSelect").entwine({onmatch:function(){},onunmatch:function(){},onmouseover:function(){t(this).parents(".ss-gridfield-item").find(".edit-link").removeClass("edit-link").addClass("tempDisabledEditLink")},onmouseout:function(){t(this).parents(".ss-gridfield-item").find(".tempDisabledEditLink").addClass("edit-link").removeClass("tempDisabledEditLink")},onclick:function(e){var n=t(e.target).find("input");t(n).prop("checked")?t(n).prop("checked",!1):t(n).prop("checked",!0)}}),t("td.col-bulkSelect input").entwine({onmatch:function(){},onunmatch:function(){},onclick:function(e){t(this).parents(".grid-field__table").find("input.bulkSelectAll").prop("checked","")}}),t("input.bulkSelectAll").entwine({onmatch:function(){},onunmatch:function(){},onclick:function(){var e=t(this).prop("checked");t(this).parents(".grid-field__table").find("td.col-bulkSelect input").prop("checked",e).trigger("change")},getSelectRecordsID:function(){return t(this).parents(".grid-field__table").find("td.col-bulkSelect input:checked").map(function(){return parseInt(t(this).data("record"))}).get()}}),t("select.bulkActionName").entwine({onmatch:function(){},onunmatch:function(){},onchange:function(e){var n=t(this).val(),i=t(this).parents(".bulkManagerOptions"),a=i.find(".doBulkActionButton"),s=a.data("config");if(t.each(s,function(t,e){t!=n&&a.removeClass(e.buttonClasses)}),a.addClass(s[n].buttonClasses).addClass("btn-outline-secondary"),s[n].icon){var o=a.find("img");o.length?o.attr("src",s[n].icon):a.prepend('<img src="'+s[n].icon+'" alt="" />')}else a.find("img").remove();s[n].destructive?a.addClass("btn-outline-danger"):a.removeClass("btn-outline-danger")}}),t(".doBulkActionButton").entwine({onmatch:function(){},onunmatch:function(){},getActionURL:function(t,e){var n=(new Date).getTime();return e=e.split("?"),t=t?"/"+t:"",e=e[1]?e[0]+t+"?"+e[1]+"&cacheBuster="+n:e[0]+t+"?cacheBuster="+n},onclick:function(e){var n=t(this).parents(".bulkManagerOptions"),i=n.find("select.bulkActionName").val(),a=t(this).parents(".bulkManagerOptions").find("input.bulkSelectAll:first").getSelectRecordsID();this.doBulkAction(i,a)},doBulkAction:function(e,n,i,a){var s=t(this).parents(".bulkManagerOptions"),o=s.find("a.doBulkActionButton"),d=o.data("config"),l=this.getActionURL(e,t(this).data("url")),r={records:n};if(n.length<=0)return void alert(ss.i18n._t("GRIDFIELD_BULK_MANAGER.BULKACTION_EMPTY_SELECT"));if(d[e].destructive&&!confirm(ss.i18n._t("GRIDFIELD_BULK_MANAGER.CONFIRM_DESTRUCTIVE_ACTION")))return i&&a&&i.call(a,!1),!1;if(o.addClass("loading"),d[e].xhr)t.ajax({url:l,data:r,type:"POST",context:t(this)}).done(function(e,n,s){o.removeClass("loading"),i&&a?i.call(a,e):t(this).parents(".ss-gridfield").entwine(".").entwine("ss").reload()});else{l=l+"&"+("records[]="+n.join("&records[]=")),window.location.href=l}}})})})}(jQuery)},function(t,e){!function(t){t.entwine("colymba",function(t){t("#bulkEditToggle").entwine({onmatch:function(){},onunmatch:function(){},onclick:function(e){var n=this.parents("form").find(".ss-toggle .ui-accordion-header"),i=this.data("state");i=i&&"close"!==i?"close":"open",n.each(function(){var e=t(this);"open"!==i||e.hasClass("ui-state-active")||e.click(),"close"===i&&e.hasClass("ui-state-active")&&e.click()}),this.data("state",i)}}),t(".bulkEditingFieldHolder").entwine({onmatch:function(){},onunmatch:function(){},onchange:function(){this.removeClass("updated"),this.hasClass("hasUpdate")||this.addClass("hasUpdate")}})})}(jQuery)},function(t,e){!function(t){t.entwine("ss",function(t){t.entwine("colymba",function(t){t(".bulkUploader").entwine({onmatch:function(){var t=this.parents("thead").find("tr"),e=this.clone();t.index(this)>1&&(e.insertAfter(t.eq(0)),this.remove())},onunmatch:function(){}}),t("ul.ss-uploadfield-files").entwine({onmatch:function(){},onunmatch:function(){},trackProgress:function(){var t=this.find("li.ss-uploadfield-item"),e=t.length,n=t.filter(".done"),i=n.length,a=t.not(n).find(".ui-state-warning-text,.ui-state-error-text"),s=a.length;this.parents(".ss-uploadfield").find(".colymba-bulkupload-buttons").refresh(e,i,s)}}),t("li.ss-uploadfield-item").entwine({onmatch:function(){this.parents("ul.ss-uploadfield-files").trackProgress()},onunmatch:function(){t("ul.ss-uploadfield-files").trackProgress()}}),t("li.ss-uploadfield-item .ui-state-warning-text,li.ss-uploadfield-item .ui-state-error-text").entwine({onmatch:function(){this.parents("ul.ss-uploadfield-files").trackProgress()},onunmatch:function(){t("ul.ss-uploadfield-files").trackProgress()}}),t(".colymba-bulkupload-buttons").entwine({onmatch:function(){},onunmatch:function(){},refresh:function(t,e,n){var i=this.find(".colymba-bulkupload-info"),a=this.find(".bulkUploadEditButton"),s=this.find(".bulkUploadCancelButton"),o=this.find(".bulkUploadFinishButton"),d=this.find(".bulkUploadClearErrorButton");t>0?(this.css({display:"block"}),i.html(ss.i18n.sprintf(ss.i18n._t("GRIDFIELD_BULK_UPLOAD.PROGRESS_INFO"),t,e,n)),s.removeClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","false").removeAttr("disabled"),e+n<t?this.hasClass("loading")||(this.addClass("loading"),o.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","disabled")):(this.removeClass("loading"),o.removeClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","false").removeAttr("disabled")),t===e?a.removeClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","false").removeAttr("disabled"):a.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","true"),n>0?d.removeClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","false").removeAttr("disabled"):d.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","true")):(this.css({display:"none"}).removeClass("loading"),a.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","true"),s.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","true"),o.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","true"),d.addClass("ui-state-disabled ssui-button-disabled").attr("aria-disabled","true").attr("disabled","true"))}}),t(".bulkUploadClearErrorButton:not(.ui-state-disabled)").entwine({onmatch:function(){this.removeClass("action")},onunmatch:function(){},onclick:function(e){var n=this.parents(".bulkUpload"),i=n.find("li.ss-uploadfield-item .ui-state-warning-text,li.ss-uploadfield-item .ui-state-error-text").parents("li");t(i.get().reverse()).each(function(e,n){t(this).remove()})}}),t(".bulkUploadCancelButton:not(.ui-state-disabled)").entwine({onmatch:function(){this.removeClass("action")},onunmatch:function(){},onclick:function(){var e,n=this.parents(".bulkUpload"),i=n.find("li.ss-uploadfield-item"),a=i.filter("[data-recordid]"),s=i.not(a),o=n.parents(".ss-gridfield-table").find(".doBulkActionButton");s.each(function(e,n){t(this).remove()}),o.length>0&&(e=a.map(function(){return parseInt(t(this).data("recordid"))}).get(),this.addClass("loading"),o.doBulkAction("delete",e,this.cancelCallback,this))},cancelCallback:function(e){var n,i=this.parents(".bulkUpload"),a=i.find("li.ss-uploadfield-item");e&&(n=e.records,a.each(function(e,i){var a=t(this),s=parseInt(a.data("recordid"));-1!==n.indexOf(s)&&a.remove()}),t(this).parents(".ss-gridfield").entwine(".").entwine("ss").reload()),this.removeClass("loading")}}),t(".bulkUploadFinishButton:not(.ui-state-disabled)").entwine({onmatch:function(){this.removeClass("action")},onunmatch:function(){},onclick:function(){var e=this.parents(".bulkUpload"),n=e.find("li.ss-uploadfield-item");this.addClass("loading"),n.each(function(e,n){t(this).remove()}),t(this).parents(".ss-gridfield").entwine(".").entwine("ss").reload(),this.removeClass("loading")}}),t(".bulkUploadEditButton:not(.ui-state-disabled)").entwine({onmatch:function(){this.removeClass("action")},onunmatch:function(){},onclick:function(){var e,n=this.parents(".bulkUpload"),i=n.find("li.ss-uploadfield-item"),a=i.filter("[data-recordid]"),s=n.parents(".ss-gridfield-table").find(".doBulkActionButton");s.length>0&&(this.addClass("loading"),e=a.map(function(){return parseInt(t(this).data("recordid"))}).get(),s.doBulkAction("bulkedit",e))}})})})}(jQuery)}]);
|
1
client/dist/js/bulkTools.js.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack:///webpack/bootstrap 4815efe042c2a898f146","webpack:///./client/src/js/manager.js","webpack:///./client/src/js/managerBulkEditingForm.js","webpack:///./client/src/js/uploader.js"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;AC7DA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;;;AAGJ;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA,IAAI;;;AAGJ;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,MAAM;;;AAGN;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;;;AAGA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAI;;;AAGJ;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,KAAK;AACL;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;;AAEL;AACA;AACA;AACA;;AAEA;AACA;AACA,yBAAyB;AACzB;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAI;;;AAGJ,GAAG;AACH,EAAE;AACF,CAAC;;;;;;;ACnQD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,W;AACA,SAAS;;AAET;AACA;AACA,KAAK;;;AAGL;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL,GAAG;AACH,CAAC,U;;;;;;AC7DD,c;AACA;;;AAGA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,W;AACA,SAAS;AACT;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,OAAO;;AAEP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,OAAO;;;AAGP;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,sBAAsB,iBAAiB;;AAEvC;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,e;AACA;AACA;AACA;AACA;AACA,a;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,gBAAgB;AACtC;AACA;AACA;AACA;AACA,W;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;;AAEA,mE;AACA;AACA,WAAW;AACX;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,WAAW;;AAEX;AACA;AACA,iD;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;;AAEb;AACA;;AAEA;AACA;AACA,OAAO;;;AAGP;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,+BAA+B;AAC/B;AACA,S;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW;;AAEX;;AAEA;AACA;AACA,OAAO;;AAEP;AACA;AACA;AACA,SAAS;AACT,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA,iD;AACA;AACA,aAAa;;AAEb;AACA;AACA;AACA,OAAO;;AAEP,GAAG,EAAE;;AAEL,EAAE,EAAE;AACJ,CAAC,U","file":"js/bulkTools.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 4815efe042c2a898f146","(function($) {\n\t$.entwine('ss', function($) {\n\n\t\t$.entwine('colymba', function($) {\n\n\t\t\t/**\n * Makes sure the component is above the headers\n */\n $('.bulkManagerOptions').entwine({\n onmatch: function(){\n var $parent = this.parents('thead'),\n \t\t$tr = $parent.find('tr'),\n\n \t\ttargets = ['.filter-header', '.sortable-header'],\n \t\t$target = $parent.find(targets.join(',')),\n\n index = $tr.index(this),\n newIndex = $tr.length - 1\n ;\n\n $target.each(function(index, Element){\n \tvar idx = $tr.index(Element);\n \tif ( idx < newIndex )\n \t{\n \t\tnewIndex = idx;\n \t}\n });\n\n if ( index > newIndex )\n {\n $tr.eq(newIndex).insertAfter($(this));\n }\n },\n onunmatch: function(){}\n });\n\n\n\t\t /**\n\t\t * Bulkselect table cell behaviours\n\t\t */\n\t\t\t$('td.col-bulkSelect').entwine({\n\t\t\t\tonmatch: function(){\n\t\t\t\t},\n\t\t\t\tonunmatch: function(){\n\t\t\t\t},\n\t\t\t\tonmouseover: function(){\n\t\t\t\t\t//disable default row click behaviour -> avoid navigation to edit form when clicking the checkbox\n\t $(this).parents('.ss-gridfield-item').find('.edit-link').removeClass('edit-link').addClass('tempDisabledEditLink');\n\t\t\t\t},\n\t\t\t\tonmouseout: function(){\n\t\t\t\t\t//re-enable default row click behaviour\n\t\t\t\t\t$(this).parents('.ss-gridfield-item').find('.tempDisabledEditLink').addClass('edit-link').removeClass('tempDisabledEditLink');\n\t\t\t\t},\n\t\t\t\tonclick: function(e) {\n\t\t\t\t\t//check/uncheck checkbox when clicking cell\n\t\t\t\t\tvar cb = $(e.target).find('input');\n\t\t\t\t\tif ( !$(cb).prop('checked') ) $(cb).prop('checked', true);\n\t\t\t\t\telse $(cb).prop('checked', false);\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\t/**\n\t\t\t * Individual select checkbox behaviour\n\t\t\t */\n\t\t\t$('td.col-bulkSelect input').entwine({\n\t\t\t\tonmatch: function(){\n\t\t\t\t},\n\t\t\t\tonunmatch: function(){\n\t\t\t\t},\n\t\t\t\tonclick: function(e) {\n\t\t\t\t\t$(this).parents('.grid-field__table').find('input.bulkSelectAll').prop('checked', '');\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\t/**\n\t\t\t * Bulkselect checkbox behaviours\n\t\t\t */\n\t $('input.bulkSelectAll').entwine({\n\t onmatch: function(){\n\t\t\t\t},\n\t\t\t\tonunmatch: function(){\n\t\t\t\t},\n\t onclick: function()\n\t {\n\t var state = $(this).prop('checked');\n\t $(this).parents('.grid-field__table')\n\t \t\t\t .find('td.col-bulkSelect input')\n\t \t\t\t .prop('checked', state)\n\t \t\t\t .trigger('change');\n\t },\n\t getSelectRecordsID: function()\n\t {\n\t \treturn $(this).parents('.grid-field__table')\n\t\t\t\t\t \t\t\t\t.find('td.col-bulkSelect input:checked')\n\t\t\t\t\t \t\t\t\t.map(function() {\n\t\t\t\t\t \t\t\t\t\treturn parseInt( $(this).data('record') )\n\t\t\t\t\t \t\t\t\t})\n\t\t\t\t\t\t\t\t\t\t\t .get();\n\t }\n\t });\n\n\n\t /**\n\t * Bulk action dropdown behaviours\n\t */\n\t\t\t$('select.bulkActionName').entwine({\n\t\t\t\tonmatch: function(){\n\t\t\t\t},\n\t\t\t\tonunmatch: function(){\n\t\t\t\t},\n\t\t\t\tonchange: function(e)\n\t\t\t\t{\n\t\t\t\t\tvar value = $(this).val(),\n\t\t\t\t\t\t$parent = $(this).parents('.bulkManagerOptions'),\n\t\t\t\t\t\t$btn = $parent.find('.doBulkActionButton'),\n\t\t\t\t\t\tconfig = $btn.data('config');\n\n\t\t\t\t\t$.each( config, function( configKey, configData )\n\t\t\t\t\t{\n\t\t\t\t\t\tif ( configKey != value )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$btn.removeClass(configData['buttonClasses']);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t$btn.addClass(config[value]['buttonClasses']).addClass('btn-outline-secondary');\n\n\n\t\t\t\t\tif ( config[value]['icon'] )\n\t\t\t\t\t{\n\t\t\t\t\t\tvar $img = $btn.find('img');\n\n\t\t\t\t\t\tif ($img.length)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$img.attr('src', config[value]['icon']);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse{\n\t\t\t\t\t\t\t$btn.prepend('<img src=\"'+config[value]['icon']+'\" alt=\"\" />');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\t$btn.find('img').remove();\n\t\t\t\t\t}\n\n\n\t\t\t\t\tif ( config[value]['destructive'] )\n\t\t\t\t\t{\n\t\t\t\t\t\t$btn.addClass('btn-outline-danger');\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\t$btn.removeClass('btn-outline-danger');\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\t/**\n\t\t\t * bulk action button behaviours\n\t\t\t */\n\t\t\t$('.doBulkActionButton').entwine({\n\t\t\t\tonmatch: function(){\n\t\t\t\t},\n\t\t\t\tonunmatch: function(){\n\t\t\t\t},\n\t\t\t\tgetActionURL: function(action, url)\n\t\t\t\t{\n\t\t\t\t\tvar cacheBuster = new Date().getTime();\n\t\t\t\t\turl = url.split('?');\n\n\t\t\t\t\tif ( action )\n\t\t\t\t\t{\n\t\t\t\t\t\taction = '/' + action;\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\taction = '';\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( url[1] )\n\t\t\t\t\t{\n\t\t\t\t\t\turl = url[0] + action + '?' + url[1] + '&' + 'cacheBuster=' + cacheBuster;\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\turl = url[0] + action + '?' + 'cacheBuster=' + cacheBuster;\n\t\t\t\t\t}\n\t\t\t\t\treturn url;\n\t\t\t\t},\n\t\t\t\tonclick: function(e)\n\t\t\t\t{\n var $parent = $(this).parents('.bulkManagerOptions'),\n action = $parent.find('select.bulkActionName').val(),\n ids = $(this).parents('.bulkManagerOptions').find('input.bulkSelectAll:first').getSelectRecordsID()\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\tthis.doBulkAction(action, ids);\n\t\t\t\t},\n\n\t\t\t\tdoBulkAction: function(action, ids, callbackFunction, callbackContext)\n\t\t\t\t{\n var $parent = $(this).parents('.bulkManagerOptions'),\n $btn = $parent.find('a.doBulkActionButton'),\n\n config = $btn.data('config'),\n url = this.getActionURL(action, $(this).data('url')),\n data = { records: ids }\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\tif ( ids.length <= 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\talert( ss.i18n._t('GRIDFIELD_BULK_MANAGER.BULKACTION_EMPTY_SELECT') );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t//if ( $btn.hasClass('ss-ui-action-destructive') )\n\t\t\t\t\tif ( config[action]['destructive'] )\n\t\t\t\t\t{\n\t\t\t\t\t\tif( !confirm(ss.i18n._t('GRIDFIELD_BULK_MANAGER.CONFIRM_DESTRUCTIVE_ACTION')) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ( callbackFunction && callbackContext )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallbackFunction.call(callbackContext, false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$btn.addClass('loading');\n\n\t\t\t\t\tif ( config[action]['xhr'] )\n\t\t\t\t\t{\n\t\t\t\t\t\t$.ajax({\n\t\t\t\t\t\t\turl: url,\n\t\t\t\t\t\t\tdata: data,\n\t\t\t\t\t\t\ttype: \"POST\",\n\t\t\t\t\t\t\tcontext: $(this)\n\t\t\t\t\t\t}).done(function(data, textStatus, jqXHR) {\n\t $btn.removeClass('loading');\n\t if ( callbackFunction && callbackContext )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallbackFunction.call(callbackContext, data);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse{\n\t\t\t\t\t\t\t\t$(this).parents('.ss-gridfield').entwine('.').entwine('ss').reload();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tvar records = 'records[]='+ids.join('&records[]=');\n\t\t\t\t\t\turl = url + '&' + records;\n\n\t\t\t\t\t\twindow.location.href = url;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t});\n\t});\n}(jQuery));\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/src/js/manager.js\n// module id = 1\n// module chunks = 0","(function($) {\n $.entwine('colymba', function($) {\n\n /**\n * Toggle all accordion forms\n * open or closed\n */\n $('#bulkEditToggle') .entwine({\n onmatch: function(){},\n onunmatch: function(){},\n onclick: function(e)\n {\n var toggleFields = this.parents('form').find('.ss-toggle .ui-accordion-header'),\n state = this.data('state')\n ;\n\n if ( !state || state === 'close' )\n {\n state = 'open';\n }\n else {\n state = 'close';\n }\n\n toggleFields.each(function()\n {\n var $this = $(this);\n \n if ( state === 'open' && !$this.hasClass('ui-state-active') )\n {\n $this.click();\n }\n\n if ( state === 'close' && $this.hasClass('ui-state-active') )\n {\n $this.click();\n } \n });\n\n this.data('state', state);\n }\n });\n \n \n /**\n * Contains each rocrds editing fields,\n * tracks changes and updates...\n */\n $('.bulkEditingFieldHolder').entwine({\n onmatch: function(){},\n onunmatch: function(){},\n onchange: function(){\n this.removeClass('updated');\n if ( !this.hasClass('hasUpdate') )\n {\n this.addClass('hasUpdate');\n }\n }\n });\n \n });\n}(jQuery));\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/src/js/managerBulkEditingForm.js\n// module id = 2\n// module chunks = 0","(function($) {\t\n\t$.entwine('ss', function($) {\n\t\t\n\n\t\t$.entwine('colymba', function($) {\n\n /**\n * Makes sure the component is at the top :)\n */\n $('.bulkUploader').entwine({\n onmatch: function(){\n var $tr = this.parents('thead').find('tr'),\n $component = this.clone(),\n index = $tr.index(this)\n ;\n if ( index > 1 )\n {\n $component.insertAfter($tr.eq(0));\n this.remove();\n } \n },\n onunmatch: function(){}\n });\n\n\n /**\n * Track upload progress...\n */ \n $('ul.ss-uploadfield-files').entwine({\n onmatch: function(){},\n onunmatch: function(){},\n trackProgress: function()\n {\n var $li = this.find('li.ss-uploadfield-item'),\n total = $li.length,\n $done = $li.filter('.done'),\n done = $done.length,\n $errors = $li.not($done).find('.ui-state-warning-text,.ui-state-error-text'),\n errors = $errors.length\n ;\n \n this.parents('.ss-uploadfield').find('.colymba-bulkupload-buttons').refresh(total, done, errors);\n }\n });\n\n\n /**\n * Track new and canceled updloads\n */\n $('li.ss-uploadfield-item').entwine({\n onmatch: function(){\n this.parents('ul.ss-uploadfield-files').trackProgress();\n },\n onunmatch: function(){\n $('ul.ss-uploadfield-files').trackProgress();\n },\n });\n\n /**\n * Track updload warning/errors\n */\n $('li.ss-uploadfield-item .ui-state-warning-text,li.ss-uploadfield-item .ui-state-error-text').entwine({\n onmatch: function(){\n this.parents('ul.ss-uploadfield-files').trackProgress();\n },\n onunmatch: function(){\n $('ul.ss-uploadfield-files').trackProgress();\n },\n });\n\n\n /**\n * Update buttons state and progress info...\n */ \n $('.colymba-bulkupload-buttons').entwine({\n onmatch: function(){},\n onunmatch: function(){},\n refresh: function(total, done, error)\n {\n var $info = this.find('.colymba-bulkupload-info'),\n $editBtn = this.find('.bulkUploadEditButton'),\n $cancelBtn = this.find('.bulkUploadCancelButton'),\n $finishBtn = this.find('.bulkUploadFinishButton'),\n $clearErrorBtn = this.find('.bulkUploadClearErrorButton')\n ;\n\n if ( total > 0 )\n {\n this.css({display: 'block'});\n\n $info.html(ss.i18n.sprintf(\n ss.i18n._t('GRIDFIELD_BULK_UPLOAD.PROGRESS_INFO'),\n total,\n done,\n error\n ));\n\n $cancelBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');\n\n //if there are still uploads going\n if ( (done + error) < total )\n {\n if ( !this.hasClass('loading') )\n {\n this.addClass('loading');\n $finishBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'disabled');\n } \n }\n else{\n this.removeClass('loading');\n $finishBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');\n } \n\n //if all done and OK, enable edit\n if ( total === done )\n {\n $editBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');\n }\n else{\n $editBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');\n }\n\n //toggle clear error button\n if ( error > 0 )\n {\n $clearErrorBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');\n }\n else{\n $clearErrorBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');\n }\n }\n else{\n //if not uploading, reset + hide\n this.css({display: 'none'}).removeClass('loading');\n $editBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');\n $cancelBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');\n $finishBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');\n $clearErrorBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');\n } \n }\n });\n\n\n /**\n * Clears all updloads with warning or error\n */\n $('.bulkUploadClearErrorButton:not(.ui-state-disabled)').entwine({\n onmatch: function(){\n this.removeClass('action');\n },\n onunmatch: function(){},\n onclick: function(e)\n {\n var $bulkUpload = this.parents('.bulkUpload'),\n $errors = $bulkUpload.find('li.ss-uploadfield-item .ui-state-warning-text,li.ss-uploadfield-item .ui-state-error-text').parents('li')\n ;\n\n $($errors.get().reverse()).each(function(index, Element){ \n $(this).remove();\n });\n }\n });\n\n\n /**\n * Cancel all uploads\n * Clear the ones with warnings/error and delete dataObjects from the successful ones\n */\n $('.bulkUploadCancelButton:not(.ui-state-disabled)').entwine({\n onmatch: function(){\n this.removeClass('action');\n },\n onunmatch: function(){},\n onclick: function()\n {\n var $bulkUpload = this.parents('.bulkUpload'),\n $li = $bulkUpload.find('li.ss-uploadfield-item'),\n $records = $li.filter('[data-recordid]'),\n $other = $li.not($records),\n $doBulkActionButton = $bulkUpload.parents('.ss-gridfield-table').find('.doBulkActionButton'), \n recordsID\n ;\n\n $other.each(function(index, Element){\n // skip in progress \n $(this).remove();\n });\n\n if ( $doBulkActionButton.length > 0 )\n {\n recordsID = $records.map(function() { \n return parseInt( $(this).data('recordid') )\n }).get();\n\n this.addClass('loading');\n $doBulkActionButton.doBulkAction('delete', recordsID, this.cancelCallback, this);\n }\n },\n cancelCallback: function(data)\n {\n var $bulkUpload = this.parents('.bulkUpload'),\n $li = $bulkUpload.find('li.ss-uploadfield-item'),\n ids\n ;\n\n if ( data )\n {\n ids = data.records;\n\n $li.each(function(index, Element){\n var $this = $(this),\n recordID = parseInt( $this.data('recordid') )\n ;\n\n if ( ids.indexOf(recordID) !== -1 )\n {\n $this.remove();\n }\n });\n\n $(this).parents('.ss-gridfield').entwine('.').entwine('ss').reload();\n }\n\n this.removeClass('loading');\n }\n });\n\n \n /**\n * Clear all the warning/error/finished uploads\n */\n $('.bulkUploadFinishButton:not(.ui-state-disabled)').entwine({\n onmatch: function(){\n this.removeClass('action');\n },\n onunmatch: function(){},\n onclick: function()\n { \n var $bulkUpload = this.parents('.bulkUpload'),\n $li = $bulkUpload.find('li.ss-uploadfield-item')\n ;\n\n this.addClass('loading');\n $li.each(function(index, Element){\n // skip in progress \n $(this).remove();\n });\n\n $(this).parents('.ss-gridfield').entwine('.').entwine('ss').reload();\n \n this.removeClass('loading');\n }\n });\n\n $('.bulkUploadEditButton:not(.ui-state-disabled)').entwine({\n onmatch: function(){\n this.removeClass('action');\n },\n onunmatch: function(){},\n onclick: function()\n {\n var $bulkUpload = this.parents('.bulkUpload'),\n $li = $bulkUpload.find('li.ss-uploadfield-item'),\n $records = $li.filter('[data-recordid]'), \n recordsID,\n $doBulkActionButton = $bulkUpload.parents('.ss-gridfield-table').find('.doBulkActionButton')\n ;\n\n if ( $doBulkActionButton.length > 0 )\n {\n this.addClass('loading');\n\n recordsID = $records.map(function() { \n return parseInt( $(this).data('recordid') )\n }).get();\n\n $doBulkActionButton.doBulkAction('bulkedit', recordsID);\n }\n }\n });\n\n\t\t}); // colymba namespace\n\n\t}); // ss namespace\n}(jQuery));\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/src/js/uploader.js\n// module id = 3\n// module chunks = 0"],"sourceRoot":""}
|
1
client/dist/styles/bulkTools.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.cms table.grid-field__table tr.bulkManagerOptions th.bulkmanagerheading{padding-left:40px}.cms table.grid-field__table tr.bulkManagerOptions th.bulkmanagerselect{text-align:center}.cms table.grid-field__table tr.bulkManagerOptions th.bulkmanagerselect input{margin-left:0}.cms table.grid-field__table tr.bulkManagerOptions .title{margin:0 0 2px 2px}.cms table.grid-field__table tr.bulkManagerOptions .dropdown{display:inline-block;border:none;box-shadow:none;padding:0;margin:0;color:#000;vertical-align:top}.cms table.grid-field__table tr.bulkManagerOptions .doBulkActionButton img{height:20px}.cms table.grid-field__table tbody .col-bulkSelect{width:25px;text-align:center}#bulkEditHeader{float:left;width:70%;margin:40px 0 20px;font-size:30px;font-weight:700}#bulkEditToggle{float:right;clear:right;width:25%;margin:40px 0 20px;text-decoration:underline;text-align:right;cursor:pointer}.bulkEditingFieldHolder{position:relative;float:left;width:100%}.bulkEditingFieldHolder.hasUpdate .ui-accordion-header{background-color:#f2ba11;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0,#f2ba11),color-stop(100%,#df6e00));background-image:-webkit-linear-gradient(top,#f2ba11,#df6e00);background-image:-moz-linear-gradient(top,#f2ba11 0,#df6e00 100%);background-image:-o-linear-gradient(top,#f2ba11 0,#df6e00 100%);background-image:-ms-linear-gradient(top,#f2ba11 0,#df6e00 100%);background-image:linear-gradient(top,#f2ba11,#df6e00)}.bulkEditingFieldHolder.hasUpdate .ui-accordion-header a{color:#fff;text-shadow:none}.bulkEditingFieldHolder.updated .ui-accordion-header{background-color:#a4ca3a;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(0,#a4ca3a),color-stop(100%,#59781d));background-image:-webkit-linear-gradient(top,#a4ca3a,#59781d);background-image:-moz-linear-gradient(top,#a4ca3a 0,#59781d 100%);background-image:-o-linear-gradient(top,#a4ca3a 0,#59781d 100%);background-image:-ms-linear-gradient(top,#a4ca3a 0,#59781d 100%);background-image:linear-gradient(top,#a4ca3a,#59781d)}.bulkEditingFieldHolder.updated .ui-accordion-header a{color:#fff;text-shadow:none}.bulkUpload{padding:0!important;border-bottom:1px solid rgba(0,0,0,.1)}.bulkUpload:hover{background-color:#444546}.bulkUpload .component{padding:0!important;color:#fff;background:#98aab6;border-top:1px solid #a4b4bf;border-left:1px solid #a4b4bf;border-bottom:1px solid rgba(0,0,0,.1)}.bulkUpload .component div.ss-uploadfield{position:relative;float:left;clear:both;width:100%}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files{float:left;clear:both;width:100%}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item{position:relative;float:left;clear:both;overflow:hidden;width:98%;padding:5px 1%;border:none;border-top:1px solid rgba(0,0,0,.1);background-color:#eceff1}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item:nth-child(2n-1){background-color:#e6eaed}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-preview{width:30px;height:30px;line-height:38px}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info{height:30px;margin-left:40px;line-height:30px}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name{position:absolute;top:0;left:50px;width:100%;height:100%;line-height:40px}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .name{color:#343434}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .size{font-weight:400}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status{float:left;width:auto;padding:0 0 0 5px;text-align:left;max-width:none}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status.ui-state-warning-text{color:#f29500}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-name .ss-uploadfield-item-status.ui-state-success-text{color:#298530}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions{position:absolute;top:0;left:0;width:100%;height:30px;margin:0;padding:5px 0}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-progress{left:50px;right:35px;margin-top:8px}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions button{margin:0 10px 0 0}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions button .ui-button-text{padding-top:4px;padding-bottom:3px}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-cancel{position:relative;top:7px;right:auto;float:right}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-cancel button{background:none}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-files .ss-uploadfield-item .ss-uploadfield-item-info .ss-uploadfield-item-actions .ss-uploadfield-item-overwrite{position:relative;float:right;margin-top:2px}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile{float:left;clear:both;width:98%;padding:1%}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile.borderTop{border:none}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-preview.ss-uploadfield-dropzone{float:right;width:35%;height:43px;margin:0;line-height:43px;color:#eee;background-color:#8898a3;border:2px dashed #73818a;box-shadow:inset 0 0 10px 0 #73818a}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-preview.ss-uploadfield-dropzone.hover{color:#444546;background-color:#eee}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info{float:left;width:60%;margin:0}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-item-name{height:auto;margin-bottom:5px!important}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-item-name small{font-weight:400!important}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-ui-button .ui-button-text .ui-button-text{padding:0}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-fromcomputer{margin-bottom:0}.bulkUpload .component div.ss-uploadfield .ss-uploadfield-addfile .ss-uploadfield-item-info .ss-uploadfield-fromfiles{margin-bottom:0;padding:.5px}.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons{display:none;float:left;width:98%;padding:6px 1%;background-color:#8898a3}.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button{float:left;margin:0 6px 0 0}.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button .ui-button-text .ui-button-text{padding:0}.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button.bulkUploadClearErrorButton,.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons button.bulkUploadEditButton{float:right;margin:0 0 0 6px}.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons .colymba-bulkupload-info{float:left;margin:0 6px;line-height:28px;height:28px;color:#fff;overflow:hidden}.bulkUpload .component div.ss-uploadfield .colymba-bulkupload-buttons.loading .colymba-bulkupload-info{padding-left:20px;background-position:0 5px}
|
1
client/dist/styles/bulkTools.css.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":[],"names":[],"mappings":"","file":"styles/bulkTools.css","sourceRoot":""}
|
94
client/dist/styles/bundle.css
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
__webpack_require__(1);
|
||||
__webpack_require__(2);
|
||||
module.exports = __webpack_require__(3);
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
// removed by extract-text-webpack-plugin
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
// removed by extract-text-webpack-plugin
|
||||
|
||||
/***/ }),
|
||||
/* 3 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
// removed by extract-text-webpack-plugin
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
1
client/dist/styles/bundle.css.map
vendored
Normal file
@ -0,0 +1 @@
|
||||
{"version":3,"sources":["webpack:///webpack/bootstrap c1e0c772c911cc70bc24","webpack:///./client/src/styles/manager.scss","webpack:///./client/src/styles/managerBulkEditingForm.scss","webpack:///./client/src/styles/uploader.scss"],"names":[],"mappings":";AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA;;;;;;;;;;;;;;;;AC7DA,yC;;;;;;ACAA,yC;;;;;;ACAA,yC","file":"styles/bundle.css","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap c1e0c772c911cc70bc24","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/src/styles/manager.scss\n// module id = 1\n// module chunks = 0","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/src/styles/managerBulkEditingForm.scss\n// module id = 2\n// module chunks = 0","// removed by extract-text-webpack-plugin\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./client/src/styles/uploader.scss\n// module id = 3\n// module chunks = 0"],"sourceRoot":""}
|
@ -112,29 +112,44 @@
|
||||
},
|
||||
onchange: function(e)
|
||||
{
|
||||
var value = $(this).val(),
|
||||
$parent = $(this).parents('.bulkManagerOptions'),
|
||||
$btn = $parent.find('.doBulkActionButton'),
|
||||
config = $btn.data('config'),
|
||||
$icon = $parent.find('.doBulkActionButton .ui-icon')
|
||||
;
|
||||
var value = $(this).val(),
|
||||
$parent = $(this).parents('.bulkManagerOptions'),
|
||||
$btn = $parent.find('.doBulkActionButton'),
|
||||
config = $btn.data('config');
|
||||
|
||||
$.each( config, function( configKey, configData )
|
||||
{
|
||||
if ( configKey != value )
|
||||
{
|
||||
$icon.removeClass('btn-icon-'+configData['icon']);
|
||||
$btn.removeClass(configData['buttonClasses']);
|
||||
}
|
||||
});
|
||||
$icon.addClass('btn-icon-'+config[value]['icon']);
|
||||
$btn.addClass(config[value]['buttonClasses']).addClass('btn-outline-secondary');
|
||||
|
||||
|
||||
if ( config[value]['isDestructive'] )
|
||||
if ( config[value]['icon'] )
|
||||
{
|
||||
$btn.addClass('ss-ui-action-destructive');
|
||||
var $img = $btn.find('img');
|
||||
|
||||
if ($img.length)
|
||||
{
|
||||
$img.attr('src', config[value]['icon']);
|
||||
}
|
||||
else{
|
||||
$btn.prepend('<img src="'+config[value]['icon']+'" alt="" />');
|
||||
}
|
||||
}
|
||||
else{
|
||||
$btn.removeClass('ss-ui-action-destructive');
|
||||
$btn.find('img').remove();
|
||||
}
|
||||
|
||||
|
||||
if ( config[value]['destructive'] )
|
||||
{
|
||||
$btn.addClass('btn-outline-danger');
|
||||
}
|
||||
else{
|
||||
$btn.removeClass('btn-outline-danger');
|
||||
}
|
||||
|
||||
}
|
||||
@ -198,7 +213,7 @@
|
||||
}
|
||||
|
||||
//if ( $btn.hasClass('ss-ui-action-destructive') )
|
||||
if ( config[action]['isDestructive'] )
|
||||
if ( config[action]['destructive'] )
|
||||
{
|
||||
if( !confirm(ss.i18n._t('GRIDFIELD_BULK_MANAGER.CONFIRM_DESTRUCTIVE_ACTION')) )
|
||||
{
|
||||
@ -212,7 +227,7 @@
|
||||
|
||||
$btn.addClass('loading');
|
||||
|
||||
if ( config[action]['isAjax'] )
|
||||
if ( config[action]['xhr'] )
|
||||
{
|
||||
$.ajax({
|
||||
url: url,
|
@ -78,8 +78,6 @@
|
||||
refresh: function(total, done, error)
|
||||
{
|
||||
var $info = this.find('.colymba-bulkupload-info'),
|
||||
$editBtn = this.find('.bulkUploadEditButton'),
|
||||
$cancelBtn = this.find('.bulkUploadCancelButton'),
|
||||
$finishBtn = this.find('.bulkUploadFinishButton'),
|
||||
$clearErrorBtn = this.find('.bulkUploadClearErrorButton')
|
||||
;
|
||||
@ -95,8 +93,6 @@
|
||||
error
|
||||
));
|
||||
|
||||
$cancelBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
|
||||
|
||||
//if there are still uploads going
|
||||
if ( (done + error) < total )
|
||||
{
|
||||
@ -109,15 +105,6 @@
|
||||
else{
|
||||
this.removeClass('loading');
|
||||
$finishBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
|
||||
}
|
||||
|
||||
//if all done and OK, enable edit
|
||||
if ( total === done )
|
||||
{
|
||||
$editBtn.removeClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'false').removeAttr('disabled');
|
||||
}
|
||||
else{
|
||||
$editBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');
|
||||
}
|
||||
|
||||
//toggle clear error button
|
||||
@ -132,8 +119,6 @@
|
||||
else{
|
||||
//if not uploading, reset + hide
|
||||
this.css({display: 'none'}).removeClass('loading');
|
||||
$editBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');
|
||||
$cancelBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');
|
||||
$finishBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');
|
||||
$clearErrorBtn.addClass('ui-state-disabled ssui-button-disabled').attr('aria-disabled', 'true').attr('disabled', 'true');
|
||||
}
|
||||
@ -161,70 +146,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Cancel all uploads
|
||||
* Clear the ones with warnings/error and delete dataObjects from the successful ones
|
||||
*/
|
||||
$('.bulkUploadCancelButton:not(.ui-state-disabled)').entwine({
|
||||
onmatch: function(){
|
||||
this.removeClass('action');
|
||||
},
|
||||
onunmatch: function(){},
|
||||
onclick: function()
|
||||
{
|
||||
var $bulkUpload = this.parents('.bulkUpload'),
|
||||
$li = $bulkUpload.find('li.ss-uploadfield-item'),
|
||||
$records = $li.filter('[data-recordid]'),
|
||||
$other = $li.not($records),
|
||||
$doBulkActionButton = $bulkUpload.parents('.ss-gridfield-table').find('.doBulkActionButton'),
|
||||
recordsID
|
||||
;
|
||||
|
||||
$other.each(function(index, Element){
|
||||
// skip in progress
|
||||
$(this).remove();
|
||||
});
|
||||
|
||||
if ( $doBulkActionButton.length > 0 )
|
||||
{
|
||||
recordsID = $records.map(function() {
|
||||
return parseInt( $(this).data('recordid') )
|
||||
}).get();
|
||||
|
||||
this.addClass('loading');
|
||||
$doBulkActionButton.doBulkAction('delete', recordsID, this.cancelCallback, this);
|
||||
}
|
||||
},
|
||||
cancelCallback: function(data)
|
||||
{
|
||||
var $bulkUpload = this.parents('.bulkUpload'),
|
||||
$li = $bulkUpload.find('li.ss-uploadfield-item'),
|
||||
ids
|
||||
;
|
||||
|
||||
if ( data )
|
||||
{
|
||||
ids = data.records;
|
||||
|
||||
$li.each(function(index, Element){
|
||||
var $this = $(this),
|
||||
recordID = parseInt( $this.data('recordid') )
|
||||
;
|
||||
|
||||
if ( ids.indexOf(recordID) !== -1 )
|
||||
{
|
||||
$this.remove();
|
||||
}
|
||||
});
|
||||
|
||||
$(this).parents('.ss-gridfield').entwine('.').entwine('ss').reload();
|
||||
}
|
||||
|
||||
this.removeClass('loading');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Clear all the warning/error/finished uploads
|
||||
@ -252,33 +173,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
$('.bulkUploadEditButton:not(.ui-state-disabled)').entwine({
|
||||
onmatch: function(){
|
||||
this.removeClass('action');
|
||||
},
|
||||
onunmatch: function(){},
|
||||
onclick: function()
|
||||
{
|
||||
var $bulkUpload = this.parents('.bulkUpload'),
|
||||
$li = $bulkUpload.find('li.ss-uploadfield-item'),
|
||||
$records = $li.filter('[data-recordid]'),
|
||||
recordsID,
|
||||
$doBulkActionButton = $bulkUpload.parents('.ss-gridfield-table').find('.doBulkActionButton')
|
||||
;
|
||||
|
||||
if ( $doBulkActionButton.length > 0 )
|
||||
{
|
||||
this.addClass('loading');
|
||||
|
||||
recordsID = $records.map(function() {
|
||||
return parseInt( $(this).data('recordid') )
|
||||
}).get();
|
||||
|
||||
$doBulkActionButton.doBulkAction('bulkedit', recordsID);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}); // colymba namespace
|
||||
|
||||
}); // ss namespace
|
@ -36,19 +36,9 @@
|
||||
|
||||
.doBulkActionButton
|
||||
{
|
||||
.ui-button-text
|
||||
img
|
||||
{
|
||||
padding: 6px 0 5px 2.1em; //3px 0 2px 1.05em; //
|
||||
|
||||
.ui-button-text
|
||||
{
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.loading .ui-icon
|
||||
{
|
||||
background: transparent url(../../framework/images/network-save.gif) no-repeat 0 0;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}// .bulkManagerOptions
|
||||
@ -60,7 +50,7 @@
|
||||
width: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*
|
||||
td a.tempDisabledEditLink
|
||||
{
|
||||
background: url('../../framework/admin/images/btn-icon/document--pencil.png') no-repeat 2px 0px;
|
||||
@ -72,6 +62,6 @@
|
||||
vertical-align: middle;
|
||||
background-position: 2px 0px;
|
||||
background-repeat: no-repeat no-repeat;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
@import 'bourbon/bourbon';
|
||||
|
||||
.bulkUpload
|
||||
{
|
||||
padding: 0 !important;
|
||||
@ -284,9 +282,9 @@
|
||||
height: 28px;
|
||||
color: #ffffff;
|
||||
|
||||
background-image: url(../../images/spinner.gif);
|
||||
/*background-image: url(../../images/spinner.gif);
|
||||
background-position: 0 -50px;
|
||||
background-repeat: no-repeat;
|
||||
background-repeat: no-repeat;*/
|
||||
|
||||
overflow: hidden;
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "colymba/gridfield-bulk-editing-tools",
|
||||
"type": "silverstripe-module",
|
||||
"description": "SilverStripe GridField component to upload images and edit records in bulk",
|
||||
"type": "silverstripe-vendormodule",
|
||||
"description": "SilverStripe GridField component to upload images/files and edit records in bulk",
|
||||
"homepage": "https://github.com/colymba/GridFieldBulkEditingTools",
|
||||
"keywords": ["silverstripe", "bulk upload", "image upload", "gridfield bulk upload"],
|
||||
"license": "BSD Simplified",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Thierry Francois",
|
||||
@ -16,18 +16,22 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"silverstripe/framework": "^4.0@dev",
|
||||
"silverstripe/asset-admin": "^1.0@dev"
|
||||
"silverstripe/framework": "^4.0",
|
||||
"silverstripe/asset-admin": "^1.0"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"expose": [
|
||||
"client/dist",
|
||||
"client/lang"
|
||||
]
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Colymba\\BulkManager\\": "bulkManager/code/",
|
||||
"Colymba\\BulkUpload\\": "bulkUpload/code/"
|
||||
"Colymba\\BulkManager\\": "src/BulkManager/",
|
||||
"Colymba\\BulkUpload\\": "src/BulkUploader/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,20 +28,13 @@ To add a custom bulk action to the list use:
|
||||
```php
|
||||
$config
|
||||
->getComponentByType('Colymba\\BulkManager\\BulkManager')
|
||||
->addBulkAction('actionName', 'Dropdown label', 'ActionHandlerClassName', $frontEndConfig)
|
||||
->addBulkAction('Namespace\\ClassName')
|
||||
```
|
||||
|
||||
You can omit the handler's class name and the front-end config array, those will default to:
|
||||
* `'GridFieldBulkAction'.ucfirst($name).'Handler'`
|
||||
* `$config = array( 'isAjax' => true, 'icon' => 'accept', 'isDestructive' => false )`
|
||||
|
||||
#### Custom action handler
|
||||
When creating your own bulk action `RequestHandler`, you should extend `Colymba\BulkManager\BulkAction\Handler` which will expose 2 useful functions `getRecordIDList()` and `getRecords()` returning either an array with the selected records IDs or a `DataList` of the selected records.
|
||||
|
||||
Make sure to define your `$allowed_actions` and `$url_handlers` on your custom bulk action handler. See `Handler`, `DeleteHandler` and `UnlinkHandler` for examples.
|
||||
Make sure to define the handler's `$url_segment`, from which the handler will be called and its relating `$allowed_actions` and `$url_handlers`. See `Handler`, `DeleteHandler` and `UnlinkHandler` for examples.
|
||||
|
||||
#### Front-end config
|
||||
The last `addBulkAction()` parameter lets you pass an array with configuration options for the UI/UX:
|
||||
* `isAjax`: if true the action will be called via XHR request otherwise the browser will be redirected to the action's URL
|
||||
* `icon`: lets you define which icon to use on the button when the action is selected (SilverStripe button icon name only)
|
||||
* `isDestructive`: if true, a confirmation dialog will be shown before the action is processed
|
||||
Bulk action handler's front-end configuration is set via class properties `label`, `icon`, `buttonClasses`, `xhr` and `destructive`. See `Handler`, `DeleteHandler` and `UnlinkHandler` for reference and examples.
|
Before Width: | Height: | Size: 1.7 KiB |
37
package.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "colymba-gridfield-bulk-editing-tools",
|
||||
"version": "3.0.0",
|
||||
"description": "Bulk upload and record editing for SilverStripe CMS",
|
||||
"engines": {
|
||||
"node": "^6.x"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "NODE_ENV=production webpack -p --bail --progress",
|
||||
"watch": "NODE_ENV=development webpack --watch --progress"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/tractorcow/silverstripe-fluent.git"
|
||||
},
|
||||
"keywords": [
|
||||
"bulk",
|
||||
"manager",
|
||||
"upload",
|
||||
"silverstripe"
|
||||
],
|
||||
"author": "Thierry Francois",
|
||||
"license": "BSD-3-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/colymba/GridFieldBulkEditingTools/issues"
|
||||
},
|
||||
"homepage": "https://github.com/colymba/GridFieldBulkEditingTools",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"node-sass": "^4.7.2",
|
||||
"sass-loader": "^6.0",
|
||||
"css-loader": "^0.28",
|
||||
"style-loader": "^0.19",
|
||||
"extract-text-webpack-plugin": "^3.0",
|
||||
"webpack": "^3.10.0"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 164 KiB |
Before Width: | Height: | Size: 156 KiB |
Before Width: | Height: | Size: 177 KiB |
Before Width: | Height: | Size: 135 KiB |
112
src/BulkManager/BulkAction/DeleteHandler.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Colymba\BulkManager\BulkAction;
|
||||
|
||||
use Colymba\BulkManager\BulkAction\Handler;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
use SilverStripe\Core\Convert;
|
||||
|
||||
/**
|
||||
* Bulk action handler for deleting records.
|
||||
*
|
||||
* @author colymba
|
||||
*/
|
||||
class DeleteHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* URL segment used to call this handler
|
||||
* If none given, @BulkManager will fallback to the Unqualified class name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $url_segment = 'delete';
|
||||
|
||||
/**
|
||||
* RequestHandler allowed actions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $allowed_actions = array('delete');
|
||||
|
||||
/**
|
||||
* RequestHandler url => action map.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'' => 'delete',
|
||||
);
|
||||
|
||||
/**
|
||||
* Front-end label for this handler's action
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'Delete';
|
||||
|
||||
/**
|
||||
* Front-end icon path for this handler's action.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $icon = '';
|
||||
|
||||
/**
|
||||
* Extra classes to add to the bulk action button for this handler
|
||||
* Can also be used to set the button font-icon e.g. font-icon-trash
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $buttonClasses = 'font-icon-trash';
|
||||
|
||||
/**
|
||||
* Whether this handler should be called via an XHR from the front-end
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $xhr = true;
|
||||
|
||||
/**
|
||||
* Set to true is this handler will destroy any data.
|
||||
* A warning and confirmation will be shown on the front-end.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $destructive = true;
|
||||
|
||||
/**
|
||||
* Return i18n localized front-end label
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getI18nLabel()
|
||||
{
|
||||
return _t('GRIDFIELD_BULK_MANAGER.DELETE_SELECT_LABEL', $this->getLabel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the selected records passed from the delete bulk action.
|
||||
*
|
||||
* @param HTTPRequest $request
|
||||
*
|
||||
* @return HTTPResponse List of deleted records ID
|
||||
*/
|
||||
public function delete(HTTPRequest $request)
|
||||
{
|
||||
$ids = array();
|
||||
|
||||
foreach ($this->getRecords() as $record) {
|
||||
array_push($ids, $record->ID);
|
||||
$record->delete();
|
||||
}
|
||||
|
||||
$response = new HTTPResponse(Convert::raw2json(array(
|
||||
'done' => true,
|
||||
'records' => $ids,
|
||||
)));
|
||||
$response->addHeader('Content-Type', 'text/json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -21,6 +21,14 @@ use SilverStripe\View\Requirements;
|
||||
*/
|
||||
class EditHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* URL segment used to call this handler
|
||||
* If none given, @BulkManager will fallback to the Unqualified class name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $url_segment = 'edit';
|
||||
|
||||
/**
|
||||
* RequestHandler allowed actions.
|
||||
*
|
||||
@ -38,11 +46,58 @@ class EditHandler extends Handler
|
||||
* @var array
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'bulkEdit/bulkEditForm' => 'bulkEditForm',
|
||||
'bulkEdit/recordEditForm' => 'recordEditForm',
|
||||
'bulkEdit' => 'index',
|
||||
'bulkEditForm' => 'bulkEditForm',
|
||||
'recordEditForm' => 'recordEditForm',
|
||||
'' => 'index',
|
||||
);
|
||||
|
||||
/**
|
||||
* Front-end label for this handler's action
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'Edit';
|
||||
|
||||
/**
|
||||
* Front-end icon path for this handler's action.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $icon = '';
|
||||
|
||||
/**
|
||||
* Extra classes to add to the bulk action button for this handler
|
||||
* Can also be used to set the button font-icon e.g. font-icon-trash
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $buttonClasses = 'font-icon-edit';
|
||||
|
||||
/**
|
||||
* Whether this handler should be called via an XHR from the front-end
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $xhr = false;
|
||||
|
||||
/**
|
||||
* Set to true is this handler will destroy any data.
|
||||
* A warning and confirmation will be shown on the front-end.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $destructive = false;
|
||||
|
||||
/**
|
||||
* Return i18n localized front-end label
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getI18nLabel()
|
||||
{
|
||||
return _t('GRIDFIELD_BULK_MANAGER.EDIT_SELECT_LABEL', $this->getLabel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URL to this RequestHandler.
|
||||
*
|
||||
@ -52,7 +107,7 @@ class EditHandler extends Handler
|
||||
*/
|
||||
public function Link($action = null)
|
||||
{
|
||||
return Controller::join_links(parent::Link(), 'bulkEdit', $action);
|
||||
return Controller::join_links(parent::Link(), $this->stat('url_segment'), $action);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,9 +367,9 @@ class EditHandler extends Handler
|
||||
$form->addExtraClass('center cms-content');
|
||||
$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
|
||||
|
||||
Requirements::javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/GridFieldBulkEditingForm.js');
|
||||
Requirements::css(BULKEDITTOOLS_MANAGER_PATH . '/css/GridFieldBulkEditingForm.css');
|
||||
Requirements::add_i18n_javascript(BULKEDITTOOLS_PATH . '/lang/js');
|
||||
Requirements::javascript('colymba/gridfield-bulk-editing-tools:client/dist/js/bulkTools.js');
|
||||
Requirements::css('colymba/gridfield-bulk-editing-tools:client/dist/styles/bulkTools.css');
|
||||
Requirements::add_i18n_javascript('colymba/gridfield-bulk-editing-tools:lang');
|
||||
|
||||
if ($this->request->isAjax()) {
|
||||
$response = new HTTPResponse(
|
329
src/BulkManager/BulkAction/Handler.php
Normal file
@ -0,0 +1,329 @@
|
||||
<?php
|
||||
|
||||
namespace Colymba\BulkManager\BulkAction;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\RequestHandler;
|
||||
use SilverStripe\Forms\GridField\GridFieldDetailForm;
|
||||
use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
|
||||
/**
|
||||
* Base class to extend for all custom bulk action handlers
|
||||
* Gives access to the GridField, Component and Controller
|
||||
* and implements useful functions like {@link getRecordIDList()} and {@link getRecords()}.
|
||||
*
|
||||
* @author colymba
|
||||
*/
|
||||
class Handler extends RequestHandler
|
||||
{
|
||||
/**
|
||||
* URL segment used to call this handler
|
||||
* If none given, @BulkManager will fallback to the Unqualified class name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $url_segment = null;
|
||||
|
||||
/**
|
||||
* Related GridField instance.
|
||||
*
|
||||
* @var GridField
|
||||
*/
|
||||
protected $gridField;
|
||||
|
||||
/**
|
||||
* GridFieldBulkManager instance.
|
||||
*
|
||||
* @var GridFieldBulkManager
|
||||
*/
|
||||
protected $component;
|
||||
|
||||
/**
|
||||
* Current controller instance.
|
||||
*
|
||||
* @var Controller
|
||||
*/
|
||||
protected $controller;
|
||||
|
||||
/**
|
||||
* Front-end label for this handler's action
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'Action';
|
||||
|
||||
/**
|
||||
* Front-end icon path for this handler's action.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $icon = '';
|
||||
|
||||
/**
|
||||
* Extra classes to add to the bulk action button for this handler
|
||||
* Can also be used to set the button font-icon e.g. font-icon-trash
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $buttonClasses = '';
|
||||
|
||||
/**
|
||||
* Whether this handler should be called via an XHR from the front-end
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $xhr = true;
|
||||
|
||||
/**
|
||||
* Set to true is this handler will destroy any data.
|
||||
* A warning and confirmation will be shown on the front-end.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $destructive = false;
|
||||
|
||||
/**
|
||||
* @param GridField $gridField
|
||||
* @param GridField_URLHandler $component
|
||||
* @param Controller $controller
|
||||
*/
|
||||
public function __construct($gridField = null, $component = null, $controller = null)
|
||||
{
|
||||
$this->gridField = $gridField;
|
||||
$this->component = $component;
|
||||
$this->controller = $controller;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return front-end configuration
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
$config = array(
|
||||
'label' => $this->getI18nLabel(),
|
||||
'icon' => $this->getIcon(),
|
||||
'buttonClasses' => $this->getButtonClasses(),
|
||||
'xhr' => $this->getXhr(),
|
||||
'destructive' => $this->getDestructive()
|
||||
);
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if hanlder performs destructive actions
|
||||
*
|
||||
* @param boolean destructive If true, a warning will be shown on the front-end
|
||||
* @return RequestHandler
|
||||
*/
|
||||
public function setDestructive($destructive)
|
||||
{
|
||||
$this->destructive = $destructive;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the hanlder performs destructive actions
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getDestructive()
|
||||
{
|
||||
return $this->destructive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if handler is called via XHR
|
||||
*
|
||||
* @param boolean xhr If true the handler will be called via an XHR from front-end
|
||||
* @return RequestHandler
|
||||
*/
|
||||
|
||||
public function setXhr($xhr)
|
||||
{
|
||||
$this->xhr = $xhr;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if handler is called via XHR
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getXhr()
|
||||
{
|
||||
return $this->xhr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set front-end buttonClasses
|
||||
*
|
||||
* @return RequestHandler
|
||||
*/
|
||||
public function setButtonClasses($buttonClasses)
|
||||
{
|
||||
$this->buttonClasses = $buttonClasses;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return front-end buttonClasses
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getButtonClasses()
|
||||
{
|
||||
return $this->buttonClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set front-end icon
|
||||
*
|
||||
* @return RequestHandler
|
||||
*/
|
||||
public function setIcon($icon)
|
||||
{
|
||||
$this->icon = $icon;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return front-end icon
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getIcon()
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set front-end label
|
||||
*
|
||||
* @return RequestHandler
|
||||
*/
|
||||
public function setLabel($label)
|
||||
{
|
||||
$this->label = $label;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return front-end label
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return i18n localized front-end label
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getI18nLabel()
|
||||
{
|
||||
return _t('GRIDFIELD_BULK_MANAGER.HANDLER_LABEL', $this->getLabel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL for this RequestHandler.
|
||||
*
|
||||
* @author SilverStripe
|
||||
*
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
*
|
||||
* @param string $action
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function Link($action = null)
|
||||
{
|
||||
return Controller::join_links($this->gridField->Link(), 'bulkAction', $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse up nested requests until we reach the first that's not a GridFieldDetailForm or GridFieldDetailForm_ItemRequest.
|
||||
* The opposite of {@link Controller::curr()}, required because
|
||||
* Controller::$controller_stack is not directly accessible.
|
||||
*
|
||||
* @return Controller
|
||||
*/
|
||||
protected function getToplevelController()
|
||||
{
|
||||
$c = $this->controller;
|
||||
while ($c && ($c instanceof GridFieldDetailForm_ItemRequest || $c instanceof GridFieldDetailForm)) {
|
||||
$c = $c->getController();
|
||||
}
|
||||
|
||||
return $c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edited version of the GridFieldEditForm function
|
||||
* adds the 'Bulk Upload' at the end of the crums.
|
||||
*
|
||||
* CMS-specific functionality: Passes through navigation breadcrumbs
|
||||
* to the template, and includes the currently edited record (if any).
|
||||
* see {@link LeftAndMain->Breadcrumbs()} for details.
|
||||
*
|
||||
* @author SilverStripe original Breadcrumbs() method
|
||||
*
|
||||
* @see GridFieldDetailForm_ItemRequest
|
||||
*
|
||||
* @param bool $unlinked
|
||||
*
|
||||
* @return ArrayData
|
||||
*/
|
||||
public function Breadcrumbs($unlinked = false)
|
||||
{
|
||||
if (!$this->controller->hasMethod('Breadcrumbs')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$items = $this->controller->Breadcrumbs($unlinked);
|
||||
$items->push(new ArrayData(array(
|
||||
'Title' => 'Bulk Editing',
|
||||
'Link' => false,
|
||||
)));
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of record IDs selected in the front-end.
|
||||
*
|
||||
* @return array List of IDs
|
||||
*/
|
||||
public function getRecordIDList()
|
||||
{
|
||||
$vars = $this->request->requestVars();
|
||||
|
||||
return $vars['records'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DataList of the records selected in the front-end.
|
||||
*
|
||||
* @return DataList List of records
|
||||
*/
|
||||
public function getRecords()
|
||||
{
|
||||
$ids = $this->getRecordIDList();
|
||||
|
||||
if ($ids) {
|
||||
$class = $this->gridField->list->dataClass;
|
||||
|
||||
return DataList::create($class)->byIDs($ids);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
108
src/BulkManager/BulkAction/UnlinkHandler.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Colymba\BulkManager\BulkAction;
|
||||
|
||||
use Colymba\BulkManager\BulkAction\Handler;
|
||||
use SilverStripe\Core\Convert;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Control\HTTPResponse;
|
||||
|
||||
/**
|
||||
* Bulk action handler for unlinking records.
|
||||
*
|
||||
* @author colymba
|
||||
*/
|
||||
class UnlinkHandler extends Handler
|
||||
{
|
||||
/**
|
||||
* URL segment used to call this handler
|
||||
* If none given, @BulkManager will fallback to the Unqualified class name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $url_segment = 'unlink';
|
||||
|
||||
/**
|
||||
* RequestHandler allowed actions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $allowed_actions = array('unLink');
|
||||
|
||||
/**
|
||||
* RequestHandler url => action map.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $url_handlers = array(
|
||||
'' => 'unLink',
|
||||
);
|
||||
|
||||
/**
|
||||
* Front-end label for this handler's action
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $label = 'Unlink';
|
||||
|
||||
/**
|
||||
* Front-end icon path for this handler's action.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $icon = '';
|
||||
|
||||
/**
|
||||
* Extra classes to add to the bulk action button for this handler
|
||||
* Can also be used to set the button font-icon e.g. font-icon-trash
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $buttonClasses = 'font-icon-link-broken';
|
||||
|
||||
/**
|
||||
* Whether this handler should be called via an XHR from the front-end
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $xhr = true;
|
||||
|
||||
/**
|
||||
* Set to true is this handler will destroy any data.
|
||||
* A warning and confirmation will be shown on the front-end.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $destructive = false;
|
||||
|
||||
/**
|
||||
* Return i18n localized front-end label
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getI18nLabel()
|
||||
{
|
||||
return _t('GRIDFIELD_BULK_MANAGER.UNLINK_SELECT_LABEL', $this->getLabel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlink the selected records passed from the unlink bulk action.
|
||||
*
|
||||
* @param HTTPRequest $request
|
||||
*
|
||||
* @return HTTPResponse List of affected records ID
|
||||
*/
|
||||
public function unLink(HTTPRequest $request)
|
||||
{
|
||||
$ids = $this->getRecordIDList();
|
||||
$this->gridField->list->removeMany($ids);
|
||||
|
||||
$response = new HTTPResponse(Convert::raw2json(array(
|
||||
'done' => true,
|
||||
'records' => $ids,
|
||||
)));
|
||||
$response->addHeader('Content-Type', 'text/json');
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Colymba\BulkManager;
|
||||
|
||||
use ReflectionClass;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
@ -24,7 +25,7 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
* component configuration.
|
||||
*
|
||||
* 'editableFields' => fields editable on the Model
|
||||
* 'actions' => maps of action name and configuration
|
||||
* 'actions' => maps of action URL and Handler Class
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@ -46,35 +47,9 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
}
|
||||
|
||||
if ($defaultActions) {
|
||||
$this->config['actions'] = array(
|
||||
'bulkEdit' => array(
|
||||
'label' => _t('GRIDFIELD_BULK_MANAGER.EDIT_SELECT_LABEL', 'Edit'),
|
||||
'handler' => 'Colymba\\BulkManager\\BulkAction\\EditHandler',
|
||||
'config' => array(
|
||||
'isAjax' => false,
|
||||
'icon' => 'pencil',
|
||||
'isDestructive' => false,
|
||||
),
|
||||
),
|
||||
'unLink' => array(
|
||||
'label' => _t('GRIDFIELD_BULK_MANAGER.UNLINK_SELECT_LABEL', 'UnLink'),
|
||||
'handler' => 'Colymba\\BulkManager\\BulkAction\\UnlinkHandler',
|
||||
'config' => array(
|
||||
'isAjax' => true,
|
||||
'icon' => 'chain--minus',
|
||||
'isDestructive' => false,
|
||||
),
|
||||
),
|
||||
'delete' => array(
|
||||
'label' => _t('GRIDFIELD_BULK_MANAGER.DELETE_SELECT_LABEL', 'Delete'),
|
||||
'handler' => 'Colymba\\BulkManager\\BulkAction\\DeleteHandler',
|
||||
'config' => array(
|
||||
'isAjax' => true,
|
||||
'icon' => 'decline',
|
||||
'isDestructive' => true,
|
||||
),
|
||||
)
|
||||
);
|
||||
$this->addBulkAction('Colymba\\BulkManager\\BulkAction\\EditHandler')
|
||||
->addBulkAction('Colymba\\BulkManager\\BulkAction\\UnlinkHandler')
|
||||
->addBulkAction('Colymba\\BulkManager\\BulkAction\\DeleteHandler');
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,49 +100,28 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
|
||||
/**
|
||||
* Lets you add custom bulk actions to the bulk manager interface.
|
||||
* Exisiting handler will be replaced
|
||||
*
|
||||
* @todo add config options for front-end: isAjax, icon
|
||||
*
|
||||
* @param string $name Bulk action's name. Used by RequestHandler.
|
||||
* @param string $label Dropdown menu action's label. Default to ucfirst($name).
|
||||
* @param string $handler RequestHandler class name for this action. Default to 'GridFieldBulkAction'.ucfirst($name).'Handler'
|
||||
* @param array $config Front-end configuration array( 'isAjax' => true, 'icon' => 'accept', 'isDestructive' => false )
|
||||
* @param string $hanlderClassName RequestHandler class name for this action.
|
||||
* @param string $action Specific RequestHandler action to be called.
|
||||
*
|
||||
* @return GridFieldBulkManager Current GridFieldBulkManager instance
|
||||
*/
|
||||
public function addBulkAction($name, $label = null, $handler = null, $config = null)
|
||||
public function addBulkAction($hanlderClassName, $action = null)
|
||||
{
|
||||
if (array_key_exists($name, $this->config['actions'])) {
|
||||
user_error("Bulk action '$name' already exists.", E_USER_ERROR);
|
||||
if (!$hanlderClassName || !ClassInfo::exists($hanlderClassName)) {
|
||||
user_error("Bulk action handler not found: $handler", E_USER_ERROR);
|
||||
}
|
||||
|
||||
if (!$label) {
|
||||
$label = ucfirst($name);
|
||||
$handler = Injector::inst()->get($hanlderClassName);
|
||||
$urlSegment = $handler->config()->get('url_segment');
|
||||
if (!$urlSegment)
|
||||
{
|
||||
$rc = new ReflectionClass($hanlderClassName);
|
||||
$urlSegment = $rc->getShortName();
|
||||
}
|
||||
|
||||
if (!$handler) {
|
||||
$handler = 'Colymba\\BulkManager\\BulkAction\\' . ucfirst($name) . 'Handler';
|
||||
}
|
||||
|
||||
if (!ClassInfo::exists($handler)) {
|
||||
user_error("Bulk action handler for $name not found: $handler", E_USER_ERROR);
|
||||
}
|
||||
|
||||
if ($config && !is_array($config)) {
|
||||
user_error('Bulk action front-end config should be an array of key => value pairs.', E_USER_ERROR);
|
||||
} else {
|
||||
$config = array(
|
||||
'isAjax' => isset($config['isAjax']) ? $config['isAjax'] : true,
|
||||
'icon' => isset($config['icon']) ? $config['icon'] : 'accept',
|
||||
'isDestructive' => isset($config['isDestructive']) ? $config['isDestructive'] : false,
|
||||
);
|
||||
}
|
||||
|
||||
$this->config['actions'][$name] = array(
|
||||
'label' => $label,
|
||||
'handler' => $handler,
|
||||
'config' => $config,
|
||||
);
|
||||
$this->config['actions'][$urlSegment] = $hanlderClassName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -175,19 +129,27 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
/**
|
||||
* Removes a bulk actions from the bulk manager interface.
|
||||
*
|
||||
* @param string $name Bulk action's name
|
||||
* @param string $hanlderClassName RequestHandler class name of the action to remove.
|
||||
* @param string $urlSegment URL segment of the action to remove.
|
||||
*
|
||||
* @return GridFieldBulkManager Current GridFieldBulkManager instance
|
||||
*/
|
||||
public function removeBulkAction($name)
|
||||
public function removeBulkAction($hanlderClassName = null, $urlSegment = null)
|
||||
{
|
||||
if (!array_key_exists($name, $this->config['actions'])) {
|
||||
user_error("Bulk action '$name' doesn't exists.", E_USER_ERROR);
|
||||
if (!$hanlderClassName && !$urlSegment) {
|
||||
user_error("Provide either a class name or URL segment", E_USER_ERROR);
|
||||
}
|
||||
|
||||
unset($this->config['actions'][$name]);
|
||||
foreach ($this->config['actions'] as $url => $class)
|
||||
{
|
||||
if ($hanlderClassName === $class || $urlSegment === $url)
|
||||
{
|
||||
unset($this->config['actions'][$url]);
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
user_error("Bulk action '$hanlderClassName' or '$urlSegment' doesn't exists.", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/* **********************************************************************
|
||||
@ -277,9 +239,9 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
*/
|
||||
public function getHTMLFragments($gridField)
|
||||
{
|
||||
Requirements::css(BULKEDITTOOLS_MANAGER_PATH . '/css/GridFieldBulkManager.css');
|
||||
Requirements::javascript(BULKEDITTOOLS_MANAGER_PATH . '/javascript/GridFieldBulkManager.js');
|
||||
Requirements::add_i18n_javascript(BULKEDITTOOLS_PATH . '/lang/js');
|
||||
Requirements::javascript('colymba/gridfield-bulk-editing-tools:client/dist/js/bulkTools.js');
|
||||
Requirements::css('colymba/gridfield-bulk-editing-tools:client/dist/styles/bulkTools.css');
|
||||
Requirements::add_i18n_javascript('colymba/gridfield-bulk-editing-tools:lang');
|
||||
|
||||
if (!count($this->config['actions'])) {
|
||||
user_error('Trying to use GridFieldBulkManager without any bulk action.', E_USER_ERROR);
|
||||
@ -288,25 +250,32 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
$actionsListSource = array();
|
||||
$actionsConfig = array();
|
||||
|
||||
foreach ($this->config['actions'] as $action => $actionData) {
|
||||
$actionsListSource[$action] = $actionData['label'];
|
||||
$actionsConfig[$action] = $actionData['config'];
|
||||
}
|
||||
foreach ($this->config['actions'] as $urlSegment => $hanlderClassName) {
|
||||
$handler = Injector::inst()->get($hanlderClassName);
|
||||
$handlerConfig = $handler->getConfig();
|
||||
|
||||
reset($this->config['actions']);
|
||||
$firstAction = key($this->config['actions']);
|
||||
$actionsListSource[$urlSegment] = $handlerConfig['label'];
|
||||
$actionsConfig[$urlSegment] = $handlerConfig;
|
||||
}
|
||||
|
||||
$dropDownActionsList = DropdownField::create('bulkActionName', '')
|
||||
->setSource($actionsListSource)
|
||||
->addExtraClass('bulkActionName no-change-track no-chosen')
|
||||
->setAttribute('id', '');
|
||||
|
||||
reset($actionsListSource);
|
||||
$firstAction = key($actionsListSource);
|
||||
|
||||
$buttonClasses = $actionsConfig[$firstAction]['buttonClasses'];
|
||||
$buttonClasses .= ($actionsConfig[$firstAction]['destructive'] ? ' btn-outline-danger' : '');
|
||||
|
||||
$templateData = array(
|
||||
'Menu' => $dropDownActionsList,
|
||||
'Button' => array(
|
||||
'Label' => _t('GRIDFIELD_BULK_MANAGER.ACTION_BTN_LABEL', 'Go'),
|
||||
'DataURL' => $gridField->Link('bulkAction'),
|
||||
'Icon' => $this->config['actions'][$firstAction]['config']['icon'],
|
||||
'Icon' => $actionsConfig[$firstAction]['icon'],
|
||||
'Classes' => $buttonClasses,
|
||||
'DataConfig' => json_encode($actionsConfig),
|
||||
),
|
||||
'Select' => array(
|
||||
@ -318,7 +287,7 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
$templateData = new ArrayData($templateData);
|
||||
|
||||
return array(
|
||||
'header' => $templateData->renderWith('BulkManagerButtons'),
|
||||
'header' => $templateData->renderWith('Colymba\\BulkManager\\BulkManagerButtons'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -356,23 +325,16 @@ class BulkManager implements GridField_HTMLProvider, GridField_ColumnProvider, G
|
||||
public function handleBulkAction($gridField, $request)
|
||||
{
|
||||
$controller = $gridField->getForm()->getController();
|
||||
|
||||
$actionUrlSegment = $request->shift();
|
||||
$handlerClass = $this->config['actions'][$actionUrlSegment];
|
||||
|
||||
foreach ($this->config['actions'] as $name => $data) {
|
||||
$handlerClass = $data['handler'];
|
||||
$urlHandlers = Config::inst()->get($handlerClass, 'url_handlers', Config::UNINHERITED);
|
||||
|
||||
if ($urlHandlers) {
|
||||
foreach ($urlHandlers as $rule => $action) {
|
||||
if ($request->match($rule, false)) {
|
||||
//print_r('matched ' . $handlerClass . ' to ' . $rule);
|
||||
$handler = Injector::inst()->create($handlerClass, $gridField, $this, $controller);
|
||||
|
||||
return $handler->handleRequest($request);
|
||||
}
|
||||
}
|
||||
}
|
||||
$handler = Injector::inst()->create($handlerClass, $gridField, $this, $controller);
|
||||
if ($handler)
|
||||
{
|
||||
return $handler->handleRequest($request);
|
||||
}
|
||||
|
||||
user_error('Unable to find matching bulk action handler for ' . $request->remaining() . '.', E_USER_ERROR);
|
||||
user_error('Unable to find matching bulk action handler for ' . $actionUrlSegment . ' URL segment.', E_USER_ERROR);
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
namespace Colymba\BulkUpload;
|
||||
|
||||
use Colymba\BulkUpload\BulkUploaderRequest;
|
||||
use Colymba\BulkUpload\BulkUploadField;
|
||||
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Dev\Deprecation;
|
||||
use SilverStripe\Forms\FormAction;
|
||||
@ -105,17 +107,7 @@ class BulkUploader implements GridField_HTMLProvider, GridField_URLHandler
|
||||
*/
|
||||
public function setConfig($reference, $value)
|
||||
{
|
||||
if (in_array($reference, array('folderName', 'maxFileSize', 'sequentialUploads', 'canAttachExisting', 'canPreviewFolder'))) {
|
||||
Deprecation::notice('2.1.0', "BulkUploader 'setConfig()' doesn't support '$reference' anymore. Please use 'setUfConfig()', 'setUfSetup()' or 'setUfValidatorSetup()' instead.");
|
||||
|
||||
if ($reference === 'folderName') {
|
||||
$this->setUfSetup('setFolderName', $value);
|
||||
} elseif ($reference === 'maxFileSize') {
|
||||
$this->setUfValidatorSetup('setAllowedMaxFileSize', $value);
|
||||
} else {
|
||||
$this->setUfConfig($reference, $value);
|
||||
}
|
||||
} elseif (!array_key_exists($reference, $this->config)) {
|
||||
if (!array_key_exists($reference, $this->config)) {
|
||||
user_error("Unknown option reference: $reference", E_USER_ERROR);
|
||||
}
|
||||
|
||||
@ -377,10 +369,7 @@ class BulkUploader implements GridField_HTMLProvider, GridField_URLHandler
|
||||
if (!singleton($gridField->getModelClass())->canEdit()) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// check BulkManager exists
|
||||
$bulkManager = $gridField->getConfig()->getComponentsByType('Colymba\\BulkManager\\BulkManager');
|
||||
|
||||
|
||||
// upload management buttons
|
||||
$finishButton = FormAction::create('Finish', _t('GRIDFIELD_BULK_UPLOAD.FINISH_BTN_LABEL', 'Finish'))
|
||||
->addExtraClass('bulkUploadFinishButton')
|
||||
@ -392,44 +381,19 @@ class BulkUploader implements GridField_HTMLProvider, GridField_URLHandler
|
||||
->setAttribute('data-icon', 'arrow-circle-double')
|
||||
->setUseButtonTag(true);
|
||||
|
||||
if (count($bulkManager)) {
|
||||
$cancelButton = FormAction::create('Cancel', _t('GRIDFIELD_BULK_UPLOAD.CANCEL_BTN_LABEL', 'Cancel'))
|
||||
->addExtraClass('bulkUploadCancelButton ss-ui-action-destructive')
|
||||
->setAttribute('data-icon', 'decline')
|
||||
->setAttribute('data-url', $gridField->Link('bulkupload/cancel'))
|
||||
->setUseButtonTag(true);
|
||||
|
||||
$bulkManager_config = $bulkManager->first()->getConfig();
|
||||
$bulkManager_actions = $bulkManager_config['actions'];
|
||||
if (array_key_exists('bulkedit', $bulkManager_actions)) {
|
||||
$editAllButton = FormAction::create('EditAll', _t('GRIDFIELD_BULK_UPLOAD.EDIT_ALL_BTN_LABEL', 'Edit all'))
|
||||
->addExtraClass('bulkUploadEditButton')
|
||||
->setAttribute('data-icon', 'pencil')
|
||||
->setAttribute('data-url', $gridField->Link('bulkupload/edit'))
|
||||
->setUseButtonTag(true);
|
||||
} else {
|
||||
$editAllButton = '';
|
||||
}
|
||||
} else {
|
||||
$cancelButton = '';
|
||||
$editAllButton = '';
|
||||
}
|
||||
|
||||
// get uploadField + inject extra buttons
|
||||
// get uploadField
|
||||
$uploadField = $this->bulkUploadField($gridField);
|
||||
$uploadField->FinishButton = $finishButton;
|
||||
$uploadField->CancelButton = $cancelButton;
|
||||
$uploadField->EditAllButton = $editAllButton;
|
||||
$uploadField->ClearErrorButton = $clearErrorButton;
|
||||
|
||||
$data = ArrayData::create(array(
|
||||
'Finish' => $finishButton,
|
||||
'ClearErrors' => $clearErrorButton,
|
||||
'Colspan' => (count($gridField->getColumns())),
|
||||
'UploadField' => $uploadField->Field() // call ->Field() to get requirements in right order
|
||||
));
|
||||
|
||||
Requirements::css(BULKEDITTOOLS_UPLOAD_PATH . '/css/GridFieldBulkUpload.css');
|
||||
Requirements::javascript(BULKEDITTOOLS_UPLOAD_PATH . '/javascript/GridFieldBulkUpload.js');
|
||||
Requirements::add_i18n_javascript(BULKEDITTOOLS_PATH . '/lang/js');
|
||||
Requirements::javascript('colymba/gridfield-bulk-editing-tools:client/dist/js/bulkTools.js');
|
||||
Requirements::css('colymba/gridfield-bulk-editing-tools:client/dist/styles/bulkTools.css');
|
||||
Requirements::add_i18n_javascript('colymba/gridfield-bulk-editing-tools:lang');
|
||||
|
||||
return array(
|
||||
'header' => $data->renderWith('Colymba\\BulkUpload\\BulkUploader'),
|
@ -8,8 +8,8 @@
|
||||
$Menu
|
||||
<a data-url="$Button.DataURL"
|
||||
data-config="$Button.DataConfig"
|
||||
class="doBulkActionButton btn btn-primary"
|
||||
data-icon="$Button.Icon">
|
||||
class="doBulkActionButton btn btn-outline-secondary $Button.Classes">
|
||||
<% if $Button.Icon %><img src="$Button.Icon" alt="" /><% end_if %>
|
||||
$Button.Label
|
||||
</a>
|
||||
<label class="form-check-label">
|
@ -1,5 +1,7 @@
|
||||
<tr class="bulkUploader">
|
||||
<th class="" colspan="$Colspan">
|
||||
$UploadField
|
||||
$Finish
|
||||
$ClearErrors
|
||||
</th>
|
||||
</tr>
|
56
webpack.config.js
Normal file
@ -0,0 +1,56 @@
|
||||
const path = require('path');
|
||||
|
||||
const PATHS = {
|
||||
ROOT: path.resolve(),
|
||||
SRC: path.resolve('client/src'),
|
||||
DIST: path.resolve('client/dist'),
|
||||
};
|
||||
|
||||
const ENV = process.env.NODE_ENV;
|
||||
|
||||
|
||||
const ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
const extractSASS = new ExtractTextPlugin({ filename: 'styles/bulkTools.css' });
|
||||
|
||||
|
||||
const config = [
|
||||
{
|
||||
name: 'js',
|
||||
entry: [
|
||||
`${PATHS.SRC}/js/manager.js`,
|
||||
`${PATHS.SRC}/js/managerBulkEditingForm.js`,
|
||||
`${PATHS.SRC}/js/uploader.js`
|
||||
],
|
||||
output: {
|
||||
path: PATHS.DIST,
|
||||
filename: 'js/bulkTools.js'
|
||||
},
|
||||
devtool: (ENV !== 'production') ? 'source-map' : ''
|
||||
},{
|
||||
name: 'scss',
|
||||
entry: [
|
||||
`${PATHS.SRC}/styles/manager.scss`,
|
||||
`${PATHS.SRC}/styles/managerBulkEditingForm.scss`,
|
||||
`${PATHS.SRC}/styles/uploader.scss`
|
||||
],
|
||||
output: {
|
||||
path: PATHS.DIST,
|
||||
filename: 'styles/bundle.css'
|
||||
},
|
||||
devtool: (ENV !== 'production') ? 'source-map' : '',
|
||||
module: {
|
||||
rules: [{
|
||||
test: /\.scss$/,
|
||||
use: extractSASS.extract({
|
||||
fallback: 'style-loader',
|
||||
use: [ 'css-loader', 'sass-loader' ]
|
||||
})
|
||||
}]
|
||||
},
|
||||
plugins: [
|
||||
extractSASS
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = config;
|