¨4.0.1¨

This commit is contained in:
¨NW¨
2023-12-03 14:07:47 +00:00
parent c08b36d1b6
commit f35052522d
1112 changed files with 43019 additions and 24987 deletions

View File

@@ -2,6 +2,12 @@
namespace Modules\Admin\Ui;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Yajra\DataTables\DataTables;
use Illuminate\Http\JsonResponse;
use Illuminate\Database\Eloquent\Builder;
use Yajra\DataTables\Exceptions\Exception;
use Illuminate\Contracts\Support\Responsable;
class AdminTable implements Responsable
@@ -11,28 +17,30 @@ class AdminTable implements Responsable
*
* @var array
*/
protected $rawColumns = [];
protected array $rawColumns = [];
/**
* Raw columns that will not be escaped.
*
* @var array
*/
protected $defaultRawColumns = [
'checkbox', 'thumbnail', 'status', 'created',
protected array $defaultRawColumns = [
'checkbox', 'thumbnail', 'status', 'created', 'updated',
];
/**
* Source of the table.
*
* @var \Illuminate\Database\Eloquent\Builder
* @var Builder
*/
protected $source;
/**
* Create a new table instance.
*
* @param \Illuminate\Database\Eloquent\Builder $source
* @param Builder $source
*
* @return void
*/
public function __construct($source = null)
@@ -40,22 +48,38 @@ class AdminTable implements Responsable
$this->source = $source;
}
/**
* Create an HTTP response that represents the object.
*
* @param Request $request
*
* @return Response
*/
public function toResponse($request)
{
return $this->make()->toJson();
}
/**
* Make table response for the resource.
*
* @param mixed $source
* @return \Illuminate\Http\JsonResponse
*
* @return JsonResponse
*/
public function make()
{
return $this->newTable();
}
/**
* Create a new datatable instance;
*
* @param mixed $source
* @return \Yajra\DataTables\DataTables
* @return DataTables
* @throws Exception
*/
public function newTable()
{
@@ -71,18 +95,10 @@ class AdminTable implements Responsable
->editColumn('created', function ($entity) {
return view('admin::partials.table.date')->with('date', $entity->created_at);
})
->editColumn('updated', function ($entity) {
return view('admin::partials.table.date')->with('date', $entity->updated_at);
})
->rawColumns(array_merge($this->defaultRawColumns, $this->rawColumns))
->removeColumn('translations');
}
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function toResponse($request)
{
return $this->make()->toJson();
}
}

View File

@@ -23,9 +23,10 @@ trait InputFields
{$attributes}"
. ($disabled ? 'disabled' : '')
. ($readonly ? 'readonly ' : '') .
'>';
'>';
}
protected function textareaField($name, $value, $class, $attributes, $options)
{
$readonly = array_pull($options, 'readonly', false);
@@ -38,21 +39,22 @@ trait InputFields
{$attributes}"
. ($disabled ? 'disabled' : '')
. ($readonly ? 'readonly ' : '') .
">{$value}</textarea>";
">{$value}</textarea>";
}
protected function checkboxField($name, $value, $class, $attributes, $options, $label)
{
$checked = array_pull($options, 'checked', false);
$disabled = array_get($options, 'disabled', false);
if (! is_null($value)) {
if (!is_null($value)) {
$checked = $value;
}
$html = '<div class="checkbox">';
if (! $disabled) {
if (!$disabled) {
$html .= "<input type='hidden' value='0' name='{$name}'>";
}
@@ -63,9 +65,9 @@ trait InputFields
id='{$name}'
{$attributes}
value='1'"
. ($checked ? 'checked ' : '')
. ($disabled ? 'disabled' : '') .
'>';
. ($checked ? 'checked ' : '')
. ($disabled ? 'disabled' : '') .
'>';
$html .= "<label for='{$name}'>{$label}</label>";
$html .= '</div>';
@@ -73,6 +75,7 @@ trait InputFields
return $html;
}
protected function selectField($name, $value, $class, $attributes, $options, $list)
{
$multiple = array_get($options, 'multiple', false);
@@ -86,7 +89,7 @@ trait InputFields
{$attributes}"
. ($disabled ? 'disabled' : '')
. ($readonly ? 'readonly ' : '') .
'>';
'>';
foreach ($list as $listValue => $listName) {
$listValue = e($listValue);
@@ -94,10 +97,10 @@ trait InputFields
if ($multiple && $value instanceof Collection) {
$selected = $value->where('id', $listValue)->isNotEmpty() ? 'selected' : '';
} elseif ($multiple && is_array($value)) {
} else if ($multiple && is_array($value)) {
$selected = in_array($listValue, $value) ? 'selected' : '';
} else {
$selected = (! is_null($value) && $value == $listValue) ? 'selected' : '';
$selected = (!is_null($value) && $value == $listValue) ? 'selected' : '';
}
$html .= "<option value='{$listValue}' {$selected}>{$listName}</option>";
@@ -108,6 +111,7 @@ trait InputFields
return $html;
}
protected function field($name, $title, $errors, $entity, $options, callable $fieldCallback, ...$args)
{
$value = $this->getValue($entity, $name);
@@ -139,7 +143,7 @@ trait InputFields
$html .= "<div class='col-md-{$fieldCol}'>";
$html .= call_user_func_array($fieldCallback, $params);
if ($help && ! $errors->has($normalizedName)) {
if ($help && !$errors->has($normalizedName)) {
$html .= "<span class='help-block'>{$help}</span>";
}
@@ -151,15 +155,31 @@ trait InputFields
return new HtmlString($html);
}
private function normalizeTranslatableFieldName($name)
protected function generateHtmlAttributes($options = [])
{
if (starts_with($name, 'translatable[')) {
return 'translatable.' . str_between($name, 'translatable[', ']');
$this->unsetUnnecessaryAttributes($options);
$attributes = '';
foreach ($options as $attr => $value) {
$attributes .= "{$attr}='{$value}' ";
}
return $name;
return $attributes;
}
protected function unsetUnnecessaryAttributes(&$options = [])
{
foreach ($this->unnecessaryAttributes as $attribute) {
if (array_key_exists($attribute, $options)) {
unset($options[$attribute]);
}
}
}
protected function label($name, $title, $labelCol = 3, $required = false)
{
$html = "<label for='{$name}' class='col-md-{$labelCol} control-label text-left'>{$title}";
@@ -171,6 +191,7 @@ trait InputFields
return $html .= '</label>';
}
private function getValue($entity, $name)
{
if (is_object($entity) && method_exists($entity, 'translate') && $entity->isTranslationAttribute($name)) {
@@ -201,25 +222,13 @@ trait InputFields
return old($normalizedName, $value);
}
protected function generateHtmlAttributes($options = [])
private function normalizeTranslatableFieldName($name)
{
$this->unsetUnnecessaryAttributes($options);
$attributes = '';
foreach ($options as $attr => $value) {
$attributes .= "{$attr}='{$value}' ";
if (starts_with($name, 'translatable[')) {
return 'translatable.' . str_between($name, 'translatable[', ']');
}
return $attributes;
}
protected function unsetUnnecessaryAttributes(&$options = [])
{
foreach ($this->unnecessaryAttributes as $attribute) {
if (array_key_exists($attribute, $options)) {
unset($options[$attribute]);
}
}
return $name;
}
}

View File

@@ -10,48 +10,49 @@ class Form
protected $unnecessaryAttributes = ['disabled', 'readonly', 'checked'];
public function text($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'text']));
}
public function password($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'password']));
}
public function number($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'number']));
}
public function email($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'email']));
}
public function file($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'file']));
}
public function color($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'color']));
}
public function input($name, $title, $errors, $entity = null, $options = [])
{
return $this->field($name, $title, $errors, $entity, $options, [$this, 'inputField']);
}
public function textarea($name, $title, $errors, $entity = null, $options = [])
{
$options = array_merge(['rows' => 10, 'cols' => 10], $options);
return $this->field($name, $title, $errors, $entity, $options, [$this, 'textareaField']);
public function password($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'password']));
}
public function number($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'number']));
}
public function email($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'email']));
}
public function file($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'file']));
}
public function color($name, $title, $errors, $entity = null, $options = [])
{
return $this->input($name, $title, $errors, $entity, array_merge($options, ['type' => 'color']));
}
public function wysiwyg($name, $title, $errors, $entity = null, $options = [])
{
$options['class'] = array_get($options, 'class', '') . ' wysiwyg';
@@ -59,11 +60,21 @@ class Form
return $this->textarea($name, $title, $errors, $entity, $options);
}
public function textarea($name, $title, $errors, $entity = null, $options = [])
{
$options = array_merge(['rows' => 10, 'cols' => 10], $options);
return $this->field($name, $title, $errors, $entity, $options, [$this, 'textareaField']);
}
public function checkbox($name, $title, $label, $errors, $entity = null, $options = [])
{
return $this->field($name, $title, $errors, $entity, $options, [$this, 'checkboxField'], $label);
}
public function select($name, $title, $errors, $list = [], $entity = null, $options = [])
{
return $this->field($name, $title, $errors, $entity, $options, [$this, 'selectField'], $list);

View File

@@ -2,6 +2,7 @@
namespace Modules\Admin\Ui;
use Closure;
use Illuminate\Support\ViewErrorBag;
class Tab
@@ -11,21 +12,21 @@ class Tab
*
* @var bool
*/
private $active = false;
public $active = false;
/**
* Name of the tab.
*
* @var string
*/
private $name;
public $name;
/**
* Label of the tab.
*
* @var string
*/
private $label;
public $label;
/**
* Weight of the tab.
@@ -44,10 +45,25 @@ class Tab
/**
* View of the tab.
*
* @var string|\Closure
* @var string|Closure
*/
private $view;
/**
* Prepend to the View of the tab.
*
* @var string|Closure
*/
private $prependView;
/**
* Append to the view of the tab.
*
* @var string|Closure
*/
private $appendView;
/**
* Data for the tab view.
*
@@ -58,15 +74,17 @@ class Tab
/**
* Error message bag.
*
* @var \Illuminate\Support\ViewErrorBag
* @var ViewErrorBag
*/
private $errors;
/**
* Create a new Tab instance.
*
* @param string $name
* @param string $label
*
* @return void
*/
public function __construct($name, $label)
@@ -76,6 +94,7 @@ class Tab
$this->errors = request()->session()->get('errors') ?: new ViewErrorBag;
}
/**
* Set tab as active.
*
@@ -88,10 +107,12 @@ class Tab
return $this;
}
/**
* Set weight of tab.
*
* @param int $weight
*
* @return self
*/
public function weight($weight)
@@ -101,6 +122,7 @@ class Tab
return $this;
}
/**
* Get weight of the tab.
*
@@ -111,10 +133,12 @@ class Tab
return $this->weight;
}
/**
* Get nav of the tab.
*
* @param array $data
*
* @return string
*/
public function getNav()
@@ -124,30 +148,12 @@ class Tab
</li>";
}
/**
* Return active class if tab is active.
*
* @return string
*/
private function activeClass()
{
return $this->active ? 'active' : '';
}
/**
* Return error class if tab fields has any error.
*
* @return string
*/
private function errorClass()
{
return $this->errors->hasAny($this->fields) ? 'has-error' : '';
}
/**
* Set fields of the tab.
*
* @param array|string $fields
*
* @return self
*/
public function fields($fields)
@@ -157,6 +163,7 @@ class Tab
return $this;
}
/**
* Get fields of the tab.
*
@@ -167,31 +174,61 @@ class Tab
return $this->fields;
}
/**
* Set view of the tab.
*
* @param \Closure|string $view
* @param Closure|string $view
* @param array $data
*
* @return self
*/
public function view($view, $data = [])
public function view($view, $data = [], $prependView = null, $appendView = null)
{
$this->view = $view;
$this->data = $data;
$this->prependView = $prependView;
$this->appendView = $appendView;
return $this;
}
/**
* Get view of the tab.
*
* @param array $data
*
* @return string
*/
public function getView($data = [])
{
$html = "<div class='tab-pane fade in {$this->activeClass()}' id='{$this->name}'>";
$html .= "<h3 class='tab-content-title'>{$this->label}</h3>";
return $this->getPrependView($data) . $this->getMainView($data) . $this->getAppendView($data);
}
public function getPrependView($data = [])
{
$html = '';
if (!is_null($this->prependView)) {
if (is_callable($this->prependView)) {
$html .= call_user_func($this->prependView, $this->name, $this->label, $this->activeClass());
} else {
$html .= $this->prependView;
}
} else {
$html .= "<div class='tab-pane fade in {$this->activeClass()}' id='{$this->name}'>";
$html .= "<h4 class='tab-content-title'>{$this->label}</h4>";
}
return $html;
}
public function getMainView($data = [])
{
$html = '';
if (is_callable($this->view)) {
$html .= call_user_func($this->view, array_merge($this->data, $data));
@@ -199,6 +236,46 @@ class Tab
$html .= view($this->view)->with(array_merge($this->data, $data))->render();
}
return $html .= '</div>';
return $html;
}
public function getAppendView($data = [])
{
$html = '';
if (!is_null($this->appendView)) {
if (is_callable($this->appendView)) {
$html .= call_user_func($this->appendView, $this->name, $this->label, $this->activeClass());
} else {
$html .= $this->appendView;
}
} else {
$html .= '</div>';
}
return $html;
}
/**
* Return active class if tab is active.
*
* @return string
*/
private function activeClass()
{
return $this->active ? 'active' : '';
}
/**
* Return error class if tab fields has any error.
*
* @return string
*/
private function errorClass()
{
return $this->errors->hasAny($this->fields) ? 'has-error' : '';
}
}

View File

@@ -18,11 +18,13 @@ class TabManager
*/
private $extends = [];
/**
* Register a new Tabs.
*
* @param string $name
* @param string $tabs
*
* @return void
*/
public function register($name, $tabs)
@@ -30,28 +32,18 @@ class TabManager
$this->tabs[$name] = $tabs;
}
/**
* Add a new Tabs extender.
*
* @param string $name
* @param string $extender
* @return void
*/
public function extend($name, $extender)
{
$this->extends[$name][] = $extender;
}
/**
* Get tabs for the given name.
*
* @param string $name
* @return \Modules\Admin\Ui\Tabs
*
* @return Tabs
*/
public function get($name)
{
if (! array_key_exists($name, $this->tabs)) {
return;
if (!array_key_exists($name, $this->tabs)) {
return null;
}
return tap(resolve($this->tabs[$name]), function (Tabs $tabs) use ($name) {
@@ -61,11 +53,27 @@ class TabManager
});
}
/**
* Add a new Tabs extender.
*
* @param string $name
* @param string $extender
*
* @return void
*/
public function extend($name, $extender)
{
$this->extends[$name][] = $extender;
}
/**
* Extend the given tabs using the given extenders.
*
* @param \Modules\Admin\Ui\Tabs $tabs
* @param Tabs $tabs
* @param array $extenders
*
* @return void
*/
private function extendTabs(Tabs $tabs, array $extenders)

View File

@@ -36,6 +36,7 @@ abstract class Tabs
*/
protected $buttonOffset = true;
/**
* Make new tabs with groups.
*
@@ -43,23 +44,6 @@ abstract class Tabs
*/
abstract public function make();
/**
* Set group name.
*
* @param string $name
* @param string $title
* @return self
*/
public function group($name, $title = null)
{
$this->group = $name;
if (! is_null($title)) {
$this->groups[$name]['title'] = $title;
}
return $this;
}
/**
* Set current group as active group.
@@ -73,21 +57,24 @@ abstract class Tabs
return $this;
}
/**
* Add new tab.
*
* @param \Modules\Admin\Ui\Tab|null $tab
* @param Tab|null $tab
*
* @return void
*/
public function add($tab)
{
if (! is_null($tab)) {
if (!is_null($tab)) {
$this->tabs[$this->group][] = $tab;
}
return $this;
}
/**
* Determine if tabs fields has any error.
*
@@ -98,16 +85,70 @@ abstract class Tabs
return $this->getErrors()->hasAny($this->getTabFields());
}
/**
* Generate navs for the tabs.
*
* @param array $data
*
* @return HtmlString
*/
public function navs($data = [])
{
return new HtmlString($this->getTabsData('nav', $data));
}
/**
* Render the tabs,
*
* @param array $data
*
* @return void
*/
public function render($data = [])
{
return view('admin::components.accordion', [
'tabs' => $this,
'name' => class_basename($this),
'groups' => $this->groups(),
'contents' => $this->contents($data),
'buttonOffset' => $this->buttonOffset,
]);
}
/**
* Set group name.
*
* @param string $name
* @param string $title
*
* @return self
*/
public function group($name, $title = null)
{
$this->group = $name;
if (!is_null($title)) {
$this->groups[$name]['title'] = $title;
}
return $this;
}
/**
* Get error message bag.
*
* @return \Illuminate\Support\ViewErrorBag
* @return ViewErrorBag
*/
protected function getErrors()
{
return request()->session()->get('errors') ?: new ViewErrorBag;
}
/**
* Get all tabs fields.
*
@@ -120,34 +161,50 @@ abstract class Tabs
}, []);
}
/**
* Generate navs for the tabs.
*
* @param array $data
* @return \Illuminate\Support\HtmlString
*/
public function navs($data = [])
{
return new HtmlString($this->getTabsData('nav', $data));
}
/**
* Render the tabs,
* Get sorted tabs.
*
* @param array $data
* @return void
* @return array
*/
public function render($data = [])
protected function getSortedTabs()
{
return view('admin::components.accordion', [
'tabs' => $this,
'name' => class_basename($this),
'groups' => $this->groups(),
'contents' => $this->contents($data),
'buttonOffset' => $this->buttonOffset,
]);
return collect($this->tabs[$this->group])->sortBy(function (Tab $tab) {
return $tab->getWeight();
})->all();
}
/**
* Get tabs data for the given type.
*
* @param string $type
* @param array $data
*
* @return string
*
* @throws InvalidArgumentException
*/
protected function getTabsData($type, $data = [])
{
if (!array_key_exists($this->group, $this->tabs)) {
throw new InvalidArgumentException("Group [$this->group] is not registered.");
}
$html = '';
foreach ($this->getSortedTabs() as $tab) {
$method = 'get' . ucfirst($type);
if (method_exists($tab, $method)) {
$html .= call_user_func_array([$tab, $method], [$data]);
}
}
return $html;
}
/**
* Get all groups with it's options.
*
@@ -164,11 +221,13 @@ abstract class Tabs
return $groups;
}
/**
* Generate contents for the tabs.
*
* @param array $data
* @return \Illuminate\Support\HtmlString
*
* @return HtmlString
*/
protected function contents($data = [])
{
@@ -180,44 +239,4 @@ abstract class Tabs
return new HtmlString($contents);
}
/**
* Get tabs data for the given type.
*
* @param string $type
* @param array $data
* @return string
*
* @throws \InvalidArgumentException
*/
protected function getTabsData($type, $data = [])
{
if (! array_key_exists($this->group, $this->tabs)) {
throw new InvalidArgumentException("Group [$this->group] is not registered.");
}
$html = '';
foreach ($this->getSortedTabs() as $tab) {
$method = 'get' . ucfirst($type);
if (method_exists($tab, $method)) {
$html .= call_user_func_array([$tab, $method], [$data]);
}
}
return $html;
}
/**
* Get sorted tabs.
*
* @return array
*/
protected function getSortedTabs()
{
return collect($this->tabs[$this->group])->sortBy(function (Tab $tab) {
return $tab->getWeight();
})->all();
}
}