mirror of
https://github.com/grocy/grocy.git
synced 2025-08-13 09:17:26 +00:00
Started working on user-defined-fields for all entities (references #176)
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
use \Grocy\Services\BatteriesService;
|
use \Grocy\Services\BatteriesService;
|
||||||
use \Grocy\Services\UsersService;
|
use \Grocy\Services\UsersService;
|
||||||
|
use \Grocy\Services\UserfieldsService;
|
||||||
|
|
||||||
class BatteriesController extends BaseController
|
class BatteriesController extends BaseController
|
||||||
{
|
{
|
||||||
@@ -11,9 +12,11 @@ class BatteriesController extends BaseController
|
|||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
$this->BatteriesService = new BatteriesService();
|
$this->BatteriesService = new BatteriesService();
|
||||||
|
$this->UserfieldsService = new UserfieldsService();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $BatteriesService;
|
protected $BatteriesService;
|
||||||
|
protected $UserfieldsService;
|
||||||
|
|
||||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
@@ -23,7 +26,9 @@ class BatteriesController extends BaseController
|
|||||||
return $this->AppContainer->view->render($response, 'batteriesoverview', [
|
return $this->AppContainer->view->render($response, 'batteriesoverview', [
|
||||||
'batteries' => $this->Database->batteries()->orderBy('name'),
|
'batteries' => $this->Database->batteries()->orderBy('name'),
|
||||||
'current' => $this->BatteriesService->GetCurrent(),
|
'current' => $this->BatteriesService->GetCurrent(),
|
||||||
'nextXDays' => $nextXDays
|
'nextXDays' => $nextXDays,
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('batteries'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('batteries')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +42,9 @@ class BatteriesController extends BaseController
|
|||||||
public function BatteriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function BatteriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'batteries', [
|
return $this->AppContainer->view->render($response, 'batteries', [
|
||||||
'batteries' => $this->Database->batteries()->orderBy('name')
|
'batteries' => $this->Database->batteries()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('batteries'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('batteries')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,14 +53,16 @@ class BatteriesController extends BaseController
|
|||||||
if ($args['batteryId'] == 'new')
|
if ($args['batteryId'] == 'new')
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'batteryform', [
|
return $this->AppContainer->view->render($response, 'batteryform', [
|
||||||
'mode' => 'create'
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('batteries')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'batteryform', [
|
return $this->AppContainer->view->render($response, 'batteryform', [
|
||||||
'battery' => $this->Database->batteries($args['batteryId']),
|
'battery' => $this->Database->batteries($args['batteryId']),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('batteries')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
use \Grocy\Services\ChoresService;
|
use \Grocy\Services\ChoresService;
|
||||||
use \Grocy\Services\UsersService;
|
use \Grocy\Services\UsersService;
|
||||||
|
use \Grocy\Services\UserfieldsService;
|
||||||
|
|
||||||
class ChoresController extends BaseController
|
class ChoresController extends BaseController
|
||||||
{
|
{
|
||||||
@@ -11,9 +12,11 @@ class ChoresController extends BaseController
|
|||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
$this->ChoresService = new ChoresService();
|
$this->ChoresService = new ChoresService();
|
||||||
|
$this->UserfieldsService = new UserfieldsService();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $ChoresService;
|
protected $ChoresService;
|
||||||
|
protected $UserfieldsService;
|
||||||
|
|
||||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
@@ -23,7 +26,9 @@ class ChoresController extends BaseController
|
|||||||
return $this->AppContainer->view->render($response, 'choresoverview', [
|
return $this->AppContainer->view->render($response, 'choresoverview', [
|
||||||
'chores' => $this->Database->chores()->orderBy('name'),
|
'chores' => $this->Database->chores()->orderBy('name'),
|
||||||
'currentChores' => $this->ChoresService->GetCurrent(),
|
'currentChores' => $this->ChoresService->GetCurrent(),
|
||||||
'nextXDays' => $nextXDays
|
'nextXDays' => $nextXDays,
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('chores'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('chores')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +43,9 @@ class ChoresController extends BaseController
|
|||||||
public function ChoresList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function ChoresList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'chores', [
|
return $this->AppContainer->view->render($response, 'chores', [
|
||||||
'chores' => $this->Database->chores()->orderBy('name')
|
'chores' => $this->Database->chores()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('chores'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('chores')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +64,8 @@ class ChoresController extends BaseController
|
|||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'choreform', [
|
return $this->AppContainer->view->render($response, 'choreform', [
|
||||||
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService'),
|
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService'),
|
||||||
'mode' => 'create'
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('chores')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -65,7 +73,8 @@ class ChoresController extends BaseController
|
|||||||
return $this->AppContainer->view->render($response, 'choreform', [
|
return $this->AppContainer->view->render($response, 'choreform', [
|
||||||
'chore' => $this->Database->chores($args['choreId']),
|
'chore' => $this->Database->chores($args['choreId']),
|
||||||
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService'),
|
'periodTypes' => GetClassConstants('\Grocy\Services\ChoresService'),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('chores')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,18 @@
|
|||||||
|
|
||||||
namespace Grocy\Controllers;
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
|
use \Grocy\Services\UserfieldsService;
|
||||||
|
|
||||||
class GenericEntityApiController extends BaseApiController
|
class GenericEntityApiController extends BaseApiController
|
||||||
{
|
{
|
||||||
|
public function __construct(\Slim\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
$this->UserfieldsService = new UserfieldsService();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $UserfieldsService;
|
||||||
|
|
||||||
public function GetObjects(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function GetObjects(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
if ($this->IsValidEntity($args['entity']) && !$this->IsEntityWithPreventedListing($args['entity']))
|
||||||
@@ -44,7 +54,9 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
$newRow = $this->Database->{$args['entity']}()->createRow($requestBody);
|
$newRow = $this->Database->{$args['entity']}()->createRow($requestBody);
|
||||||
$newRow->save();
|
$newRow->save();
|
||||||
$success = $newRow->isClean();
|
$success = $newRow->isClean();
|
||||||
return $this->EmptyApiResponse($response);
|
return $this->ApiResponse(array(
|
||||||
|
'created_object_id' => $this->Database->lastInsertId()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
catch (\Exception $ex)
|
catch (\Exception $ex)
|
||||||
{
|
{
|
||||||
@@ -101,6 +113,38 @@ class GenericEntityApiController extends BaseApiController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function GetUserfields(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return $this->ApiResponse($this->UserfieldsService->GetValues($args['entity'], $args['objectId']));
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetUserfields(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
|
{
|
||||||
|
$requestBody = $request->getParsedBody();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ($requestBody === null)
|
||||||
|
{
|
||||||
|
throw new \Exception('Request body could not be parsed (probably invalid JSON format or missing/wrong Content-Type header)');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->UserfieldsService->SetValues($args['entity'], $args['objectId'], $requestBody);
|
||||||
|
return $this->EmptyApiResponse($response);
|
||||||
|
}
|
||||||
|
catch (\Exception $ex)
|
||||||
|
{
|
||||||
|
return $this->GenericErrorResponse($response, $ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function IsValidEntity($entity)
|
private function IsValidEntity($entity)
|
||||||
{
|
{
|
||||||
return in_array($entity, $this->OpenApiSpec->components->internalSchemas->ExposedEntity->enum);
|
return in_array($entity, $this->OpenApiSpec->components->internalSchemas->ExposedEntity->enum);
|
||||||
|
45
controllers/GenericEntityController.php
Normal file
45
controllers/GenericEntityController.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grocy\Controllers;
|
||||||
|
|
||||||
|
use \Grocy\Services\UserfieldsService;
|
||||||
|
|
||||||
|
class GenericEntityController extends BaseController
|
||||||
|
{
|
||||||
|
public function __construct(\Slim\Container $container)
|
||||||
|
{
|
||||||
|
parent::__construct($container);
|
||||||
|
$this->UserfieldsService = new UserfieldsService();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $UserfieldsService;
|
||||||
|
|
||||||
|
public function UserfieldsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
|
{
|
||||||
|
return $this->AppContainer->view->render($response, 'userfields', [
|
||||||
|
'userfields' => $this->UserfieldsService->GetAllFields(),
|
||||||
|
'entities' => $this->UserfieldsService->GetEntities()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function UserfieldEditForm(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
|
{
|
||||||
|
if ($args['userfieldId'] == 'new')
|
||||||
|
{
|
||||||
|
return $this->AppContainer->view->render($response, 'userfieldform', [
|
||||||
|
'mode' => 'create',
|
||||||
|
'userfieldTypes' => $this->UserfieldsService->GetFieldTypes(),
|
||||||
|
'entities' => $this->UserfieldsService->GetEntities()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return $this->AppContainer->view->render($response, 'userfieldform', [
|
||||||
|
'mode' => 'edit',
|
||||||
|
'userfield' => $this->UserfieldsService->GetField($args['userfieldId']),
|
||||||
|
'userfieldTypes' => $this->UserfieldsService->GetFieldTypes(),
|
||||||
|
'entities' => $this->UserfieldsService->GetEntities()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -4,6 +4,7 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
use \Grocy\Services\StockService;
|
use \Grocy\Services\StockService;
|
||||||
use \Grocy\Services\UsersService;
|
use \Grocy\Services\UsersService;
|
||||||
|
use \Grocy\Services\UserfieldsService;
|
||||||
|
|
||||||
class StockController extends BaseController
|
class StockController extends BaseController
|
||||||
{
|
{
|
||||||
@@ -12,9 +13,11 @@ class StockController extends BaseController
|
|||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
$this->StockService = new StockService();
|
$this->StockService = new StockService();
|
||||||
|
$this->UserfieldsService = new UserfieldsService();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $StockService;
|
protected $StockService;
|
||||||
|
protected $UserfieldsService;
|
||||||
|
|
||||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
@@ -29,7 +32,9 @@ class StockController extends BaseController
|
|||||||
'currentStockLocations' => $this->StockService->GetCurrentStockLocations(),
|
'currentStockLocations' => $this->StockService->GetCurrentStockLocations(),
|
||||||
'missingProducts' => $this->StockService->GetMissingProducts(),
|
'missingProducts' => $this->StockService->GetMissingProducts(),
|
||||||
'nextXDays' => $nextXDays,
|
'nextXDays' => $nextXDays,
|
||||||
'productGroups' => $this->Database->product_groups()->orderBy('name')
|
'productGroups' => $this->Database->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('products'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('products')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +87,9 @@ class StockController extends BaseController
|
|||||||
'products' => $this->Database->products()->orderBy('name'),
|
'products' => $this->Database->products()->orderBy('name'),
|
||||||
'locations' => $this->Database->locations()->orderBy('name'),
|
'locations' => $this->Database->locations()->orderBy('name'),
|
||||||
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
||||||
'productGroups' => $this->Database->product_groups()->orderBy('name')
|
'productGroups' => $this->Database->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('products'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('products')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +105,9 @@ class StockController extends BaseController
|
|||||||
public function LocationsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function LocationsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'locations', [
|
return $this->AppContainer->view->render($response, 'locations', [
|
||||||
'locations' => $this->Database->locations()->orderBy('name')
|
'locations' => $this->Database->locations()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('locations'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('locations')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,14 +115,18 @@ class StockController extends BaseController
|
|||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'productgroups', [
|
return $this->AppContainer->view->render($response, 'productgroups', [
|
||||||
'productGroups' => $this->Database->product_groups()->orderBy('name'),
|
'productGroups' => $this->Database->product_groups()->orderBy('name'),
|
||||||
'products' => $this->Database->products()->orderBy('name')
|
'products' => $this->Database->products()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('product_groups'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('product_groups')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function QuantityUnitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function QuantityUnitsList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'quantityunits', [
|
return $this->AppContainer->view->render($response, 'quantityunits', [
|
||||||
'quantityunits' => $this->Database->quantity_units()->orderBy('name')
|
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('quantity_units'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('quantity_units')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +138,7 @@ class StockController extends BaseController
|
|||||||
'locations' => $this->Database->locations()->orderBy('name'),
|
'locations' => $this->Database->locations()->orderBy('name'),
|
||||||
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
||||||
'productgroups' => $this->Database->product_groups()->orderBy('name'),
|
'productgroups' => $this->Database->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('products'),
|
||||||
'mode' => 'create'
|
'mode' => 'create'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -135,6 +149,7 @@ class StockController extends BaseController
|
|||||||
'locations' => $this->Database->locations()->orderBy('name'),
|
'locations' => $this->Database->locations()->orderBy('name'),
|
||||||
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
'quantityunits' => $this->Database->quantity_units()->orderBy('name'),
|
||||||
'productgroups' => $this->Database->product_groups()->orderBy('name'),
|
'productgroups' => $this->Database->product_groups()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('products'),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -145,14 +160,16 @@ class StockController extends BaseController
|
|||||||
if ($args['locationId'] == 'new')
|
if ($args['locationId'] == 'new')
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'locationform', [
|
return $this->AppContainer->view->render($response, 'locationform', [
|
||||||
'mode' => 'create'
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('locations')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'locationform', [
|
return $this->AppContainer->view->render($response, 'locationform', [
|
||||||
'location' => $this->Database->locations($args['locationId']),
|
'location' => $this->Database->locations($args['locationId']),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('locations')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,14 +179,16 @@ class StockController extends BaseController
|
|||||||
if ($args['productGroupId'] == 'new')
|
if ($args['productGroupId'] == 'new')
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'productgroupform', [
|
return $this->AppContainer->view->render($response, 'productgroupform', [
|
||||||
'mode' => 'create'
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('product_groups')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'productgroupform', [
|
return $this->AppContainer->view->render($response, 'productgroupform', [
|
||||||
'group' => $this->Database->product_groups($args['productGroupId']),
|
'group' => $this->Database->product_groups($args['productGroupId']),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('product_groups')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,14 +198,16 @@ class StockController extends BaseController
|
|||||||
if ($args['quantityunitId'] == 'new')
|
if ($args['quantityunitId'] == 'new')
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'quantityunitform', [
|
return $this->AppContainer->view->render($response, 'quantityunitform', [
|
||||||
'mode' => 'create'
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('quantity_units')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'quantityunitform', [
|
return $this->AppContainer->view->render($response, 'quantityunitform', [
|
||||||
'quantityunit' => $this->Database->quantity_units($args['quantityunitId']),
|
'quantityunit' => $this->Database->quantity_units($args['quantityunitId']),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('quantity_units')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ namespace Grocy\Controllers;
|
|||||||
|
|
||||||
use \Grocy\Services\TasksService;
|
use \Grocy\Services\TasksService;
|
||||||
use \Grocy\Services\UsersService;
|
use \Grocy\Services\UsersService;
|
||||||
|
use \Grocy\Services\UserfieldsService;
|
||||||
|
|
||||||
class TasksController extends BaseController
|
class TasksController extends BaseController
|
||||||
{
|
{
|
||||||
@@ -11,9 +12,11 @@ class TasksController extends BaseController
|
|||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
$this->TasksService = new TasksService();
|
$this->TasksService = new TasksService();
|
||||||
|
$this->UserfieldsService = new UserfieldsService();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected $TasksService;
|
protected $TasksService;
|
||||||
|
protected $UserfieldsService;
|
||||||
|
|
||||||
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function Overview(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
@@ -44,7 +47,8 @@ class TasksController extends BaseController
|
|||||||
return $this->AppContainer->view->render($response, 'taskform', [
|
return $this->AppContainer->view->render($response, 'taskform', [
|
||||||
'mode' => 'create',
|
'mode' => 'create',
|
||||||
'taskCategories' => $this->Database->task_categories()->orderBy('name'),
|
'taskCategories' => $this->Database->task_categories()->orderBy('name'),
|
||||||
'users' => $this->Database->users()->orderBy('username')
|
'users' => $this->Database->users()->orderBy('username'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('tasks')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -53,7 +57,8 @@ class TasksController extends BaseController
|
|||||||
'task' => $this->Database->tasks($args['taskId']),
|
'task' => $this->Database->tasks($args['taskId']),
|
||||||
'mode' => 'edit',
|
'mode' => 'edit',
|
||||||
'taskCategories' => $this->Database->task_categories()->orderBy('name'),
|
'taskCategories' => $this->Database->task_categories()->orderBy('name'),
|
||||||
'users' => $this->Database->users()->orderBy('username')
|
'users' => $this->Database->users()->orderBy('username'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('tasks')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +66,9 @@ class TasksController extends BaseController
|
|||||||
public function TaskCategoriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
public function TaskCategoriesList(\Slim\Http\Request $request, \Slim\Http\Response $response, array $args)
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'taskcategories', [
|
return $this->AppContainer->view->render($response, 'taskcategories', [
|
||||||
'taskCategories' => $this->Database->task_categories()->orderBy('name')
|
'taskCategories' => $this->Database->task_categories()->orderBy('name'),
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('task_categories'),
|
||||||
|
'userfieldValues' => $this->UserfieldsService->GetAllValues('task_categories')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,14 +77,16 @@ class TasksController extends BaseController
|
|||||||
if ($args['categoryId'] == 'new')
|
if ($args['categoryId'] == 'new')
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'taskcategoryform', [
|
return $this->AppContainer->view->render($response, 'taskcategoryform', [
|
||||||
'mode' => 'create'
|
'mode' => 'create',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('task_categories')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->AppContainer->view->render($response, 'taskcategoryform', [
|
return $this->AppContainer->view->render($response, 'taskcategoryform', [
|
||||||
'category' => $this->Database->task_categories($args['categoryId']),
|
'category' => $this->Database->task_categories($args['categoryId']),
|
||||||
'mode' => 'edit'
|
'mode' => 'edit',
|
||||||
|
'userfields' => $this->UserfieldsService->GetFields('task_categories')
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
data/viewcache/.gitignore
vendored
2
data/viewcache/.gitignore
vendored
@@ -1,2 +0,0 @@
|
|||||||
*
|
|
||||||
!.gitignore
|
|
@@ -234,8 +234,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
"204": {
|
"200": {
|
||||||
"description": "The operation was successful"
|
"description": "The operation was successful",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"created_object_id": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "integer",
|
||||||
|
"description": "The id of the created object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": "The operation was not successful",
|
"description": "The operation was not successful",
|
||||||
@@ -438,6 +452,109 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/userfields/{entity}/{objectId}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Returns all userfields with their values of the given object of the given entity",
|
||||||
|
"tags": [
|
||||||
|
"Generic entity interactions"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "entity",
|
||||||
|
"required": true,
|
||||||
|
"description": "A valid entity name",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/internalSchemas/ExposedEntity"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "objectId",
|
||||||
|
"required": true,
|
||||||
|
"description": "A valid object id of the given entity",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "An entity object",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Just key/value pairs of userfields"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "The operation was not successful",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/GenericErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"summary": "Edits the given userfields of the given object of the given entity",
|
||||||
|
"tags": [
|
||||||
|
"Generic entity interactions"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "entity",
|
||||||
|
"required": true,
|
||||||
|
"description": "A valid entity name",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/internalSchemas/ExposedEntity"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "path",
|
||||||
|
"name": "objectId",
|
||||||
|
"required": true,
|
||||||
|
"description": "A valid object id of the given entity",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "A valid entity object of the entity specified in parameter *entity*",
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"description": "Just key/value pairs of userfields"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "The operation was successful"
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "The operation was not successful",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/GenericErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/{group}/{fileName}": {
|
"/files/{group}/{fileName}": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "Serves the given file",
|
"summary": "Serves the given file",
|
||||||
@@ -2030,7 +2147,8 @@
|
|||||||
"task_categories",
|
"task_categories",
|
||||||
"product_groups",
|
"product_groups",
|
||||||
"equipment",
|
"equipment",
|
||||||
"api_keys"
|
"api_keys",
|
||||||
|
"userfields"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ExposedEntitiesPreventListing": {
|
"ExposedEntitiesPreventListing": {
|
||||||
|
11
localization/en/userfield_types.php
Normal file
11
localization/en/userfield_types.php
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'text-single-line' => 'Text (single line)',
|
||||||
|
'text-multi-line' => 'Text (multi line)',
|
||||||
|
'number-integral' => 'Number (integral)',
|
||||||
|
'number-decimal' => 'Number (decimal)',
|
||||||
|
'date' => 'Date (without time)',
|
||||||
|
'datetime' => 'Date & time',
|
||||||
|
'checkbox' => 'Checkbox'
|
||||||
|
);
|
31
migrations/0066.sql
Normal file
31
migrations/0066.sql
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
CREATE TABLE userfields (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
entity TEXT NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
caption TEXT NOT NULL,
|
||||||
|
type TEXT NOT NULL,
|
||||||
|
show_as_column_in_tables TINYINT NOT NULL DEFAULT 0,
|
||||||
|
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')),
|
||||||
|
|
||||||
|
UNIQUE(entity, name)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE userfield_values (
|
||||||
|
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
field_id INTEGER NOT NULL,
|
||||||
|
object_id INTEGER NOT NULL,
|
||||||
|
value TEXT NOT NULL,
|
||||||
|
row_created_timestamp DATETIME DEFAULT (datetime('now', 'localtime')),
|
||||||
|
|
||||||
|
UNIQUE(field_id, object_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE VIEW userfield_values_resolved
|
||||||
|
AS
|
||||||
|
SELECT
|
||||||
|
u.*,
|
||||||
|
uv.object_id,
|
||||||
|
uv.value
|
||||||
|
FROM userfields u
|
||||||
|
JOIN userfield_values uv
|
||||||
|
ON u.id = uv.field_id;
|
@@ -10,7 +10,11 @@
|
|||||||
Grocy.Api.Post('objects/batteries', jsonData,
|
Grocy.Api.Post('objects/batteries', jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/batteries');
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/batteries');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -24,7 +28,10 @@
|
|||||||
Grocy.Api.Put('objects/batteries/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/batteries/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/batteries');
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/batteries');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -57,5 +64,6 @@ $('#battery-form input').keydown(function(event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
Grocy.FrontendHelpers.ValidateForm('battery-form');
|
Grocy.FrontendHelpers.ValidateForm('battery-form');
|
||||||
|
@@ -10,7 +10,11 @@
|
|||||||
Grocy.Api.Post('objects/chores', jsonData,
|
Grocy.Api.Post('objects/chores', jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/chores');
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/chores');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -24,7 +28,10 @@
|
|||||||
Grocy.Api.Put('objects/chores/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/chores/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/chores');
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/chores');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -66,6 +73,7 @@ for (var i = 0; i < checkboxValues.length; i++)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
Grocy.FrontendHelpers.ValidateForm('chore-form');
|
Grocy.FrontendHelpers.ValidateForm('chore-form');
|
||||||
|
|
||||||
|
69
public/viewjs/components/userfieldsform.js
Normal file
69
public/viewjs/components/userfieldsform.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
Grocy.Components.UserfieldsForm = { };
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Save = function(success, error)
|
||||||
|
{
|
||||||
|
var jsonData = { };
|
||||||
|
|
||||||
|
$("#userfields-form .userfield-input").each(function()
|
||||||
|
{
|
||||||
|
var input = $(this);
|
||||||
|
var fieldName = input.attr("id");
|
||||||
|
var fieldValue = input.val();
|
||||||
|
|
||||||
|
if (input.attr("type") == "checkbox")
|
||||||
|
{
|
||||||
|
jsonData[fieldName] = "0";
|
||||||
|
if (input.is(":checked"))
|
||||||
|
{
|
||||||
|
jsonData[fieldName] = "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jsonData[fieldName] = fieldValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Grocy.Api.Put('userfields/' + $("#userfields-form").data("entity") + '/' + Grocy.EditObjectId, jsonData,
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load = function()
|
||||||
|
{
|
||||||
|
Grocy.Api.Get('userfields/' + $("#userfields-form").data("entity") + '/' + Grocy.EditObjectId,
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
$.each(result, function(key, value)
|
||||||
|
{
|
||||||
|
var input = $("#" + key + ".userfield-input");
|
||||||
|
|
||||||
|
if (input.attr("type") == "checkbox" && value == 1)
|
||||||
|
{
|
||||||
|
input.prop("checked", true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input.val(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
console.log(xhr);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
@@ -10,7 +10,11 @@
|
|||||||
Grocy.Api.Post('objects/locations', jsonData,
|
Grocy.Api.Post('objects/locations', jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/locations');
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/locations');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -24,7 +28,10 @@
|
|||||||
Grocy.Api.Put('objects/locations/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/locations/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/locations');
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/locations');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -57,5 +64,6 @@ $('#location-form input').keydown(function (event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
Grocy.FrontendHelpers.ValidateForm('location-form');
|
Grocy.FrontendHelpers.ValidateForm('location-form');
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
$('#save-product-button').on('click', function (e)
|
$('#save-product-button').on('click', function(e)
|
||||||
{
|
{
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -26,26 +26,30 @@
|
|||||||
if (Grocy.EditMode === 'create')
|
if (Grocy.EditMode === 'create')
|
||||||
{
|
{
|
||||||
Grocy.Api.Post('objects/products', jsonData,
|
Grocy.Api.Post('objects/products', jsonData,
|
||||||
function (result)
|
function(result)
|
||||||
{
|
{
|
||||||
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
{
|
{
|
||||||
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
|
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
|
||||||
function (result)
|
{
|
||||||
{
|
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
|
||||||
window.location.href = redirectDestination;
|
function(result)
|
||||||
},
|
{
|
||||||
function (xhr)
|
window.location.href = redirectDestination;
|
||||||
{
|
},
|
||||||
Grocy.FrontendHelpers.EndUiBusy("product-form");
|
function (xhr)
|
||||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
{
|
||||||
}
|
Grocy.FrontendHelpers.EndUiBusy("product-form");
|
||||||
);
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
||||||
}
|
}
|
||||||
else
|
);
|
||||||
{
|
}
|
||||||
window.location.href = redirectDestination;
|
else
|
||||||
}
|
{
|
||||||
|
window.location.href = redirectDestination;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function (xhr)
|
function (xhr)
|
||||||
{
|
{
|
||||||
@@ -74,24 +78,27 @@
|
|||||||
Grocy.Api.Put('objects/products/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/products/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
{
|
{
|
||||||
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
|
if (jsonData.hasOwnProperty("picture_file_name") && !Grocy.DeleteProductPictureOnSave)
|
||||||
function(result)
|
{
|
||||||
{
|
Grocy.Api.UploadFile($("#product-picture")[0].files[0], 'productpictures', jsonData.picture_file_name,
|
||||||
window.location.href = redirectDestination;
|
function(result)
|
||||||
},
|
{
|
||||||
function(xhr)
|
window.location.href = redirectDestination;
|
||||||
{
|
},
|
||||||
Grocy.FrontendHelpers.EndUiBusy("product-form");
|
function(xhr)
|
||||||
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
{
|
||||||
}
|
Grocy.FrontendHelpers.EndUiBusy("product-form");
|
||||||
);
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
||||||
}
|
}
|
||||||
else
|
);
|
||||||
{
|
}
|
||||||
window.location.href = redirectDestination;
|
else
|
||||||
}
|
{
|
||||||
|
window.location.href = redirectDestination;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -258,6 +265,7 @@ if (Grocy.EditMode === 'create')
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
$('.input-group-qu').trigger('change');
|
$('.input-group-qu').trigger('change');
|
||||||
Grocy.FrontendHelpers.ValidateForm('product-form');
|
Grocy.FrontendHelpers.ValidateForm('product-form');
|
||||||
|
@@ -10,7 +10,11 @@
|
|||||||
Grocy.Api.Post('objects/product_groups', jsonData,
|
Grocy.Api.Post('objects/product_groups', jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/productgroups');
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/productgroups');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -24,7 +28,10 @@
|
|||||||
Grocy.Api.Put('objects/product_groups/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/product_groups/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/productgroups');
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/productgroups');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -57,5 +64,6 @@ $('#product-group-form input').keydown(function (event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
Grocy.FrontendHelpers.ValidateForm('product-group-form');
|
Grocy.FrontendHelpers.ValidateForm('product-group-form');
|
||||||
|
@@ -10,7 +10,11 @@
|
|||||||
Grocy.Api.Post('objects/quantity_units', jsonData,
|
Grocy.Api.Post('objects/quantity_units', jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/quantityunits');
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/quantityunits');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -24,7 +28,10 @@
|
|||||||
Grocy.Api.Put('objects/quantity_units/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/quantity_units/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/quantityunits');
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/quantityunits');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -57,5 +64,6 @@ $('#quantityunit-form input').keydown(function(event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
Grocy.FrontendHelpers.ValidateForm('quantityunit-form');
|
Grocy.FrontendHelpers.ValidateForm('quantityunit-form');
|
||||||
|
@@ -10,7 +10,11 @@
|
|||||||
Grocy.Api.Post('objects/task_categories', jsonData,
|
Grocy.Api.Post('objects/task_categories', jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/taskcategories');
|
Grocy.EditObjectId = result.created_object_id;
|
||||||
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/taskcategories');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -24,7 +28,10 @@
|
|||||||
Grocy.Api.Put('objects/task_categories/' + Grocy.EditObjectId, jsonData,
|
Grocy.Api.Put('objects/task_categories/' + Grocy.EditObjectId, jsonData,
|
||||||
function(result)
|
function(result)
|
||||||
{
|
{
|
||||||
window.location.href = U('/taskcategories');
|
Grocy.Components.UserfieldsForm.Save(function()
|
||||||
|
{
|
||||||
|
window.location.href = U('/taskcategories');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
function(xhr)
|
function(xhr)
|
||||||
{
|
{
|
||||||
@@ -57,5 +64,6 @@ $('#task-category-form input').keydown(function (event)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Grocy.Components.UserfieldsForm.Load();
|
||||||
$('#name').focus();
|
$('#name').focus();
|
||||||
Grocy.FrontendHelpers.ValidateForm('task-category-form');
|
Grocy.FrontendHelpers.ValidateForm('task-category-form');
|
||||||
|
74
public/viewjs/userfieldform.js
Normal file
74
public/viewjs/userfieldform.js
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
$('#save-userfield-button').on('click', function(e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var jsonData = $('#userfield-form').serializeJSON();
|
||||||
|
Grocy.FrontendHelpers.BeginUiBusy("userfield-form");
|
||||||
|
|
||||||
|
if (Grocy.EditMode === 'create')
|
||||||
|
{
|
||||||
|
Grocy.Api.Post('objects/userfields', jsonData,
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
window.location.href = U('/userfields');
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
Grocy.FrontendHelpers.EndUiBusy("userfield-form");
|
||||||
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Grocy.Api.Put('objects/userfields/' + Grocy.EditObjectId, jsonData,
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
window.location.href = U('/userfields');
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
Grocy.FrontendHelpers.EndUiBusy("userfield-form");
|
||||||
|
Grocy.FrontendHelpers.ShowGenericError('Error while saving, probably this item already exists', xhr.response)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#userfield-form input').keyup(function(event)
|
||||||
|
{
|
||||||
|
Grocy.FrontendHelpers.ValidateForm('userfield-form');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#userfield-form select').change(function(event)
|
||||||
|
{
|
||||||
|
Grocy.FrontendHelpers.ValidateForm('userfield-form');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#userfield-form input').keydown(function(event)
|
||||||
|
{
|
||||||
|
if (event.keyCode === 13) //Enter
|
||||||
|
{
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (document.getElementById('userfield-form').checkValidity() === false) //There is at least one validation error
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$('#save-userfield-button').click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#entity').focus();
|
||||||
|
|
||||||
|
if (typeof GetUriParam("entity") !== "undefined")
|
||||||
|
{
|
||||||
|
$("#entity").val(GetUriParam("entity"));
|
||||||
|
$("#entity").trigger("change");
|
||||||
|
$('#name').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
Grocy.FrontendHelpers.ValidateForm('userfield-form');
|
86
public/viewjs/userfields.js
Normal file
86
public/viewjs/userfields.js
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
var userfieldsTable = $('#userfields-table').DataTable({
|
||||||
|
'paginate': false,
|
||||||
|
'order': [[1, 'asc']],
|
||||||
|
'columnDefs': [
|
||||||
|
{ 'orderable': false, 'targets': 0 }
|
||||||
|
],
|
||||||
|
'language': JSON.parse(L('datatables_localization')),
|
||||||
|
'scrollY': false,
|
||||||
|
'colReorder': true,
|
||||||
|
'stateSave': true,
|
||||||
|
'stateSaveParams': function(settings, data)
|
||||||
|
{
|
||||||
|
data.search.search = "";
|
||||||
|
|
||||||
|
data.columns.forEach(column =>
|
||||||
|
{
|
||||||
|
column.search.search = "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('#userfields-table tbody').removeClass("d-none");
|
||||||
|
userfieldsTable.columns.adjust().draw();
|
||||||
|
|
||||||
|
$("#search").on("keyup", function()
|
||||||
|
{
|
||||||
|
var value = $(this).val();
|
||||||
|
if (value === "all")
|
||||||
|
{
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
userfieldsTable.search(value).draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#entity-filter").on("change", function()
|
||||||
|
{
|
||||||
|
var value = $("#entity-filter option:selected").text();
|
||||||
|
if (value === L("All"))
|
||||||
|
{
|
||||||
|
value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
userfieldsTable.column(1).search(value).draw();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.userfield-delete-button', function (e)
|
||||||
|
{
|
||||||
|
var objectName = $(e.currentTarget).attr('data-userfield-name');
|
||||||
|
var objectId = $(e.currentTarget).attr('data-userfield-id');
|
||||||
|
|
||||||
|
bootbox.confirm({
|
||||||
|
message: L('Are you sure to delete user field "#1"?', objectName),
|
||||||
|
buttons: {
|
||||||
|
confirm: {
|
||||||
|
label: L('Yes'),
|
||||||
|
className: 'btn-success'
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
label: L('No'),
|
||||||
|
className: 'btn-danger'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
callback: function(result)
|
||||||
|
{
|
||||||
|
if (result === true)
|
||||||
|
{
|
||||||
|
Grocy.Api.Delete('objects/userfields/' + objectId, {},
|
||||||
|
function(result)
|
||||||
|
{
|
||||||
|
window.location.href = U('/userfields');
|
||||||
|
},
|
||||||
|
function(xhr)
|
||||||
|
{
|
||||||
|
console.error(xhr);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof GetUriParam("entity") !== "undefined")
|
||||||
|
{
|
||||||
|
$("#entity-filter").val(GetUriParam("entity"));
|
||||||
|
$("#entity-filter").trigger("change");
|
||||||
|
}
|
@@ -16,6 +16,10 @@ $app->group('', function()
|
|||||||
$this->post('/login', 'LoginControllerInstance:ProcessLogin')->setName('login');
|
$this->post('/login', 'LoginControllerInstance:ProcessLogin')->setName('login');
|
||||||
$this->get('/logout', 'LoginControllerInstance:Logout');
|
$this->get('/logout', 'LoginControllerInstance:Logout');
|
||||||
|
|
||||||
|
// Generic entity interaction
|
||||||
|
$this->get('/userfields', '\Grocy\Controllers\GenericEntityController:UserfieldsList');
|
||||||
|
$this->get('/userfield/{userfieldId}', '\Grocy\Controllers\GenericEntityController:UserfieldEditForm');
|
||||||
|
|
||||||
// User routes
|
// User routes
|
||||||
$this->get('/users', '\Grocy\Controllers\UsersController:UsersList');
|
$this->get('/users', '\Grocy\Controllers\UsersController:UsersList');
|
||||||
$this->get('/user/{userId}', '\Grocy\Controllers\UsersController:UserEditForm');
|
$this->get('/user/{userId}', '\Grocy\Controllers\UsersController:UserEditForm');
|
||||||
@@ -119,6 +123,8 @@ $app->group('/api', function()
|
|||||||
$this->post('/objects/{entity}', '\Grocy\Controllers\GenericEntityApiController:AddObject');
|
$this->post('/objects/{entity}', '\Grocy\Controllers\GenericEntityApiController:AddObject');
|
||||||
$this->put('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:EditObject');
|
$this->put('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:EditObject');
|
||||||
$this->delete('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:DeleteObject');
|
$this->delete('/objects/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:DeleteObject');
|
||||||
|
$this->get('/userfields/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:GetUserfields');
|
||||||
|
$this->put('/userfields/{entity}/{objectId}', '\Grocy\Controllers\GenericEntityApiController:SetUserfields');
|
||||||
|
|
||||||
// Files
|
// Files
|
||||||
$this->put('/files/{group}/{fileName}', '\Grocy\Controllers\FilesApiController:UploadFile');
|
$this->put('/files/{group}/{fileName}', '\Grocy\Controllers\FilesApiController:UploadFile');
|
||||||
|
@@ -28,6 +28,7 @@ class LocalizationService
|
|||||||
'strings.php',
|
'strings.php',
|
||||||
'stock_transaction_types.php',
|
'stock_transaction_types.php',
|
||||||
'chore_types.php',
|
'chore_types.php',
|
||||||
|
'userfield_types.php',
|
||||||
'component_translations.php',
|
'component_translations.php',
|
||||||
'demo_data.php'
|
'demo_data.php'
|
||||||
);
|
);
|
||||||
|
121
services/UserfieldsService.php
Normal file
121
services/UserfieldsService.php
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Grocy\Services;
|
||||||
|
|
||||||
|
class UserfieldsService extends BaseService
|
||||||
|
{
|
||||||
|
const USERFIELD_TYPE_SINGLE_LINE_TEXT = 'text-single-line';
|
||||||
|
const USERFIELD_TYPE_SINGLE_MULTILINE_TEXT = 'text-multi-line';
|
||||||
|
const USERFIELD_TYPE_INTEGRAL_NUMBER = 'number-integral';
|
||||||
|
const USERFIELD_TYPE_DECIMAL_NUMBER = 'number-decimal';
|
||||||
|
const USERFIELD_TYPE_DATE = 'date';
|
||||||
|
const USERFIELD_TYPE_DATETIME = 'datetime';
|
||||||
|
const USERFIELD_TYPE_CHECKBOX = 'checkbox';
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
$this->OpenApiSpec = json_decode(file_get_contents(__DIR__ . '/../grocy.openapi.json'));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $OpenApiSpec;
|
||||||
|
|
||||||
|
public function GetFields($entity)
|
||||||
|
{
|
||||||
|
if (!$this->IsValidEntity($entity))
|
||||||
|
{
|
||||||
|
throw new \Exception('Entity does not exist or is not exposed');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->Database->userfields()->where('entity', $entity)->orderBy('name')->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetField($fieldId)
|
||||||
|
{
|
||||||
|
return $this->Database->userfields($fieldId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAllFields()
|
||||||
|
{
|
||||||
|
return $this->Database->userfields()->orderBy('name')->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetValues($entity, $objectId)
|
||||||
|
{
|
||||||
|
if (!$this->IsValidEntity($entity))
|
||||||
|
{
|
||||||
|
throw new \Exception('Entity does not exist or is not exposed');
|
||||||
|
}
|
||||||
|
|
||||||
|
$userfields = $this->Database->userfield_values_resolved()->where('entity = :1 AND object_id = :2', $entity, $objectId)->orderBy('name')->fetchAll();
|
||||||
|
$userfieldKeyValuePairs = array();
|
||||||
|
foreach ($userfields as $userfield)
|
||||||
|
{
|
||||||
|
$userfieldKeyValuePairs[$userfield->name] = $userfield->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $userfieldKeyValuePairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAllValues($entity)
|
||||||
|
{
|
||||||
|
if (!$this->IsValidEntity($entity))
|
||||||
|
{
|
||||||
|
throw new \Exception('Entity does not exist or is not exposed');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->Database->userfield_values_resolved()->where('entity', $entity)->orderBy('name')->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetValues($entity, $objectId, $userfields)
|
||||||
|
{
|
||||||
|
if (!$this->IsValidEntity($entity))
|
||||||
|
{
|
||||||
|
throw new \Exception('Entity does not exist or is not exposed');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($userfields as $key => $value)
|
||||||
|
{
|
||||||
|
$fieldRow = $this->Database->userfields()->where('entity = :1 AND name = :2', $entity, $key)->fetch();
|
||||||
|
|
||||||
|
if ($fieldRow === null)
|
||||||
|
{
|
||||||
|
throw new \Exception("Field $key is not a valid userfield of the given entity");
|
||||||
|
}
|
||||||
|
|
||||||
|
$fieldId = $fieldRow->id;
|
||||||
|
|
||||||
|
$alreadyExistingEntry = $this->Database->userfield_values()->where('field_id = :1 AND object_id = :2', $fieldId, $objectId)->fetch();
|
||||||
|
if ($alreadyExistingEntry) // Update
|
||||||
|
{
|
||||||
|
$alreadyExistingEntry->update(array(
|
||||||
|
'value' => $value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else // Insert
|
||||||
|
{
|
||||||
|
$newRow = $this->Database->userfield_values()->createRow(array(
|
||||||
|
'field_id' => $fieldId,
|
||||||
|
'object_id' => $objectId,
|
||||||
|
'value' => $value
|
||||||
|
));
|
||||||
|
$newRow->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetEntities()
|
||||||
|
{
|
||||||
|
return $this->OpenApiSpec->components->internalSchemas->ExposedEntity->enum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetFieldTypes()
|
||||||
|
{
|
||||||
|
return GetClassConstants('\Grocy\Services\UserfieldsService');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function IsValidEntity($entity)
|
||||||
|
{
|
||||||
|
return in_array($entity, $this->OpenApiSpec->components->internalSchemas->ExposedEntity->enum);
|
||||||
|
}
|
||||||
|
}
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/battery/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/battery/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=batteries') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -33,6 +36,11 @@
|
|||||||
<th>{{ $L('Description') }}</th>
|
<th>{{ $L('Description') }}</th>
|
||||||
<th>{{ $L('Used in') }}</th>
|
<th>{{ $L('Used in') }}</th>
|
||||||
<th>{{ $L('Charge cycle interval (days)') }}</th>
|
<th>{{ $L('Charge cycle interval (days)') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -58,6 +66,12 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ $battery->charge_interval_days }}
|
{{ $battery->charge_interval_days }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $battery->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -46,6 +46,11 @@
|
|||||||
<th>{{ $L('Last charged') }}</th>
|
<th>{{ $L('Last charged') }}</th>
|
||||||
<th>{{ $L('Next planned charge cycle') }}</th>
|
<th>{{ $L('Next planned charge cycle') }}</th>
|
||||||
<th class="d-none">Hidden status</th>
|
<th class="d-none">Hidden status</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -92,6 +97,12 @@
|
|||||||
<td class="d-none">
|
<td class="d-none">
|
||||||
"@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $curentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s')) overdue @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $curentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) duesoon @endif
|
"@if(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $curentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s')) overdue @elseif(FindObjectInArrayByPropertyValue($batteries, 'id', $curentBatteryEntry->battery_id)->charge_interval_days > 0 && $curentBatteryEntry->next_estimated_charge_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) duesoon @endif
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $curentBatteryEntry->battery_id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -47,6 +47,11 @@
|
|||||||
'invalidFeedback' => $L('This cannot be negative')
|
'invalidFeedback' => $L('This cannot be negative')
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'batteries'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-battery-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-battery-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@@ -87,6 +87,11 @@
|
|||||||
|
|
||||||
<input type="hidden" id="period_config" name="period_config" value="@if($mode == 'edit'){{ $chore->period_config }}@endif">
|
<input type="hidden" id="period_config" name="period_config" value="@if($mode == 'edit'){{ $chore->period_config }}@endif">
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'chores'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-chore-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-chore-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/chore/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/chore/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=chores') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,6 +35,11 @@
|
|||||||
<th>{{ $L('Name') }}</th>
|
<th>{{ $L('Name') }}</th>
|
||||||
<th>{{ $L('Period type') }}</th>
|
<th>{{ $L('Period type') }}</th>
|
||||||
<th>{{ $L('Description') }}</th>
|
<th>{{ $L('Description') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -54,6 +62,12 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ $chore->description }}
|
{{ $chore->description }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $chore->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -46,6 +46,11 @@
|
|||||||
<th>{{ $L('Next estimated tracking') }}</th>
|
<th>{{ $L('Next estimated tracking') }}</th>
|
||||||
<th>{{ $L('Last tracked') }}</th>
|
<th>{{ $L('Last tracked') }}</th>
|
||||||
<th class="d-none">Hidden status</th>
|
<th class="d-none">Hidden status</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -92,6 +97,12 @@
|
|||||||
<td class="d-none">
|
<td class="d-none">
|
||||||
@if(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s')) overdue @elseif(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) duesoon @endif
|
@if(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s')) overdue @elseif(FindObjectInArrayByPropertyValue($chores, 'id', $curentChoreEntry->chore_id)->period_type !== \Grocy\Services\ChoresService::CHORE_TYPE_MANUALLY && $curentChoreEntry->next_estimated_execution_time < date('Y-m-d H:i:s', strtotime("+$nextXDays days"))) duesoon @endif
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $curentChoreEntry->chore_id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
16
views/components/userfields_tbody.blade.php
Normal file
16
views/components/userfields_tbody.blade.php
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
@push('componentScripts')
|
||||||
|
<script src="{{ $U('/viewjs/components/userfieldsform.js', true) }}?v={{ $version }}"></script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@if(count($userfields) > 0)
|
||||||
|
|
||||||
|
@foreach($userfields as $userfield)
|
||||||
|
|
||||||
|
@if($userfield->show_as_column_in_tables == 1)
|
||||||
|
@php $userfieldObject = FindObjectInArrayByPropertyValue($userfieldValues, 'name', $userfield->name) @endphp
|
||||||
|
<td>@if($userfieldObject !== null){{ $userfieldObject->value }}@endif</td>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@endif
|
15
views/components/userfields_thead.blade.php
Normal file
15
views/components/userfields_thead.blade.php
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
@push('componentScripts')
|
||||||
|
<script src="{{ $U('/viewjs/components/userfieldsform.js', true) }}?v={{ $version }}"></script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@if(count($userfields) > 0)
|
||||||
|
|
||||||
|
@foreach($userfields as $userfield)
|
||||||
|
|
||||||
|
@if($userfield->show_as_column_in_tables == 1)
|
||||||
|
<th>{{ $userfield->name }}</th>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
@endif
|
32
views/components/userfieldsform.blade.php
Normal file
32
views/components/userfieldsform.blade.php
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
@push('componentScripts')
|
||||||
|
<script src="{{ $U('/viewjs/components/userfieldsform.js', true) }}?v={{ $version }}"></script>
|
||||||
|
@endpush
|
||||||
|
|
||||||
|
@if(count($userfields) > 0)
|
||||||
|
|
||||||
|
<div id="userfields-form" data-entity="{{ $entity }}" class="border border-info p-2 mb-2" novalidate>
|
||||||
|
<h2 class="small">{{ $L('Userfields') }}</h2>
|
||||||
|
|
||||||
|
@foreach($userfields as $userfield)
|
||||||
|
|
||||||
|
@if($userfield->type == \Grocy\Services\UserfieldsService::USERFIELD_TYPE_SINGLE_LINE_TEXT)
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">{{ $userfield->caption }}</label>
|
||||||
|
<input type="text" class="form-control userfield-input" id="{{ $userfield->name }}" value="">
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if($userfield->type == \Grocy\Services\UserfieldsService::USERFIELD_TYPE_CHECKBOX)
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input userfield-input" type="checkbox" id="{{ $userfield->name }}" value="1">
|
||||||
|
<label class="form-check-label" for="{{ $userfield->name }}">{{ $userfield->caption }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@endif
|
@@ -32,6 +32,11 @@
|
|||||||
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $location->description }}@endif</textarea>
|
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $location->description }}@endif</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'locations'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-location-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-location-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/location/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/location/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=locations') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,6 +34,11 @@
|
|||||||
<th class="border-right"></th>
|
<th class="border-right"></th>
|
||||||
<th>{{ $L('Name') }}</th>
|
<th>{{ $L('Name') }}</th>
|
||||||
<th>{{ $L('Description') }}</th>
|
<th>{{ $L('Description') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -50,6 +58,12 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ $location->description }}
|
{{ $location->description }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $location->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -187,8 +187,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'products'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-product-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-product-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-lg-6 col-xs-12">
|
<div class="col-lg-6 col-xs-12">
|
||||||
|
@@ -32,6 +32,11 @@
|
|||||||
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $group->description }}@endif</textarea>
|
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $group->description }}@endif</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'product_groups'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-product-group-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-product-group-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/productgroup/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/productgroup/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=product_groups') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -32,6 +35,10 @@
|
|||||||
<th>{{ $L('Name') }}</th>
|
<th>{{ $L('Name') }}</th>
|
||||||
<th>{{ $L('Description') }}</th>
|
<th>{{ $L('Description') }}</th>
|
||||||
<th>{{ $L('Product count') }}</th>
|
<th>{{ $L('Product count') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -57,6 +64,12 @@
|
|||||||
<i class="fas fa-external-link-alt"></i>
|
<i class="fas fa-external-link-alt"></i>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $productGroup->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/product/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/product/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=products') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
<a class="btn btn-outline-secondary" href="{{ $U('/stocksettings#productpresets') }}">
|
<a class="btn btn-outline-secondary" href="{{ $U('/stocksettings#productpresets') }}">
|
||||||
<i class="fas fa-sliders-h"></i> {{ $L('Presets for new products') }}
|
<i class="fas fa-sliders-h"></i> {{ $L('Presets for new products') }}
|
||||||
</a>
|
</a>
|
||||||
@@ -48,6 +51,11 @@
|
|||||||
<th>{{ $L('QU stock') }}</th>
|
<th>{{ $L('QU stock') }}</th>
|
||||||
<th>{{ $L('QU factor') }}</th>
|
<th>{{ $L('QU factor') }}</th>
|
||||||
<th>{{ $L('Product group') }}</th>
|
<th>{{ $L('Product group') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -82,6 +90,12 @@
|
|||||||
<td>
|
<td>
|
||||||
@if(!empty($product->product_group_id)) {{ FindObjectInArrayByPropertyValue($productGroups, 'id', $product->product_group_id)->name }} @endif
|
@if(!empty($product->product_group_id)) {{ FindObjectInArrayByPropertyValue($productGroups, 'id', $product->product_group_id)->name }} @endif
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $product->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -37,6 +37,11 @@
|
|||||||
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $quantityunit->description }}@endif</textarea>
|
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $quantityunit->description }}@endif</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'quantity_units'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-quantityunit-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-quantityunit-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/quantityunit/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/quantityunit/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=quantity_units') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,6 +34,10 @@
|
|||||||
<th class="border-right"></th>
|
<th class="border-right"></th>
|
||||||
<th>{{ $L('Name') }}</th>
|
<th>{{ $L('Name') }}</th>
|
||||||
<th>{{ $L('Description') }}</th>
|
<th>{{ $L('Description') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -50,6 +57,12 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ $quantityunit->description }}
|
{{ $quantityunit->description }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $quantityunit->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -77,6 +77,11 @@
|
|||||||
<th class="d-none">Hidden location</th>
|
<th class="d-none">Hidden location</th>
|
||||||
<th class="d-none">Hidden status</th>
|
<th class="d-none">Hidden status</th>
|
||||||
<th class="d-none">Hidden product group</th>
|
<th class="d-none">Hidden product group</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -143,6 +148,12 @@
|
|||||||
<td class="d-none">
|
<td class="d-none">
|
||||||
@if($productGroup !== null){{ $productGroup->name }}@endif
|
@if($productGroup !== null){{ $productGroup->name }}@endif
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $currentStockEntry->product_id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -12,6 +12,9 @@
|
|||||||
<a class="btn btn-outline-dark" href="{{ $U('/taskcategory/new') }}">
|
<a class="btn btn-outline-dark" href="{{ $U('/taskcategory/new') }}">
|
||||||
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="btn btn-outline-secondary" href="{{ $U('/userfields?entity=task_categories') }}">
|
||||||
|
<i class="fas fa-sliders-h"></i> {{ $L('Configure userfields') }}
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -31,6 +34,11 @@
|
|||||||
<th class="border-right"></th>
|
<th class="border-right"></th>
|
||||||
<th>{{ $L('Name') }}</th>
|
<th>{{ $L('Name') }}</th>
|
||||||
<th>{{ $L('Description') }}</th>
|
<th>{{ $L('Description') }}</th>
|
||||||
|
|
||||||
|
@include('components.userfields_thead', array(
|
||||||
|
'userfields' => $userfields
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="d-none">
|
<tbody class="d-none">
|
||||||
@@ -50,6 +58,12 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ $taskCategory->description }}
|
{{ $taskCategory->description }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
@include('components.userfields_tbody', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'userfieldValues' => FindAllObjectsInArrayByPropertyValue($userfieldValues, 'object_id', $taskCategory->id)
|
||||||
|
))
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -32,6 +32,11 @@
|
|||||||
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $category->description }}@endif</textarea>
|
<textarea class="form-control" rows="2" id="description" name="description">@if($mode == 'edit'){{ $category->description }}@endif</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@include('components.userfieldsform', array(
|
||||||
|
'userfields' => $userfields,
|
||||||
|
'entity' => 'task_categories'
|
||||||
|
))
|
||||||
|
|
||||||
<button id="save-task-category-button" class="btn btn-success">{{ $L('Save') }}</button>
|
<button id="save-task-category-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
71
views/userfieldform.blade.php
Normal file
71
views/userfieldform.blade.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
@extends('layout.default')
|
||||||
|
|
||||||
|
@if($mode == 'edit')
|
||||||
|
@section('title', $L('Edit userfield'))
|
||||||
|
@else
|
||||||
|
@section('title', $L('Create userfield'))
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@section('viewJsName', 'userfieldform')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6 col-xs-12">
|
||||||
|
<h1>@yield('title')</h1>
|
||||||
|
|
||||||
|
<script>Grocy.EditMode = '{{ $mode }}';</script>
|
||||||
|
|
||||||
|
@if($mode == 'edit')
|
||||||
|
<script>Grocy.EditObjectId = {{ $userfield->id }};</script>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<form id="userfield-form" novalidate>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="entity">{{ $L('Entity') }}</label>
|
||||||
|
<select required class="form-control" id="entity" name="entity">
|
||||||
|
<option></option>
|
||||||
|
@foreach($entities as $entity)
|
||||||
|
<option @if($mode == 'edit' && $userfield->entity == $entity) selected="selected" @endif value="{{ $entity }}">{{ $entity }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<div class="invalid-feedback">{{ $L('A entity is required') }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">{{ $L('Name') }}</label>
|
||||||
|
<input type="text" class="form-control" required id="name" name="name" value="@if($mode == 'edit'){{ $userfield->name }}@endif">
|
||||||
|
<div class="invalid-feedback">{{ $L('A name is required') }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">{{ $L('Caption') }}</label>
|
||||||
|
<input type="text" class="form-control" required id="caption" name="caption" value="@if($mode == 'edit'){{ $userfield->caption }}@endif">
|
||||||
|
<div class="invalid-feedback">{{ $L('A caption is required') }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="entity">{{ $L('Type') }}</label>
|
||||||
|
<select required class="form-control" id="type" name="type">
|
||||||
|
<option></option>
|
||||||
|
@foreach($userfieldTypes as $userfieldType)
|
||||||
|
<option @if($mode == 'edit' && $userfield->type == $userfieldType) selected="selected" @endif value="{{ $userfieldType }}">{{ $L($userfieldType) }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<div class="invalid-feedback">{{ $L('A type is required') }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="hidden" name="show_as_column_in_tables" value="0">
|
||||||
|
<input @if($mode == 'edit' && $userfield->show_as_column_in_tables == 1) checked @endif class="form-check-input" type="checkbox" id="show_as_column_in_tables" name="show_as_column_in_tables" value="1">
|
||||||
|
<label class="form-check-label" for="show_as_column_in_tables">{{ $L('Show as column in tables') }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="save-userfield-button" class="btn btn-success">{{ $L('Save') }}</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@stop
|
76
views/userfields.blade.php
Normal file
76
views/userfields.blade.php
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
@extends('layout.default')
|
||||||
|
|
||||||
|
@section('title', $L('Userfields'))
|
||||||
|
@section('activeNav', 'userfields')
|
||||||
|
@section('viewJsName', 'userfields')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<h1>
|
||||||
|
@yield('title')
|
||||||
|
<a class="btn btn-outline-dark" href="{{ $U('/userfield/new') }}">
|
||||||
|
<i class="fas fa-plus"></i> {{ $L('Add') }}
|
||||||
|
</a>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||||
|
<label for="search">{{ $L('Search') }}</label> <i class="fas fa-search"></i>
|
||||||
|
<input type="text" class="form-control" id="search">
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-md-6 col-xl-3">
|
||||||
|
<label for="entity-filter">{{ $L('Filter by entity') }}</label> <i class="fas fa-filter"></i>
|
||||||
|
<select class="form-control" id="entity-filter">
|
||||||
|
<option value="all">{{ $L('All') }}</option>
|
||||||
|
@foreach($entities as $entity)
|
||||||
|
<option value="{{ $entity }}">{{ $entity }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<table id="userfields-table" class="table table-sm table-striped dt-responsive">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="border-right"></th>
|
||||||
|
<th>{{ $L('Entity') }}</th>
|
||||||
|
<th>{{ $L('Name') }}</th>
|
||||||
|
<th>{{ $L('Caption') }}</th>
|
||||||
|
<th>{{ $L('Type') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="d-none">
|
||||||
|
@foreach($userfields as $userfield)
|
||||||
|
<tr>
|
||||||
|
<td class="fit-content border-right">
|
||||||
|
<a class="btn btn-info btn-sm" href="{{ $U('/userfield/') }}{{ $userfield->id }}">
|
||||||
|
<i class="fas fa-edit"></i>
|
||||||
|
</a>
|
||||||
|
<a class="btn btn-danger btn-sm userfield-delete-button" href="#" data-userfield-id="{{ $userfield->id }}" data-userfield-name="{{ $userfield->name }}">
|
||||||
|
<i class="fas fa-trash"></i>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ $userfield->entity }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ $userfield->name }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ $userfield->caption }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ $L($userfield->type) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@stop
|
Reference in New Issue
Block a user