terminando servicios manipulados y preimpresion
@ -494,7 +494,6 @@ $routes->resource('cosidotapablanda', ['namespace' => 'App\Controllers\Presupue
|
||||
|
||||
$routes->group('serviciosacabados', ['namespace' => 'App\Controllers\Presupuestos'], function ($routes) {
|
||||
$routes->post('datatable', 'Presupuestoacabados::datatable', ['as' => 'dataTableOfPresupuestoAcabados']);
|
||||
$routes->get('delete/(:num)', 'Presupuestoacabados::delete/$1', ['as' => 'deletePresupuestoAcabado']);
|
||||
$routes->post('edit/(:num)', 'Presupuestoacabados::edit/$1', ['as' => 'updatePresupuestoacabados']);
|
||||
});
|
||||
|
||||
@ -507,13 +506,13 @@ $routes->group('serviciosencuadernaciones', ['namespace' => 'App\Controllers\Pre
|
||||
});
|
||||
|
||||
$routes->group('serviciosmanipulados', ['namespace' => 'App\Controllers\Presupuestos'], function ($routes) {
|
||||
$routes->post('datatable', 'PresupuestoManipulados::datatable', ['as' => 'dataTableOfPresupuestoManipulados']);
|
||||
$routes->post('datatable_editor', 'PresupuestoManipulados::datatable_editor', ['as' => 'editorOfPresupuestoManipulados']);
|
||||
$routes->post('datatable', 'Presupuestomanipulados::datatable', ['as' => 'dataTableOfPresupuestoManipulados']);
|
||||
$routes->post('edit/(:num)', 'Presupuestomanipulados::edit/$1', ['as' => 'updatePresupuestomanipulados']);
|
||||
});
|
||||
|
||||
$routes->group('serviciospreimpresiones', ['namespace' => 'App\Controllers\Presupuestos'], function ($routes) {
|
||||
$routes->post('datatable', 'PresupuestoPreimpresiones::datatable', ['as' => 'dataTableOfPresupuestoPreimpresiones']);
|
||||
$routes->post('datatable_editor', 'PresupuestoPreimpresiones::datatable_editor', ['as' => 'editorOfPresupuestoPreimpresiones']);
|
||||
$routes->post('datatable', 'Presupuestopreimpresiones::datatable', ['as' => 'dataTableOfPresupuestoPreimpresiones']);
|
||||
$routes->post('edit/(:num)', 'Presupuestopreimpresiones::edit/$1', ['as' => 'updatePresupuestopreimpresiones']);
|
||||
});
|
||||
|
||||
$routes->group('printpresupuestos', ['namespace' => 'App\Controllers\Pdf'], function ($routes) {
|
||||
|
||||
@ -12,6 +12,8 @@ use App\Models\Presupuestos\PresupuestoModel;
|
||||
|
||||
use App\Models\Presupuestos\PresupuestoEncuadernacionesModel;
|
||||
use App\Models\Presupuestos\PresupuestoAcabadosModel;
|
||||
use App\Models\Presupuestos\PresupuestoManipuladosModel;
|
||||
use App\Models\Presupuestos\PresupuestoPreimpresionesModel;
|
||||
|
||||
use App\Services\PresupuestoService;
|
||||
use App\Models\Configuracion\PapelImpresionModel;
|
||||
@ -284,6 +286,8 @@ class Cosidotapablanda extends \App\Controllers\GoBaseResourceController
|
||||
$this->viewData['serviciosManipulado'] = $this->getServiciosManipulado();
|
||||
$this->viewData['serviciosEncuadernacionList'] = (new PresupuestoEncuadernacionesModel())->getResource($id)->get()->getResultObject();
|
||||
$this->viewData['serviciosAcabadosList'] = (new PresupuestoAcabadosModel())->getResource($id)->get()->getResultObject();
|
||||
$this->viewData['serviciosManipuladoList'] = (new PresupuestoManipuladosModel())->getResource($id)->get()->getResultObject();
|
||||
$this->viewData['serviciosPreimpresionList'] = (new PresupuestoPreimpresionesModel())->getResource($id)->get()->getResultObject();
|
||||
|
||||
$this->viewData['POD'] = $this->getPOD();
|
||||
|
||||
|
||||
@ -1,123 +0,0 @@
|
||||
<?php namespace App\Controllers\Presupuestos;
|
||||
|
||||
|
||||
use App\Controllers\GoBaseResourceController;
|
||||
|
||||
use App\Models\Collection;
|
||||
|
||||
use App\Entities\Clientes\ClienteContactoEntity;
|
||||
|
||||
use App\Models\Clientes\ClienteModel;
|
||||
|
||||
use App\Models\Presupuestos\PresupuestoManipuladosModel;
|
||||
use DataTables\Editor;
|
||||
use DataTables\Editor\Field;
|
||||
use DataTables\Editor\Validate;
|
||||
|
||||
class PresupuestoManipulados extends \App\Controllers\GoBaseResourceController
|
||||
{
|
||||
|
||||
protected $modelName = PresupuestoManipuladosModel::class;
|
||||
protected $format = 'json';
|
||||
|
||||
protected static $singularObjectName = 'Presupuesto manipulado';
|
||||
protected static $singularObjectNameCc = 'presupuestoManipulado';
|
||||
protected static $pluralObjectName = 'Presupuestos manipulado';
|
||||
protected static $pluralObjectNameCc = 'presupuestosManipulado';
|
||||
|
||||
protected static $controllerSlug = 'presupuesto-manipulado';
|
||||
|
||||
protected static $viewPath = 'themes/backend/vuexy/form/presupuestos/';
|
||||
|
||||
protected $indexRoute = 'contactoDeClienteList';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
parent::initController($request, $response, $logger);
|
||||
}
|
||||
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$reqData = $this->request->getPost();
|
||||
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
|
||||
$errstr = 'No data available in response to this specific request.';
|
||||
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
|
||||
return $response;
|
||||
}
|
||||
$start = $reqData['start'] ?? 0;
|
||||
$length = $reqData['length'] ?? 5;
|
||||
$requestedOrder = $reqData['order']['0']['column'] ?? 1;
|
||||
$order = PresupuestoManipuladosModel::SORTABLE[$requestedOrder >= 0 ? $requestedOrder : 1];
|
||||
$dir = $reqData['order']['0']['dir'] ?? 'asc';
|
||||
|
||||
$id_P = $reqData['id_presupuesto'] ?? -1;
|
||||
|
||||
$resourceData = $this->model->getResource($id_P)->orderBy($order, $dir)->limit($length, $start)->get()->getResultObject();
|
||||
|
||||
return $this->respond(Collection::datatable(
|
||||
$resourceData,
|
||||
$this->model->getResource()->countAllResults(),
|
||||
$this->model->getResource($id_P)->countAllResults()
|
||||
));
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function datatable_editor() {
|
||||
if ($this->request->isAJAX()) {
|
||||
|
||||
include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php");
|
||||
|
||||
// Build our Editor instance and process the data coming from _POST
|
||||
$response = Editor::inst( $db, 'presupuesto_manipulados' )
|
||||
->fields(
|
||||
Field::inst( 'tarifa_manipulado_id' )
|
||||
->validator( 'Validate::notEmpty',array(
|
||||
'message' => 'Selecciones servicios de acabado' )
|
||||
),
|
||||
Field::inst( 'precio_unidad' )
|
||||
->validator( 'Validate::notEmpty',array(
|
||||
'message' => 'Falta precio unitario' )
|
||||
),
|
||||
Field::inst( 'precio_total' )
|
||||
->validator( 'Validate::notEmpty',array(
|
||||
'message' => 'Falta precio total' )
|
||||
),
|
||||
|
||||
Field::inst( 'presupuesto_id' ),
|
||||
|
||||
)
|
||||
->validator( function($editor, $action, $data){
|
||||
if ($action === Editor::ACTION_CREATE || $action === Editor::ACTION_EDIT){
|
||||
//return $response;
|
||||
/*foreach ($data['data'] as $pkey => $values ){
|
||||
// No se pueden duplicar valores al crear o al editar
|
||||
if (!empty($response)){
|
||||
return $response;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
})
|
||||
->debug(true)
|
||||
->process( $_POST )
|
||||
->data();
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
|
||||
$response[$csrfTokenName] = $newTokenHash;
|
||||
|
||||
echo json_encode($response);
|
||||
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -1,117 +0,0 @@
|
||||
<?php namespace App\Controllers\Presupuestos;
|
||||
|
||||
|
||||
use App\Models\Collection;
|
||||
|
||||
use App\Models\Presupuestos\PresupuestoPreimpresionesModel;
|
||||
use DataTables\Editor;
|
||||
use DataTables\Editor\Field;
|
||||
use DataTables\Editor\Validate;
|
||||
|
||||
class PresupuestoPreimpresiones extends \App\Controllers\GoBaseResourceController
|
||||
{
|
||||
|
||||
protected $modelName = PresupuestoPreimpresionesModel::class;
|
||||
protected $format = 'json';
|
||||
|
||||
protected static $singularObjectName = 'Presupuesto preimpresion';
|
||||
protected static $singularObjectNameCc = 'presupuestoPreimpresion';
|
||||
protected static $pluralObjectName = 'Presupuestos preimpresion';
|
||||
protected static $pluralObjectNameCc = 'presupuestosPreimpresion';
|
||||
|
||||
protected static $controllerSlug = 'presupuesto-preimpresiones';
|
||||
|
||||
protected static $viewPath = 'themes/backend/vuexy/form/presupuestos/';
|
||||
|
||||
protected $indexRoute = 'contactoDeClienteList';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
parent::initController($request, $response, $logger);
|
||||
}
|
||||
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$reqData = $this->request->getPost();
|
||||
if (!isset($reqData['draw']) || !isset($reqData['columns'])) {
|
||||
$errstr = 'No data available in response to this specific request.';
|
||||
$response = $this->respond(Collection::datatable([], 0, 0, $errstr), 400, $errstr);
|
||||
return $response;
|
||||
}
|
||||
$start = $reqData['start'] ?? 0;
|
||||
$length = $reqData['length'] ?? 5;
|
||||
$requestedOrder = $reqData['order']['0']['column'] ?? 1;
|
||||
$order = PresupuestoPreimpresionesModel::SORTABLE[$requestedOrder >= 0 ? $requestedOrder : 1];
|
||||
$dir = $reqData['order']['0']['dir'] ?? 'asc';
|
||||
|
||||
$id_P = $reqData['id_presupuesto'] ?? -1;
|
||||
|
||||
$resourceData = $this->model->getResource($id_P)->orderBy($order, $dir)->limit(50, $start)->get()->getResultObject();
|
||||
|
||||
return $this->respond(Collection::datatable(
|
||||
$resourceData,
|
||||
$this->model->getResource()->countAllResults(),
|
||||
$this->model->getResource($id_P)->countAllResults()
|
||||
));
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function datatable_editor() {
|
||||
if ($this->request->isAJAX()) {
|
||||
|
||||
include(APPPATH . "ThirdParty/DatatablesEditor/DataTables.php");
|
||||
|
||||
// Build our Editor instance and process the data coming from _POST
|
||||
$response = Editor::inst( $db, 'presupuesto_preimpresiones' )
|
||||
->fields(
|
||||
Field::inst( 'tarifa_preimpresion_id' )
|
||||
->validator( 'Validate::notEmpty',array(
|
||||
'message' => 'Selecciones servicios de acabado' )
|
||||
),
|
||||
Field::inst( 'precio_unidad' )
|
||||
->validator( 'Validate::notEmpty',array(
|
||||
'message' => 'Falta precio unitario' )
|
||||
),
|
||||
Field::inst( 'precio_total' )
|
||||
->validator( 'Validate::notEmpty',array(
|
||||
'message' => 'Falta precio total' )
|
||||
),
|
||||
|
||||
Field::inst( 'presupuesto_id' ),
|
||||
|
||||
)
|
||||
->validator( function($editor, $action, $data){
|
||||
if ($action === Editor::ACTION_CREATE || $action === Editor::ACTION_EDIT){
|
||||
//return $response;
|
||||
/*foreach ($data['data'] as $pkey => $values ){
|
||||
// No se pueden duplicar valores al crear o al editar
|
||||
if (!empty($response)){
|
||||
return $response;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
})
|
||||
->debug(true)
|
||||
->process( $_POST )
|
||||
->data();
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
|
||||
$response[$csrfTokenName] = $newTokenHash;
|
||||
|
||||
echo json_encode($response);
|
||||
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -7,9 +7,7 @@ use App\Models\Collection;
|
||||
|
||||
|
||||
use App\Models\Presupuestos\PresupuestoAcabadosModel;
|
||||
use DataTables\Editor;
|
||||
use DataTables\Editor\Field;
|
||||
use DataTables\Editor\Validate;
|
||||
|
||||
|
||||
|
||||
class Presupuestoacabados extends \App\Controllers\GoBaseResourceController
|
||||
|
||||
89
ci4/app/Controllers/Presupuestos/Presupuestomanipulados.php
Executable file
@ -0,0 +1,89 @@
|
||||
<?php namespace App\Controllers\Presupuestos;
|
||||
|
||||
|
||||
use App\Controllers\GoBaseResourceController;
|
||||
|
||||
use App\Models\Collection;
|
||||
|
||||
use App\Entities\Clientes\ClienteContactoEntity;
|
||||
|
||||
use App\Models\Clientes\ClienteModel;
|
||||
|
||||
use App\Models\Presupuestos\PresupuestoManipuladosModel;
|
||||
|
||||
class Presupuestomanipulados extends \App\Controllers\GoBaseResourceController
|
||||
{
|
||||
|
||||
protected $modelName = PresupuestoManipuladosModel::class;
|
||||
protected $format = 'json';
|
||||
|
||||
protected static $singularObjectName = 'Presupuesto manipulado';
|
||||
protected static $singularObjectNameCc = 'presupuestoManipulado';
|
||||
protected static $pluralObjectName = 'Presupuestos manipulado';
|
||||
protected static $pluralObjectNameCc = 'presupuestosManipulado';
|
||||
|
||||
protected static $controllerSlug = 'presupuesto-manipulado';
|
||||
|
||||
protected static $viewPath = 'themes/backend/vuexy/form/presupuestos/';
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
parent::initController($request, $response, $logger);
|
||||
}
|
||||
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
|
||||
if ($requestedId == null) :
|
||||
return;
|
||||
endif;
|
||||
|
||||
$postData = $this->request->getJSON();
|
||||
$tarifas = array_column($postData->datos, 'tarifa_id');
|
||||
if(count($tarifas)>0){
|
||||
$this->model->deleteServiciosNotInArray($requestedId, $tarifas);
|
||||
}
|
||||
else{
|
||||
$this->model->deleteAllServicios($requestedId);
|
||||
}
|
||||
|
||||
$this->model->updateTarifas($requestedId, $postData->datos);
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
$data = [
|
||||
$csrfTokenName => $newTokenHash
|
||||
];
|
||||
|
||||
return $this->respond($data);
|
||||
}
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$reqData = $this->request->getPost();
|
||||
|
||||
$tarifa_manipulado_id = $reqData['tarifa_manipulado_id'] ?? 0;
|
||||
$tirada = $reqData['tirada'] ?? 0;
|
||||
$POD = $reqData['POD'] ?? 0;
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
|
||||
$values = $this->model->getPrecioTarifa($tarifa_manipulado_id, $tirada, $POD);
|
||||
|
||||
$data = [
|
||||
'values' => $values,
|
||||
$csrfTokenName => $newTokenHash
|
||||
];
|
||||
|
||||
return $this->respond($data);
|
||||
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
83
ci4/app/Controllers/Presupuestos/Presupuestopreimpresiones.php
Executable file
@ -0,0 +1,83 @@
|
||||
<?php namespace App\Controllers\Presupuestos;
|
||||
|
||||
|
||||
use App\Models\Collection;
|
||||
|
||||
use App\Models\Presupuestos\PresupuestoPreimpresionesModel;
|
||||
|
||||
|
||||
class Presupuestopreimpresiones extends \App\Controllers\GoBaseResourceController
|
||||
{
|
||||
|
||||
protected $modelName = PresupuestoPreimpresionesModel::class;
|
||||
protected $format = 'json';
|
||||
|
||||
protected static $singularObjectName = 'Presupuesto preimpresion';
|
||||
protected static $singularObjectNameCc = 'presupuestoPreimpresion';
|
||||
protected static $pluralObjectName = 'Presupuestos preimpresion';
|
||||
protected static $pluralObjectNameCc = 'presupuestosPreimpresion';
|
||||
|
||||
protected static $controllerSlug = 'presupuesto-preimpresiones';
|
||||
|
||||
protected static $viewPath = 'themes/backend/vuexy/form/presupuestos/';
|
||||
|
||||
|
||||
|
||||
public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
|
||||
{
|
||||
parent::initController($request, $response, $logger);
|
||||
}
|
||||
|
||||
|
||||
public function edit($requestedId = null)
|
||||
{
|
||||
|
||||
if ($requestedId == null) :
|
||||
return;
|
||||
endif;
|
||||
|
||||
$postData = $this->request->getJSON();
|
||||
$tarifas = array_column($postData->datos, 'tarifa_id');
|
||||
if(count($tarifas)>0){
|
||||
$this->model->deleteServiciosNotInArray($requestedId, $tarifas);
|
||||
}
|
||||
else{
|
||||
$this->model->deleteAllServicios($requestedId);
|
||||
}
|
||||
|
||||
$this->model->updateTarifas($requestedId, $postData->datos);
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
$data = [
|
||||
$csrfTokenName => $newTokenHash
|
||||
];
|
||||
|
||||
return $this->respond($data);
|
||||
}
|
||||
|
||||
public function datatable()
|
||||
{
|
||||
if ($this->request->isAJAX()) {
|
||||
$reqData = $this->request->getPost();
|
||||
|
||||
$tarifa_preimpresion_id = $reqData['tarifa_preimpresion_id'] ?? 0;
|
||||
|
||||
$newTokenHash = csrf_hash();
|
||||
$csrfTokenName = csrf_token();
|
||||
|
||||
$values = $this->model->getPrecioTarifa($tarifa_preimpresion_id);
|
||||
|
||||
$data = [
|
||||
'values' => $values,
|
||||
$csrfTokenName => $newTokenHash
|
||||
];
|
||||
|
||||
return $this->respond($data);
|
||||
|
||||
} else {
|
||||
return $this->failUnauthorized('Invalid request', 403);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
0
ci4/app/Controllers/Tarifas/Tarifaencuadernacionlineashoras.php
Normal file → Executable file
0
ci4/app/Entities/Tarifas/TarifaEncuadernacionLineaHoras.php
Normal file → Executable file
@ -8,7 +8,7 @@ class TarifapreimpresionEntity extends \CodeIgniter\Entity\Entity
|
||||
protected $attributes = [
|
||||
"id" => null,
|
||||
"nombre" => null,
|
||||
"precio_pagina" => null,
|
||||
"precio" => null,
|
||||
"precio_min" => 0,
|
||||
"importe_fijo" => 0,
|
||||
"margen" => 0,
|
||||
@ -21,7 +21,7 @@ class TarifapreimpresionEntity extends \CodeIgniter\Entity\Entity
|
||||
"updated_at" => null,
|
||||
];
|
||||
protected $casts = [
|
||||
"precio_pagina" => "float",
|
||||
"precio" => "float",
|
||||
"precio_min" => "float",
|
||||
"importe_fijo" => "float",
|
||||
"margen" => "float",
|
||||
|
||||
@ -8,7 +8,7 @@ return [
|
||||
'id' => 'ID',
|
||||
'moduleTitle' => 'Preprinting rates',
|
||||
'nombre' => 'Name',
|
||||
'precio' => 'Price per page',
|
||||
'precio' => 'Price',
|
||||
'precioMin' => 'Min Price',
|
||||
'importeFijo' => 'Fixed amount',
|
||||
'margen' => 'Margin',
|
||||
|
||||
@ -153,6 +153,8 @@ return [
|
||||
'servicioEncuadernado' => 'Servicio de encuadernación',
|
||||
'servicioEncuadernadoList' => 'Servicios de encuadernación',
|
||||
'servicioAcabadoList' => 'Servicios de acabado',
|
||||
'servicioManipuladoList' => 'Servicios de manipulado',
|
||||
'servicioPreimpresionList' => 'Servicios de preimpresion',
|
||||
|
||||
'servicioManipulado' => 'Servicio de manipulado',
|
||||
'comentarios' => 'Comentarios',
|
||||
@ -168,6 +170,7 @@ return [
|
||||
'confirmar' => 'Confirmar presupuesto',
|
||||
|
||||
// Servicios
|
||||
'precio' => 'Precio',
|
||||
'precioUnidad' => 'Precio unitario',
|
||||
'precioTotal' => 'Precio total',
|
||||
'serviciosEncDefault' => 'Servicios Enc. por defecto',
|
||||
|
||||
@ -7,7 +7,7 @@ return [
|
||||
'id' => 'ID',
|
||||
'moduleTitle' => 'Tarifas Preimpresión',
|
||||
'nombre' => 'Nombre',
|
||||
'precio' => 'Precio/página',
|
||||
'precio' => 'Precio',
|
||||
'precioMin' => 'Precio Mínimo',
|
||||
'importeFijo' => 'Importe Fijo',
|
||||
'mostrar_en_presupuesto' => 'Mostrar en presupuesto',
|
||||
|
||||
@ -45,6 +45,101 @@ class PresupuestoManipuladosModel extends \App\Models\GoBaseModel
|
||||
];
|
||||
|
||||
|
||||
public function getPrecioTarifa($tarifa_manipulado_id, $tirada, $POD){
|
||||
|
||||
$modelTarifa = model('App\Models\Tarifas\TarifaManipuladoModel');
|
||||
$tarifa_value = $modelTarifa->getTarifaPresupuestoManipulado($tarifa_manipulado_id, $tirada);
|
||||
if (count($tarifa_value)>0) {
|
||||
|
||||
$result_data = $this->calcularTarifa($tarifa_value[0], $tirada, $POD<$tirada?false:true);
|
||||
$ret_array[] = (object)[
|
||||
'tarifa_id'=> $tarifa_value[0]->tarifa_manipulado_id,
|
||||
'tarifa_nombre'=> $tarifa_value[0]->tarifa_manipulado_nombre,
|
||||
'precio_unidad'=> $result_data[0],
|
||||
'total'=> $result_data[1],
|
||||
];
|
||||
return $ret_array;
|
||||
}
|
||||
else{
|
||||
$ret_array[] = (object)[
|
||||
'tarifa_id'=> $tarifa_manipulado_id,
|
||||
'tarifa_nombre'=> $modelTarifa->getNombreTarifaManipulado($tarifa_manipulado_id)[0]->nombre,
|
||||
'precio_unidad' => 0,
|
||||
'total'=> 0,
|
||||
];
|
||||
return $ret_array;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private function calcularTarifa($tarifa, $tirada, $is_POD=false){
|
||||
|
||||
$precio_unidad = floatval($tarifa->precio_min) - (floatval($tarifa->precio_min) - floatval($tarifa->precio_max))/($tarifa->tirada_max - $tarifa->tirada_min) * ($tirada - $tarifa->tirada_min);
|
||||
if ($tirada > $tarifa->tirada_max)
|
||||
$precio_unidad = $tarifa->precio_max;
|
||||
$precio_unidad = $precio_unidad* (1+ floatval($tarifa->margen)/100.0);
|
||||
|
||||
$total = $precio_unidad * $tirada;
|
||||
|
||||
if (!$is_POD){
|
||||
$total += floatval($tarifa->tarifa_importe_fijo);
|
||||
}
|
||||
|
||||
return [$precio_unidad, $total];
|
||||
}
|
||||
|
||||
public function deleteAllServicios($presupuesto_id){
|
||||
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->where('presupuesto_id', $presupuesto_id)
|
||||
->delete();
|
||||
}
|
||||
|
||||
public function deleteServiciosNotInArray($presupuesto_id, $tarifas_id){
|
||||
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1");
|
||||
$builder->where('presupuesto_id', $presupuesto_id);
|
||||
foreach($tarifas_id as $id){
|
||||
$builder->where('tarifa_manipulado_id !=', $id);
|
||||
}
|
||||
$builder->delete();
|
||||
}
|
||||
|
||||
public function updateTarifas($presupuesto_id, $tarifas){
|
||||
|
||||
foreach($tarifas as $tarifa){
|
||||
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1");
|
||||
$builder->select("id");
|
||||
$builder->where('presupuesto_id', $presupuesto_id);
|
||||
$builder->where('tarifa_manipulado_id', $tarifa->tarifa_id);
|
||||
$result = $builder->get()->getResultObject();
|
||||
if(count($result)>0){
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->where('presupuesto_id', $presupuesto_id)
|
||||
->where('tarifa_manipulado_id', $tarifa->tarifa_id)
|
||||
->set('precio_unidad', $tarifa->precio_unidad)
|
||||
->set('precio_total', $tarifa->precio_total)
|
||||
->update();
|
||||
|
||||
|
||||
}
|
||||
else{
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->set('presupuesto_id', $presupuesto_id)
|
||||
->set('tarifa_manipulado_id', $tarifa->tarifa_id)
|
||||
->set('precio_unidad', $tarifa->precio_unidad)
|
||||
->set('precio_total', $tarifa->precio_total)
|
||||
->insert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get resource data.
|
||||
*
|
||||
|
||||
@ -45,6 +45,90 @@ class PresupuestoPreimpresionesModel extends \App\Models\GoBaseModel
|
||||
];
|
||||
|
||||
|
||||
public function getPrecioTarifa($tarifa_preimpresion_id){
|
||||
|
||||
$modelTarifa = model('App\Models\Tarifas\TarifapreimpresionModel');
|
||||
$tarifa_value = $modelTarifa->getTarifaPresupuestoPreimpresion($tarifa_preimpresion_id);
|
||||
if (count($tarifa_value)>0) {
|
||||
|
||||
$result_data = $this->calcularTarifa($tarifa_value[0]);
|
||||
$ret_array[] = (object)[
|
||||
'tarifa_id'=> $tarifa_value[0]->tarifa_preimpresion_id,
|
||||
'tarifa_nombre'=> $tarifa_value[0]->tarifa_preimpresion_nombre,
|
||||
'precio'=> $result_data,
|
||||
];
|
||||
return $ret_array;
|
||||
}
|
||||
else{
|
||||
$ret_array[] = (object)[
|
||||
'tarifa_id'=> $tarifa_preimpresion_id,
|
||||
'tarifa_nombre'=> $modelTarifa->getNombreTarifaPreimpresion($tarifa_preimpresion_id)[0]->nombre,
|
||||
'precio' => 0,
|
||||
];
|
||||
return $ret_array;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private function calcularTarifa($tarifa){
|
||||
|
||||
$precio = floatval($tarifa->precio);
|
||||
$precio = $precio * (1+ floatval($tarifa->margen)/100.0);
|
||||
|
||||
return $precio;
|
||||
}
|
||||
|
||||
public function deleteAllServicios($presupuesto_id){
|
||||
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->where('presupuesto_id', $presupuesto_id)
|
||||
->delete();
|
||||
}
|
||||
|
||||
public function deleteServiciosNotInArray($presupuesto_id, $tarifas_id){
|
||||
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1");
|
||||
$builder->where('presupuesto_id', $presupuesto_id);
|
||||
foreach($tarifas_id as $id){
|
||||
$builder->where('tarifa_preimpresion_id !=', $id);
|
||||
}
|
||||
$builder->delete();
|
||||
}
|
||||
|
||||
public function updateTarifas($presupuesto_id, $tarifas){
|
||||
|
||||
foreach($tarifas as $tarifa){
|
||||
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1");
|
||||
$builder->select("id");
|
||||
$builder->where('presupuesto_id', $presupuesto_id);
|
||||
$builder->where('tarifa_preimpresion_id', $tarifa->tarifa_id);
|
||||
$result = $builder->get()->getResultObject();
|
||||
if(count($result)>0){
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->where('presupuesto_id', $presupuesto_id)
|
||||
->where('tarifa_preimpresion_id', $tarifa->tarifa_id)
|
||||
->set('precio', $tarifa->precio)
|
||||
->update();
|
||||
|
||||
|
||||
}
|
||||
else{
|
||||
$this->db
|
||||
->table($this->table . " t1")
|
||||
->set('presupuesto_id', $presupuesto_id)
|
||||
->set('tarifa_preimpresion_id', $tarifa->tarifa_id)
|
||||
->set('precio', $tarifa->precio)
|
||||
->insert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get resource data.
|
||||
*
|
||||
@ -57,7 +141,7 @@ class PresupuestoPreimpresionesModel extends \App\Models\GoBaseModel
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.id AS id, t1.tarifa_preimpresion_id AS tarifa_preimpresion_id, t1.precio_unidad AS precio_unidad, t1.precio_total AS precio_total, t2.nombre AS nombre"
|
||||
"t1.id AS id, t1.tarifa_preimpresion_id AS tarifa_preimpresion_id, t1.precio AS precio, t2.nombre AS nombre"
|
||||
);
|
||||
|
||||
$builder->where('t1.presupuesto_id', $presupuesto_id);
|
||||
|
||||
0
ci4/app/Models/Tarifas/TarifaEncuadernacionLineaHorasModel.php
Normal file → Executable file
@ -109,4 +109,41 @@ class TarifaManipuladoModel extends \App\Models\GoBaseModel
|
||||
|
||||
return $builder->orderBy("t1.nombre", "asc")->get()->getResultObject();
|
||||
}
|
||||
|
||||
public function getTarifaPresupuestoManipulado($tarifa_id, $tirada){
|
||||
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.id AS tarifa_manipulado_id, t1.nombre AS tarifa_manipulado_nombre, t1.precio_min AS tarifa_precio_min, t1.importe_fijo AS tarifa_importe_fijo,
|
||||
t2.id AS tarifa_linea_id, t2.tirada_min AS tirada_min, t2.tirada_max AS tirada_max,
|
||||
t2.precio_min AS precio_min, t2.precio_max AS precio_max, t2.margen AS margen"
|
||||
)
|
||||
->join("tarifa_manipulado_lineas t2", "t1.id = t2.tarifa_manipulado_id", "left")
|
||||
->where("t1.is_deleted", 0)
|
||||
//->where("t1.mostrar_en_presupuesto", 1)
|
||||
->where("t2.is_deleted", 0);
|
||||
|
||||
$builder->where('t1.id =', $tarifa_id);
|
||||
$builder->where('t2.tirada_min <=', $tirada);
|
||||
$builder->where('t2.tirada_max >', $tirada);
|
||||
|
||||
return $builder->get()->getResultObject();
|
||||
}
|
||||
|
||||
public function getNombreTarifaManipulado($id=-1)
|
||||
{
|
||||
/*
|
||||
Todos los servicios de encuadernacion activas que se pueden usar en presupuestos
|
||||
*/
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.nombre AS nombre"
|
||||
)
|
||||
->where("t1.id", $id)
|
||||
->where("t1.is_deleted", 0);
|
||||
|
||||
return $builder->orderBy("t1.nombre", "asc")->get()->getResultObject();
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ class TarifapreimpresionModel extends \App\Models\GoBaseModel
|
||||
|
||||
protected $allowedFields = [
|
||||
"nombre",
|
||||
"precio_pagina",
|
||||
"precio",
|
||||
"precio_min",
|
||||
"importe_fijo",
|
||||
"margen",
|
||||
@ -39,7 +39,7 @@ class TarifapreimpresionModel extends \App\Models\GoBaseModel
|
||||
"label" => "Tarifapreimpresion.nombre",
|
||||
"rules" => "trim|required|max_length[255]",
|
||||
],
|
||||
"precio_pagina" => [
|
||||
"precio" => [
|
||||
"label" => "Tarifapreimpresion.precio",
|
||||
"rules" => "required|decimal",
|
||||
],
|
||||
@ -62,7 +62,7 @@ class TarifapreimpresionModel extends \App\Models\GoBaseModel
|
||||
"max_length" => "Tarifapreimpresion.validation.nombre.max_length",
|
||||
"required" => "Tarifapreimpresion.validation.nombre.required",
|
||||
],
|
||||
"precio_pagina" => [
|
||||
"precio" => [
|
||||
"decimal" => "Tarifapreimpresion.validation.precio.decimal",
|
||||
"required" => "Tarifapreimpresion.validation.precio.required",
|
||||
],
|
||||
@ -96,5 +96,35 @@ class TarifapreimpresionModel extends \App\Models\GoBaseModel
|
||||
return $builder->orderBy("t1.nombre", "asc")->get()->getResultObject();
|
||||
}
|
||||
|
||||
public function getTarifaPresupuestoPreimpresion($tarifa_id){
|
||||
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.id AS tarifa_preimpresion_id, t1.nombre AS tarifa_preimpresion_nombre, t1.precio AS precio, t1.margen AS margen"
|
||||
)
|
||||
->where("t1.is_deleted", 0);
|
||||
//->where("t1.mostrar_en_presupuesto", 1)
|
||||
|
||||
$builder->where('t1.id =', $tarifa_id);
|
||||
|
||||
return $builder->get()->getResultObject();
|
||||
}
|
||||
|
||||
public function getNombreTarifaPreimpresion($id=-1)
|
||||
{
|
||||
/*
|
||||
Todos los servicios de encuadernacion activas que se pueden usar en presupuestos
|
||||
*/
|
||||
$builder = $this->db
|
||||
->table($this->table . " t1")
|
||||
->select(
|
||||
"t1.nombre AS nombre"
|
||||
)
|
||||
->where("t1.id", $id)
|
||||
->where("t1.is_deleted", 0);
|
||||
|
||||
return $builder->orderBy("t1.nombre", "asc")->get()->getResultObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
</table>
|
||||
<div class="row mb-3 px-4">
|
||||
<div class="col-md-12 col-lg-4 py-4">
|
||||
<select id="add_servicio_acabado_list" class="proveedor_enc select2bs2" style="width: 100%;">
|
||||
<select id="add_servicio_acabado_list" class="select2bs2" style="width: 100%;">
|
||||
<option></option>
|
||||
<?php foreach ($serviciosAcabado as $item) : ?>
|
||||
<option value="<?= $item->value ?>" >
|
||||
@ -101,18 +101,38 @@
|
||||
|
||||
|
||||
<div class="tab-pane fade" id="servicios-preimpresion" role="tabpanel">
|
||||
<div id="serv-preimpresion-alert">
|
||||
</div>
|
||||
<div id="serv-preimpresion-error">
|
||||
</div>
|
||||
<table id="tableOfServiciosPreimpresion" class="table table-striped table-hover" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= lang('Presupuestos.id') ?></th>
|
||||
<th><?= lang('Tarifapreimpresion.tarifapreimpresion') ?></th>
|
||||
<th><?= lang('Presupuestos.precioUnidad') ?></th>
|
||||
<th><?= lang('Presupuestos.precioTotal') ?></th>
|
||||
<th><?= lang('Presupuestos.precio') ?></th>
|
||||
<th class="text-nowrap"><?= lang('Basic.global.Action') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row mb-3 px-4">
|
||||
<div class="col-md-12 col-lg-4 py-4">
|
||||
<select id="add_servicio_preimpresion_list" class="select2bs2" style="width: 100%;">
|
||||
<option></option>
|
||||
<?php foreach ($serviciosPreimpresion as $item) : ?>
|
||||
<option value="<?= $item->value ?>" >
|
||||
<?= $item->label ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12 col-lg-4 px-2 py-4">
|
||||
<button id="insertar_serv_preimpresion" type="button" class="btn btn-secondary waves-effect waves-light float-start"><?= lang("Presupuestos.insertar")?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="servicios-encuadernacion" role="tabpanel">
|
||||
@ -143,7 +163,7 @@
|
||||
</table>
|
||||
<div class="row mb-3 px-4">
|
||||
<div class="col-md-12 col-lg-4 py-4">
|
||||
<select id="add_servicio_enc_list" class="proveedor_enc select2bs2" style="width: 100%;">
|
||||
<select id="add_servicio_enc_list" class="select2bs2" style="width: 100%;">
|
||||
<option></option>
|
||||
<?php foreach ($serviciosEncuadernacion as $item) : ?>
|
||||
<option value="<?= $item->value ?>" >
|
||||
@ -161,9 +181,14 @@
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade" id="servicios-manipulado" role="tabpanel">
|
||||
<div id="serv-manipulado-alert">
|
||||
</div>
|
||||
<div id="serv-manipulado-error">
|
||||
</div>
|
||||
<table id="tableOfServiciosManipulado" class="table table-striped table-hover" style="width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?= lang('Presupuestos.id') ?></th>
|
||||
<th><?= lang('Tarifamanipulado.tarifamanipulado') ?></th>
|
||||
<th><?= lang('Presupuestos.precioUnidad') ?></th>
|
||||
<th><?= lang('Presupuestos.precioTotal') ?></th>
|
||||
@ -173,6 +198,22 @@
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row mb-3 px-4">
|
||||
<div class="col-md-12 col-lg-4 py-4">
|
||||
<select id="add_servicio_manipulado_list" class="select2bs2" style="width: 100%;">
|
||||
<option></option>
|
||||
<?php foreach ($serviciosManipulado as $item) : ?>
|
||||
<option value="<?= $item->value ?>" >
|
||||
<?= $item->label ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-12 col-lg-4 px-2 py-4">
|
||||
<button id="insertar_serv_manipulado" type="button" class="btn btn-secondary waves-effect waves-light float-start"><?= lang("Presupuestos.insertar")?></button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -198,6 +239,9 @@
|
||||
|
||||
$('.nav-servicios button').on('shown.bs.tab', function(){
|
||||
$("#tableOfServiciosEncuadernacion").DataTable().columns.adjust();
|
||||
$("#tableOfServiciosPreimpresion").DataTable().columns.adjust();
|
||||
$("#tableOfServiciosManipulado").DataTable().columns.adjust();
|
||||
$("#tableOfServiciosAcabado").DataTable().columns.adjust();
|
||||
})
|
||||
|
||||
|
||||
@ -215,6 +259,12 @@
|
||||
else if($(this).closest('table').attr('id').includes('tableOfServiciosAcabado')){
|
||||
table = "tableOfServiciosAcabado";
|
||||
}
|
||||
else if($(this).closest('table').attr('id').includes('tableOfServiciosManipulado')){
|
||||
table = "tableOfServiciosManipulado";
|
||||
}
|
||||
else if($(this).closest('table').attr('id').includes('tableOfServiciosPreimpresion')){
|
||||
table = "tableOfServiciosPreimpresion";
|
||||
}
|
||||
else{
|
||||
table = "";
|
||||
}
|
||||
@ -229,14 +279,18 @@
|
||||
|
||||
check_serv_enc_error()
|
||||
check_serv_acabado_error()
|
||||
check_serv_preimpresion_error()
|
||||
check_serv_manipulado_error()
|
||||
|
||||
});
|
||||
|
||||
function save_servicios(){
|
||||
|
||||
var datosAcabado = get_datos_acabado()
|
||||
|
||||
var datosEnc = get_datos_encuadernacion()
|
||||
var datosManipulado = get_datos_manipulado()
|
||||
var datosPreimpresion = get_datos_preimpresion()
|
||||
|
||||
const domain = window.location.origin
|
||||
|
||||
fetch(domain + "/presupuestos/presupuestoencuadernaciones/edit/" + id , {
|
||||
@ -253,23 +307,54 @@
|
||||
.then(data => {
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
})
|
||||
.then(
|
||||
fetch(domain + "/presupuestos/presupuestoacabados/edit/" + id , {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
datos: datosAcabado,
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
})
|
||||
|
||||
)
|
||||
.then(
|
||||
fetch(domain + "/presupuestos/presupuestomanipulados/edit/" + id , {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
datos: datosAcabado,
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
})
|
||||
)
|
||||
.then(
|
||||
fetch(domain + "/presupuestos/presupuestoacabados/edit/" + id , {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
datos: datosManipulado,
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
})
|
||||
)
|
||||
.then(
|
||||
fetch(domain + "/presupuestos/presupuestopreimpresiones/edit/" + id , {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
datos: datosPreimpresion,
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
|
||||
}),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
})
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@ -341,7 +426,6 @@
|
||||
}
|
||||
|
||||
function get_tarifas_acabado(tarifa_id = -1){
|
||||
const dimension = getDimensionLibro();
|
||||
|
||||
if(parseInt($('#tirada').val())>0){
|
||||
var tirada = parseInt($('#tirada').val())
|
||||
@ -396,7 +480,7 @@
|
||||
popErrorAlert("Ese servicio ya existe", 'serv-acabado-alert')
|
||||
}
|
||||
}
|
||||
check_serv_enc_error()
|
||||
check_serv_acabado_error()
|
||||
})
|
||||
|
||||
function get_datos_acabado(){
|
||||
@ -434,9 +518,6 @@
|
||||
<!-------------------------------------------------------------->
|
||||
<?= $this->section("additionalInlineJs") ?>
|
||||
|
||||
// Generación de la lista de servicios de acabado (id, nombre)
|
||||
const encuadernadosList = <?php echo json_encode($serviciosEncuadernacion); ?>;
|
||||
|
||||
var tableServiciosEnc = new DataTable('#tableOfServiciosEncuadernacion',{
|
||||
scrollX: true,
|
||||
searching: false,
|
||||
@ -735,137 +816,150 @@
|
||||
<!-- Código JS comportamiento tabla servicios manipulados. -->
|
||||
<!-------------------------------------------------------------->
|
||||
<?= $this->section("additionalInlineJs") ?>
|
||||
/*
|
||||
const lastColNr3 = $('#tableOfServiciosManipulado').find("tr:first th").length - 1;
|
||||
|
||||
editor3 = new $.fn.dataTable.Editor( {
|
||||
ajax: {
|
||||
url: "<?= route_to('editorOfPresupuestoManipulados') ?>",
|
||||
headers: {
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v,
|
||||
},
|
||||
},
|
||||
table : "#tableOfServiciosManipulado",
|
||||
idSrc: 'id',
|
||||
fields: [ {
|
||||
"name": "tarifa_manipulado_id",
|
||||
"type": "select"
|
||||
}, {
|
||||
"name": "precio_unidad"
|
||||
}, {
|
||||
"name": "precio_total"
|
||||
}, {
|
||||
"name": "presupuesto_id",
|
||||
"type": "hidden"
|
||||
},
|
||||
]
|
||||
} );
|
||||
|
||||
// Generación de la lista de servicios de acabado (id, nombre)
|
||||
const manipuladosList = <?php echo json_encode($serviciosManipulado); ?>;
|
||||
editor3.field( 'tarifa_manipulado_id' ).update( manipuladosList );
|
||||
|
||||
editor3.on( 'preSubmit', function ( e, d, type ) {
|
||||
if ( type === 'create'){
|
||||
d.data[0]['presupuesto_id'] = id;
|
||||
}
|
||||
else if(type === 'edit' ) {
|
||||
for (v in d.data){
|
||||
d.data[v]['presupuesto_id'] = id;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editor3.on( 'postSubmit', function ( e, json, data, action ) {
|
||||
yeniden(json.<?= csrf_token() ?>);
|
||||
});
|
||||
|
||||
editor3.on( 'submitSuccess', function ( e, json, data, action ) {
|
||||
theTable3.clearPipeline();
|
||||
theTable3.draw();
|
||||
});
|
||||
|
||||
// Activate an inline edit on click of a table cell
|
||||
$('#tableOfServiciosManipulado').on( 'click', 'tbody span.edit', function (e) {
|
||||
editor3.inline(
|
||||
theTable3.cells(this.parentNode.parentNode, '*').nodes(),
|
||||
{
|
||||
cancelHtml: '<a href="javascript:void(0);"><i class="ti ti-x"></i></a>',
|
||||
cancelTrigger: 'span.cancel',
|
||||
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>',
|
||||
submitTrigger: 'span.edit',
|
||||
submit: 'allIfChanged'
|
||||
}
|
||||
);
|
||||
} );
|
||||
|
||||
|
||||
// Delete row
|
||||
|
||||
|
||||
var theTable3 = $('#tableOfServiciosManipulado').DataTable( {
|
||||
draw: 3,
|
||||
serverSide: false,
|
||||
processing: true,
|
||||
autoWidth: true,
|
||||
responsive: true,
|
||||
lengthMenu: [ 5, 10, 25],
|
||||
order: [[ 0, "asc" ], [ 1, "asc" ]],
|
||||
pageLength: 10,
|
||||
lengthChange: true,
|
||||
var tableServiciosManipulado = new DataTable('#tableOfServiciosManipulado',{
|
||||
scrollX: true,
|
||||
searching: false,
|
||||
paging: true,
|
||||
paging: false,
|
||||
info: false,
|
||||
dom: '<"mt-4"><"float-start"l><t><"mt-4 mb-3"p>',
|
||||
ajax : $.fn.dataTable.pipeline( {
|
||||
url: '<?= route_to('dataTableOfPresupuestoManipulados') ?>',
|
||||
data: {
|
||||
id_presupuesto: id,
|
||||
},
|
||||
method: 'POST',
|
||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||
async: true,
|
||||
}),
|
||||
columns: [
|
||||
{'data': 'tarifa_manipulado_id',
|
||||
render: function(data, type, row, meta) {
|
||||
var value = manipuladosList.find(element => element.value === data);
|
||||
return value['label'];
|
||||
},
|
||||
},
|
||||
{ 'data': 'precio_unidad' },
|
||||
{ 'data': 'precio_total' },
|
||||
{
|
||||
data: actionBtns,
|
||||
className: 'row-edit dt-center'
|
||||
}
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
targets: [lastColNr3]
|
||||
},
|
||||
{
|
||||
"orderData": [ 0, 1 ],
|
||||
"targets": 0
|
||||
},
|
||||
|
||||
],
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
select: false,
|
||||
language: {
|
||||
url: "//cdn.datatables.net/plug-ins/1.13.4/i18n/<?= config('Basics')->i18n ?>.json"
|
||||
},
|
||||
buttons: [ {
|
||||
className: 'btn btn-primary float-end me-sm-3 me-1',
|
||||
extend: "createInline",
|
||||
editor: editor3,
|
||||
formOptions: {
|
||||
submitTrigger: -1,
|
||||
submitHtml: '<i class="ti ti-device-floppy"/>'
|
||||
|
||||
});
|
||||
|
||||
function init_servicio_manipulado(){
|
||||
const serviciosmanipuladoList = <?php echo json_encode($serviciosManipuladoList); ?>;
|
||||
|
||||
$('#add_servicio_manipulado_list').select2({
|
||||
allowClear: false,
|
||||
minimumResultsForSearch: -1,
|
||||
placeholder: '<?= lang("Presupuestos.servicioManipuladoList") ?>'
|
||||
})
|
||||
|
||||
serviciosmanipuladoList.forEach((element) =>{
|
||||
|
||||
tableServiciosManipulado.row.add([
|
||||
element.tarifa_manipulado_id,
|
||||
element.nombre,
|
||||
'<span id="precio_unidad_' + element.tarifa_manipulado_id + '">' + parseFloat(element.precio_unidad).toFixed(2) + '</span>',
|
||||
'<input id="precio_total_' + element.tarifa_manipulado_id +'" value="' + parseFloat(element.precio_total).toFixed(2) + '"></input>',
|
||||
'<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-serv mx-2" data-id="' + element.tarifa_manipulado_id +'"></i></a>'
|
||||
]).draw(false)
|
||||
|
||||
})
|
||||
check_serv_manipulado_error()
|
||||
}
|
||||
|
||||
function check_serv_manipulado_error(){
|
||||
|
||||
var htmlString = '';
|
||||
|
||||
$('#tableOfServiciosManipulado tr').each(function(){
|
||||
if($(this).find('td').eq(2).text() == '0.00'){
|
||||
htmlString = `
|
||||
<div class="alert alert-danger d-flex align-items-baseline" role="alert">
|
||||
<span class="alert-icon alert-icon-lg text-primary me-2">
|
||||
<i class="ti ti-ban ti-sm"></i>
|
||||
</span>
|
||||
<div class="d-flex flex-column ps-1">
|
||||
<h5 class="alert-heading mb-2"><?= lang("Presupuestos.errores.error_servicios_anadidos") ?></h5>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
} ]
|
||||
} );
|
||||
*/
|
||||
})
|
||||
$('#serv-manipulado-error').html(htmlString)
|
||||
}
|
||||
|
||||
function get_tarifas_manipulado(tarifa_id = -1){
|
||||
|
||||
if(parseInt($('#tirada').val())>0){
|
||||
var tirada = parseInt($('#tirada').val())
|
||||
}
|
||||
else{
|
||||
var tirada = 0
|
||||
}
|
||||
|
||||
var datos = {
|
||||
tarifa_manipulado_id : tarifa_id,
|
||||
tirada: tirada,
|
||||
POD: POD,
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
|
||||
};
|
||||
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '<?=route_to('dataTableOfPresupuestoManipulados') ?>',
|
||||
data: datos,
|
||||
success: function (data) {
|
||||
|
||||
data.values.forEach((row) => {
|
||||
|
||||
tableServiciosManipulado.row.add([
|
||||
row.tarifa_id,
|
||||
row.tarifa_nombre,
|
||||
'<span id="precio_unidad_' + row.tarifa_id + '">' + parseFloat(row.precio_unidad).toFixed(2) + '</span>',
|
||||
'<input id="precio_total_' + row.tarifa_id +'" value="' + parseFloat(row.total).toFixed(2) + '"></input>',
|
||||
'<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-serv mx-2" data-id="' + row.tarifa_id +'"></i></a>'
|
||||
]).draw(false)
|
||||
});
|
||||
|
||||
check_serv_manipulado_error()
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
return true;
|
||||
},
|
||||
error: function(e){
|
||||
return false;
|
||||
}
|
||||
})
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#insertar_serv_manipulado').on('click', function(){
|
||||
const tarifa_text = $('#add_servicio_manipulado_list').select2('data')[0].text.trim()
|
||||
|
||||
if( $('#add_servicio_manipulado_list').select2('data')[0].text.trim().length > 0){
|
||||
if($('#tableOfServiciosManipulado tr > td:contains(' + tarifa_text + ')').length == 0)
|
||||
get_tarifas_manipulado($('#add_servicio_manipulado_list').select2('data')[0].id);
|
||||
else{
|
||||
popErrorAlert("Ese servicio ya existe", 'serv-manipulado-alert')
|
||||
}
|
||||
}
|
||||
check_serv_manipulado_error()
|
||||
})
|
||||
|
||||
function get_datos_manipulado(){
|
||||
|
||||
var datosManipulado = []
|
||||
$("#tableOfServiciosManipulado tr").each(function (index,tr) {
|
||||
var values = {}
|
||||
$(this).find("td").each(function (index2) {
|
||||
|
||||
switch (index2) {
|
||||
case 0:
|
||||
values['tarifa_id'] = $(this).text()
|
||||
break
|
||||
case 2:
|
||||
values['precio_unidad'] = $(this).text()
|
||||
break
|
||||
case 3:
|
||||
values['precio_total'] = $(this).children(":first").val()
|
||||
break
|
||||
}
|
||||
})
|
||||
if(Object.keys(values).length>0)
|
||||
datosManipulado.push(values)
|
||||
})
|
||||
|
||||
return datosManipulado
|
||||
}
|
||||
|
||||
init_servicio_manipulado()
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
|
||||
@ -873,135 +967,135 @@
|
||||
<!-- Código JS comportamiento tabla servicios preimpresion. -->
|
||||
<!-------------------------------------------------------------->
|
||||
<?= $this->section("additionalInlineJs") ?>
|
||||
/*
|
||||
const lastColNr4 = $('#tableOfServiciosPreimpresion').find("tr:first th").length - 1;
|
||||
|
||||
editor4 = new $.fn.dataTable.Editor( {
|
||||
ajax: {
|
||||
url: "<?= route_to('editorOfPresupuestoPreimpresiones') ?>",
|
||||
headers: {
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v,
|
||||
},
|
||||
},
|
||||
table : "#tableOfServiciosPreimpresion",
|
||||
idSrc: 'id',
|
||||
fields: [ {
|
||||
"name": "tarifa_preimpresion_id",
|
||||
"type": "select"
|
||||
}, {
|
||||
"name": "precio_unidad"
|
||||
}, {
|
||||
"name": "precio_total"
|
||||
}, {
|
||||
"name": "presupuesto_id",
|
||||
"type": "hidden"
|
||||
},
|
||||
]
|
||||
} );
|
||||
|
||||
// Generación de la lista de servicios de acabado (id, nombre)
|
||||
const preimpresionesList = <?php echo json_encode($serviciosPreimpresion); ?>;
|
||||
editor4.field( 'tarifa_preimpresion_id' ).update( preimpresionesList );
|
||||
|
||||
editor4.on( 'preSubmit', function ( e, d, type ) {
|
||||
if ( type === 'create'){
|
||||
d.data[0]['presupuesto_id'] = id;
|
||||
}
|
||||
else if(type === 'edit' ) {
|
||||
for (v in d.data){
|
||||
d.data[v]['presupuesto_id'] = id;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editor4.on( 'postSubmit', function ( e, json, data, action ) {
|
||||
yeniden(json.<?= csrf_token() ?>);
|
||||
});
|
||||
|
||||
editor4.on( 'submitSuccess', function ( e, json, data, action ) {
|
||||
theTable4.clearPipeline();
|
||||
theTable4.draw();
|
||||
});
|
||||
|
||||
// Activate an inline edit on click of a table cell
|
||||
$('#tableOfServiciosPreimpresion').on( 'click', 'tbody span.edit', function (e) {
|
||||
editor4.inline(
|
||||
theTable4.cells(this.parentNode.parentNode, '*').nodes(),
|
||||
{
|
||||
cancelHtml: '<a href="javascript:void(0);"><i class="ti ti-x"></i></a>',
|
||||
cancelTrigger: 'span.cancel',
|
||||
submitHtml: '<a href="javascript:void(0);"><i class="ti ti-device-floppy"></i></a>',
|
||||
submitTrigger: 'span.edit',
|
||||
submit: 'allIfChanged'
|
||||
}
|
||||
);
|
||||
} );
|
||||
|
||||
|
||||
// Delete row
|
||||
|
||||
|
||||
var theTable4 = $('#tableOfServiciosPreimpresion').DataTable( {
|
||||
draw: 4,
|
||||
serverSide: false,
|
||||
processing: true,
|
||||
autoWidth: true,
|
||||
responsive: true,
|
||||
lengthMenu: [ 5, 10, 25],
|
||||
order: [[ 0, "asc" ], [ 1, "asc" ]],
|
||||
pageLength: 10,
|
||||
lengthChange: true,
|
||||
var tableServiciosPreimpresion = new DataTable('#tableOfServiciosPreimpresion',{
|
||||
scrollX: true,
|
||||
searching: false,
|
||||
paging: true,
|
||||
paging: false,
|
||||
info: false,
|
||||
dom: '<"mt-4"><"float-start"l><t><"mt-4 mb-3"p>',
|
||||
ajax : $.fn.dataTable.pipeline( {
|
||||
url: '<?= route_to('dataTableOfPresupuestoPreimpresiones') ?>',
|
||||
data: {
|
||||
id_presupuesto: id,
|
||||
},
|
||||
method: 'POST',
|
||||
headers: {'X-Requested-With': 'XMLHttpRequest'},
|
||||
async: true,
|
||||
}),
|
||||
columns: [
|
||||
{'data': 'tarifa_preimpresion_id',
|
||||
render: function(data, type, row, meta) {
|
||||
var value = preimpresionesList.find(element => element.value === data);
|
||||
return value['label'];
|
||||
},
|
||||
},
|
||||
{ 'data': 'precio_unidad' },
|
||||
{ 'data': 'precio_total' },
|
||||
{
|
||||
data: actionBtns,
|
||||
className: 'row-edit dt-center'
|
||||
}
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
targets: [lastColNr4]
|
||||
},
|
||||
{
|
||||
"orderData": [ 0, 1 ],
|
||||
"targets": 0
|
||||
},
|
||||
|
||||
],
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
select: false,
|
||||
language: {
|
||||
url: "//cdn.datatables.net/plug-ins/1.13.4/i18n/<?= config('Basics')->i18n ?>.json"
|
||||
},
|
||||
buttons: [ {
|
||||
className: 'btn btn-primary float-end me-sm-3 me-1',
|
||||
extend: "createInline",
|
||||
editor: editor4,
|
||||
formOptions: {
|
||||
submitTrigger: -1,
|
||||
submitHtml: '<i class="ti ti-device-floppy"/>'
|
||||
|
||||
});
|
||||
|
||||
function init_servicio_preimpresion(){
|
||||
const serviciospreimpresionList = <?php echo json_encode($serviciosPreimpresionList); ?>;
|
||||
|
||||
$('#add_servicio_preimpresion_list').select2({
|
||||
allowClear: false,
|
||||
minimumResultsForSearch: -1,
|
||||
placeholder: '<?= lang("Presupuestos.servicioPreimpresionList") ?>'
|
||||
})
|
||||
|
||||
serviciospreimpresionList.forEach((element) =>{
|
||||
|
||||
tableServiciosPreimpresion.row.add([
|
||||
element.tarifa_preimpresion_id,
|
||||
element.nombre,
|
||||
'<input id="precio_' + element.tarifa_preimpresion_id +'" value="' + parseFloat(element.precio).toFixed(2) + '"></input>',
|
||||
'<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-serv mx-2" data-id="' + element.tarifa_preimpresion_id +'"></i></a>'
|
||||
]).draw(false)
|
||||
|
||||
})
|
||||
check_serv_preimpresion_error()
|
||||
}
|
||||
|
||||
function check_serv_preimpresion_error(){
|
||||
|
||||
var htmlString = '';
|
||||
|
||||
$('#tableOfServiciosPreimpresion tr').each(function(){
|
||||
|
||||
if(parseFloat($(this).find('td:eq(2) input').val()) == '0'){
|
||||
htmlString = `
|
||||
<div class="alert alert-danger d-flex align-items-baseline" role="alert">
|
||||
<span class="alert-icon alert-icon-lg text-primary me-2">
|
||||
<i class="ti ti-ban ti-sm"></i>
|
||||
</span>
|
||||
<div class="d-flex flex-column ps-1">
|
||||
<h5 class="alert-heading mb-2"><?= lang("Presupuestos.errores.error_servicios_anadidos") ?></h5>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
} ]
|
||||
} );
|
||||
*/
|
||||
})
|
||||
$('#serv-preimpresion-error').html(htmlString)
|
||||
}
|
||||
|
||||
function get_tarifas_preimpresion(tarifa_id = -1){
|
||||
|
||||
var datos = {
|
||||
tarifa_preimpresion_id : tarifa_id,
|
||||
<?= csrf_token() ?? "token" ?> : <?= csrf_token() ?>v
|
||||
};
|
||||
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '<?=route_to('dataTableOfPresupuestoPreimpresiones') ?>',
|
||||
data: datos,
|
||||
success: function (data) {
|
||||
|
||||
data.values.forEach((row) => {
|
||||
|
||||
tableServiciosPreimpresion.row.add([
|
||||
row.tarifa_id,
|
||||
row.tarifa_nombre,
|
||||
'<input id="precio_' + row.tarifa_id +'" value="' + parseFloat(row.precio).toFixed(2) + '"></input>',
|
||||
'<a href="javascript:void(0);"><i class="ti ti-trash ti-sm btn-delete-serv mx-2" data-id="' + row.tarifa_id +'"></i></a>'
|
||||
]).draw(false)
|
||||
});
|
||||
|
||||
check_serv_preimpresion_error()
|
||||
yeniden(data.<?= csrf_token() ?>);
|
||||
return true;
|
||||
},
|
||||
error: function(e){
|
||||
return false;
|
||||
}
|
||||
})
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#insertar_serv_preimpresion').on('click', function(){
|
||||
const tarifa_text = $('#add_servicio_preimpresion_list').select2('data')[0].text.trim()
|
||||
|
||||
if( $('#add_servicio_preimpresion_list').select2('data')[0].text.trim().length > 0){
|
||||
if($('#tableOfServiciosPreimpresion tr > td:contains(' + tarifa_text + ')').length == 0)
|
||||
get_tarifas_preimpresion($('#add_servicio_preimpresion_list').select2('data')[0].id);
|
||||
else{
|
||||
popErrorAlert("Ese servicio ya existe", 'serv-preimpresion-alert')
|
||||
}
|
||||
}
|
||||
check_serv_preimpresion_error()
|
||||
})
|
||||
|
||||
function get_datos_preimpresion(){
|
||||
|
||||
var datosPreimpresion = []
|
||||
$("#tableOfServiciosPreimpresion tr").each(function (index,tr) {
|
||||
var values = {}
|
||||
$(this).find("td").each(function (index2) {
|
||||
|
||||
switch (index2) {
|
||||
case 0:
|
||||
values['tarifa_id'] = $(this).text()
|
||||
break
|
||||
case 2:
|
||||
values['precio_total'] = $(this).children(":first").val()
|
||||
break
|
||||
}
|
||||
})
|
||||
if(Object.keys(values).length>0)
|
||||
datosPreimpresion.push(values)
|
||||
})
|
||||
|
||||
return datosPreimpresion
|
||||
}
|
||||
|
||||
init_servicio_preimpresion()
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
@ -21,13 +21,13 @@
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id="precio_pagina"
|
||||
name="precio_pagina"
|
||||
id="precio"
|
||||
name="precio"
|
||||
required
|
||||
maxLength="31"
|
||||
step="0.01"
|
||||
class="form-control"
|
||||
value="<?= old('precio', $tarifapreimpresionEntity->precio_pagina) ?>"
|
||||
value="<?= old('precio', $tarifapreimpresionEntity->precio) ?>"
|
||||
>
|
||||
</div><!--//.mb-3 -->
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<?= empty($item->nombre) || strlen($item->nombre) < 51 ? esc($item->nombre) : character_limiter(esc($item->nombre), 50) ?>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<?= esc($item->precio_pagina) ?>
|
||||
<?= esc($item->precio) ?>
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<?= esc($item->precio_min) ?>
|
||||
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 179 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 38 KiB |
@ -1,195 +0,0 @@
|
||||
/**
|
||||
* App user list (jquery)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
$(function () {
|
||||
var dataTablePermissions = $('.datatables-permissions'),
|
||||
dt_permission,
|
||||
userList = 'app-user-list.html';
|
||||
|
||||
// Users List datatable
|
||||
if (dataTablePermissions.length) {
|
||||
dt_permission = dataTablePermissions.DataTable({
|
||||
ajax: assetsPath + 'json/permissions-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'id' },
|
||||
{ data: 'name' },
|
||||
{ data: 'assigned_to' },
|
||||
{ data: 'created_date' },
|
||||
{ data: '' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: 1,
|
||||
searchable: false,
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
// Name
|
||||
targets: 2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $name = full['name'];
|
||||
return '<span class="text-nowrap">' + $name + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Role
|
||||
targets: 3,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
var $assignedTo = full['assigned_to'],
|
||||
$output = '';
|
||||
var roleBadgeObj = {
|
||||
Admin: '<a href="' + userList + '"><span class="badge bg-label-primary m-1">Administrator</span></a>',
|
||||
Manager: '<a href="' + userList + '"><span class="badge bg-label-warning m-1">Manager</span></a>',
|
||||
Users: '<a href="' + userList + '"><span class="badge bg-label-success m-1">Users</span></a>',
|
||||
Support: '<a href="' + userList + '"><span class="badge bg-label-info m-1">Support</span></a>',
|
||||
Restricted:
|
||||
'<a href="' + userList + '"><span class="badge bg-label-danger m-1">Restricted User</span></a>'
|
||||
};
|
||||
for (var i = 0; i < $assignedTo.length; i++) {
|
||||
var val = $assignedTo[i];
|
||||
$output += roleBadgeObj[val];
|
||||
}
|
||||
return '<span class="text-nowrap">' + $output + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// remove ordering from Name
|
||||
targets: 4,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
var $date = full['created_date'];
|
||||
return '<span class="text-nowrap">' + $date + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
searchable: false,
|
||||
title: 'Actions',
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<span class="text-nowrap"><button class="btn btn-sm btn-icon me-2" data-bs-target="#editPermissionModal" data-bs-toggle="modal" data-bs-dismiss="modal"><i class="ti ti-edit"></i></button>' +
|
||||
'<button class="btn btn-sm btn-icon delete-record"><i class="ti ti-trash"></i></button></span>'
|
||||
);
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[1, 'asc']],
|
||||
dom:
|
||||
'<"row mx-1"' +
|
||||
'<"col-sm-12 col-md-3" l>' +
|
||||
'<"col-sm-12 col-md-9"<"dt-action-buttons text-xl-end text-lg-start text-md-end text-start d-flex align-items-center justify-content-md-end justify-content-center flex-wrap me-1"<"me-3"f>B>>' +
|
||||
'>t' +
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
language: {
|
||||
sLengthMenu: 'Show _MENU_',
|
||||
search: 'Search',
|
||||
searchPlaceholder: 'Search..'
|
||||
},
|
||||
// Buttons with Dropdown
|
||||
buttons: [
|
||||
{
|
||||
text: 'Add Permission',
|
||||
className: 'add-new btn btn-primary mb-3 mb-md-0',
|
||||
attr: {
|
||||
'data-bs-toggle': 'modal',
|
||||
'data-bs-target': '#addPermissionModal'
|
||||
},
|
||||
init: function (api, node, config) {
|
||||
$(node).removeClass('btn-secondary');
|
||||
}
|
||||
}
|
||||
],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
// Adding role filter once table initialized
|
||||
this.api()
|
||||
.columns(3)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="UserRole" class="form-select text-capitalize"><option value=""> Select Role </option></select>'
|
||||
)
|
||||
.appendTo('.user_role')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '" class="text-capitalize">' + d + '</option>');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Delete Record
|
||||
$('.datatables-permissions tbody').on('click', '.delete-record', function () {
|
||||
dt_permission.row($(this).parents('tr')).remove().draw();
|
||||
});
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
});
|
||||
@ -1,258 +0,0 @@
|
||||
/**
|
||||
* App user list
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// Datatable (jquery)
|
||||
$(function () {
|
||||
var dtUserTable = $('.datatables-users'),
|
||||
statusObj = {
|
||||
1: { title: 'Pending', class: 'bg-label-warning' },
|
||||
2: { title: 'Active', class: 'bg-label-success' },
|
||||
3: { title: 'Inactive', class: 'bg-label-secondary' }
|
||||
};
|
||||
|
||||
var userView = 'app-user-view-account.html';
|
||||
|
||||
// Users List datatable
|
||||
if (dtUserTable.length) {
|
||||
var dtUser = dtUserTable.DataTable({
|
||||
ajax: assetsPath + 'json/user-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'full_name' },
|
||||
{ data: 'role' },
|
||||
{ data: 'current_plan' },
|
||||
{ data: 'billing' },
|
||||
{ data: 'status' },
|
||||
{ data: '' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User full name and email
|
||||
targets: 1,
|
||||
responsivePriority: 4,
|
||||
render: function (data, type, full, meta) {
|
||||
var $name = full['full_name'],
|
||||
$email = full['email'],
|
||||
$image = full['avatar'];
|
||||
if ($image) {
|
||||
// For Avatar image
|
||||
var $output =
|
||||
'<img src="' + assetsPath + 'img/avatars/' + $image + '" alt="Avatar" class="rounded-circle">';
|
||||
} else {
|
||||
// For Avatar badge
|
||||
var stateNum = Math.floor(Math.random() * 6);
|
||||
var states = ['success', 'danger', 'warning', 'info', 'primary', 'secondary'];
|
||||
var $state = states[stateNum],
|
||||
$name = full['full_name'],
|
||||
$initials = $name.match(/\b\w/g) || [];
|
||||
$initials = (($initials.shift() || '') + ($initials.pop() || '')).toUpperCase();
|
||||
$output = '<span class="avatar-initial rounded-circle bg-label-' + $state + '">' + $initials + '</span>';
|
||||
}
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<div class="d-flex justify-content-left align-items-center">' +
|
||||
'<div class="avatar-wrapper">' +
|
||||
'<div class="avatar avatar-sm me-3">' +
|
||||
$output +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="d-flex flex-column">' +
|
||||
'<a href="' +
|
||||
userView +
|
||||
'" class="text-body text-truncate"><span class="fw-semibold">' +
|
||||
$name +
|
||||
'</span></a>' +
|
||||
'<small class="text-muted">@' +
|
||||
$email +
|
||||
'</small>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Role
|
||||
targets: 2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $role = full['role'];
|
||||
var roleBadgeObj = {
|
||||
Subscriber:
|
||||
'<span class="badge badge-center rounded-pill bg-label-warning me-3 w-px-30 h-px-30"><i class="ti ti-user ti-sm"></i></span>',
|
||||
Author:
|
||||
'<span class="badge badge-center rounded-pill bg-label-success me-3 w-px-30 h-px-30"><i class="ti ti-settings ti-sm"></i></span>',
|
||||
Maintainer:
|
||||
'<span class="badge badge-center rounded-pill bg-label-primary me-3 w-px-30 h-px-30"><i class="ti ti-chart-pie-2 ti-sm"></i></span>',
|
||||
Editor:
|
||||
'<span class="badge badge-center rounded-pill bg-label-info me-3 w-px-30 h-px-30"><i class="ti ti-edit ti-sm"></i></span>',
|
||||
Admin:
|
||||
'<span class="badge badge-center rounded-pill bg-label-secondary me-3 w-px-30 h-px-30"><i class="ti ti-device-laptop ti-sm"></i></span>'
|
||||
};
|
||||
return "<span class='text-truncate d-flex align-items-center'>" + roleBadgeObj[$role] + $role + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// Plans
|
||||
targets: 3,
|
||||
render: function (data, type, full, meta) {
|
||||
var $plan = full['current_plan'];
|
||||
|
||||
return '<span class="fw-semibold">' + $plan + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Status
|
||||
targets: 5,
|
||||
render: function (data, type, full, meta) {
|
||||
var $status = full['status'];
|
||||
|
||||
return (
|
||||
'<span class="badge ' +
|
||||
statusObj[$status].class +
|
||||
'" text-capitalized>' +
|
||||
statusObj[$status].title +
|
||||
'</span>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
title: 'Actions',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<div class="d-flex align-items-center">' +
|
||||
'<a href="' +
|
||||
userView +
|
||||
'" class="btn btn-sm btn-icon"><i class="ti ti-eye"></i></a>' +
|
||||
'<a href="javascript:;" class="text-body delete-record"><i class="ti ti-trash ti-sm mx-2"></i></a>' +
|
||||
'<a href="javascript:;" class="text-body dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-sm mx-1"></i></a>' +
|
||||
'<div class="dropdown-menu dropdown-menu-end m-0">' +
|
||||
'<a href="javascript:;"" class="dropdown-item">Edit</a>' +
|
||||
'<a href="javascript:;" class="dropdown-item">Suspend</a>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
dom:
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-4 col-lg-6" l>' +
|
||||
'<"col-sm-12 col-md-8 col-lg-6"<"dt-action-buttons text-xl-end text-lg-start text-md-end text-start d-flex align-items-center justify-content-md-end justify-content-center align-items-center flex-sm-nowrap flex-wrap me-1"<"me-3"f><"user_role w-px-200 pb-3 pb-sm-0">>>' +
|
||||
'>t' +
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
language: {
|
||||
sLengthMenu: 'Show _MENU_',
|
||||
search: 'Search',
|
||||
searchPlaceholder: 'Search..'
|
||||
},
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
// Adding role filter once table initialized
|
||||
this.api()
|
||||
.columns(2)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="UserRole" class="form-select text-capitalize"><option value=""> Select Role </option></select>'
|
||||
)
|
||||
.appendTo('.user_role')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '" class="text-capitalize">' + d + '</option>');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// Delete Record
|
||||
$('.datatables-users tbody').on('click', '.delete-record', function () {
|
||||
dtUser.row($(this).parents('tr')).remove().draw();
|
||||
});
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
});
|
||||
|
||||
(function () {
|
||||
// On edit role click, update text
|
||||
var roleEditList = document.querySelectorAll('.role-edit-modal'),
|
||||
roleAdd = document.querySelector('.add-new-role'),
|
||||
roleTitle = document.querySelector('.role-title');
|
||||
|
||||
roleAdd.onclick = function () {
|
||||
roleTitle.innerHTML = 'Add New Role'; // reset text
|
||||
};
|
||||
if (roleEditList) {
|
||||
roleEditList.forEach(function (roleEditEl) {
|
||||
roleEditEl.onclick = function () {
|
||||
roleTitle.innerHTML = 'Edit Role'; // reset text
|
||||
};
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* App Calendar Events
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
let date = new Date();
|
||||
let nextDay = new Date(new Date().getTime() + 24 * 60 * 60 * 1000);
|
||||
// prettier-ignore
|
||||
let nextMonth = date.getMonth() === 11 ? new Date(date.getFullYear() + 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() + 1, 1);
|
||||
// prettier-ignore
|
||||
let prevMonth = date.getMonth() === 11 ? new Date(date.getFullYear() - 1, 0, 1) : new Date(date.getFullYear(), date.getMonth() - 1, 1);
|
||||
|
||||
let events = [
|
||||
{
|
||||
id: 1,
|
||||
url: '',
|
||||
title: 'Design Review',
|
||||
start: date,
|
||||
end: nextDay,
|
||||
allDay: false,
|
||||
extendedProps: {
|
||||
calendar: 'Business'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
url: '',
|
||||
title: 'Meeting With Client',
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -11),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -10),
|
||||
allDay: true,
|
||||
extendedProps: {
|
||||
calendar: 'Business'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
url: '',
|
||||
title: 'Family Trip',
|
||||
allDay: true,
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -9),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -7),
|
||||
extendedProps: {
|
||||
calendar: 'Holiday'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
url: '',
|
||||
title: "Doctor's Appointment",
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -11),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -10),
|
||||
extendedProps: {
|
||||
calendar: 'Personal'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
url: '',
|
||||
title: 'Dart Game?',
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
|
||||
allDay: true,
|
||||
extendedProps: {
|
||||
calendar: 'ETC'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
url: '',
|
||||
title: 'Meditation',
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
|
||||
allDay: true,
|
||||
extendedProps: {
|
||||
calendar: 'Personal'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
url: '',
|
||||
title: 'Dinner',
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
|
||||
extendedProps: {
|
||||
calendar: 'Family'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
url: '',
|
||||
title: 'Product Review',
|
||||
start: new Date(date.getFullYear(), date.getMonth() + 1, -13),
|
||||
end: new Date(date.getFullYear(), date.getMonth() + 1, -12),
|
||||
allDay: true,
|
||||
extendedProps: {
|
||||
calendar: 'Business'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
url: '',
|
||||
title: 'Monthly Meeting',
|
||||
start: nextMonth,
|
||||
end: nextMonth,
|
||||
allDay: true,
|
||||
extendedProps: {
|
||||
calendar: 'Business'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
url: '',
|
||||
title: 'Monthly Checkup',
|
||||
start: prevMonth,
|
||||
end: prevMonth,
|
||||
allDay: true,
|
||||
extendedProps: {
|
||||
calendar: 'Personal'
|
||||
}
|
||||
}
|
||||
];
|
||||
@ -1,571 +0,0 @@
|
||||
/**
|
||||
* App Calendar
|
||||
*/
|
||||
|
||||
/**
|
||||
* ! If both start and end dates are same Full calendar will nullify the end date value.
|
||||
* ! Full calendar will end the event on a day before at 12:00:00AM thus, event won't extend to the end date.
|
||||
* ! We are getting events from a separate file named app-calendar-events.js. You can add or remove events from there.
|
||||
*
|
||||
**/
|
||||
|
||||
'use strict';
|
||||
|
||||
let direction = 'ltr';
|
||||
|
||||
if (isRtl) {
|
||||
direction = 'rtl';
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
(function () {
|
||||
const calendarEl = document.getElementById('calendar'),
|
||||
appCalendarSidebar = document.querySelector('.app-calendar-sidebar'),
|
||||
addEventSidebar = document.getElementById('addEventSidebar'),
|
||||
appOverlay = document.querySelector('.app-overlay'),
|
||||
calendarsColor = {
|
||||
Business: 'primary',
|
||||
Holiday: 'success',
|
||||
Personal: 'danger',
|
||||
Family: 'warning',
|
||||
ETC: 'info'
|
||||
},
|
||||
offcanvasTitle = document.querySelector('.offcanvas-title'),
|
||||
btnToggleSidebar = document.querySelector('.btn-toggle-sidebar'),
|
||||
btnSubmit = document.querySelector('button[type="submit"]'),
|
||||
btnDeleteEvent = document.querySelector('.btn-delete-event'),
|
||||
btnCancel = document.querySelector('.btn-cancel'),
|
||||
eventTitle = document.querySelector('#eventTitle'),
|
||||
eventStartDate = document.querySelector('#eventStartDate'),
|
||||
eventEndDate = document.querySelector('#eventEndDate'),
|
||||
eventUrl = document.querySelector('#eventURL'),
|
||||
eventLabel = $('#eventLabel'), // ! Using jquery vars due to select2 jQuery dependency
|
||||
eventGuests = $('#eventGuests'), // ! Using jquery vars due to select2 jQuery dependency
|
||||
eventLocation = document.querySelector('#eventLocation'),
|
||||
eventDescription = document.querySelector('#eventDescription'),
|
||||
allDaySwitch = document.querySelector('.allDay-switch'),
|
||||
selectAll = document.querySelector('.select-all'),
|
||||
filterInput = [].slice.call(document.querySelectorAll('.input-filter')),
|
||||
inlineCalendar = document.querySelector('.inline-calendar');
|
||||
|
||||
let eventToUpdate,
|
||||
currentEvents = events, // Assign app-calendar-events.js file events (assume events from API) to currentEvents (browser store/object) to manage and update calender events
|
||||
isFormValid = false,
|
||||
inlineCalInstance;
|
||||
|
||||
// Init event Offcanvas
|
||||
const bsAddEventSidebar = new bootstrap.Offcanvas(addEventSidebar);
|
||||
|
||||
//! TODO: Update Event label and guest code to JS once select removes jQuery dependency
|
||||
// Event Label (select2)
|
||||
if (eventLabel.length) {
|
||||
function renderBadges(option) {
|
||||
if (!option.id) {
|
||||
return option.text;
|
||||
}
|
||||
var $badge =
|
||||
"<span class='badge badge-dot bg-" + $(option.element).data('label') + " me-2'> " + '</span>' + option.text;
|
||||
|
||||
return $badge;
|
||||
}
|
||||
eventLabel.wrap('<div class="position-relative"></div>').select2({
|
||||
placeholder: 'Select value',
|
||||
dropdownParent: eventLabel.parent(),
|
||||
templateResult: renderBadges,
|
||||
templateSelection: renderBadges,
|
||||
minimumResultsForSearch: -1,
|
||||
escapeMarkup: function (es) {
|
||||
return es;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Event Guests (select2)
|
||||
if (eventGuests.length) {
|
||||
function renderGuestAvatar(option) {
|
||||
if (!option.id) {
|
||||
return option.text;
|
||||
}
|
||||
var $avatar =
|
||||
"<div class='d-flex flex-wrap align-items-center'>" +
|
||||
"<div class='avatar avatar-xs me-2'>" +
|
||||
"<img src='" +
|
||||
assetsPath +
|
||||
'img/avatars/' +
|
||||
$(option.element).data('avatar') +
|
||||
"' alt='avatar' class='rounded-circle' />" +
|
||||
'</div>' +
|
||||
option.text +
|
||||
'</div>';
|
||||
|
||||
return $avatar;
|
||||
}
|
||||
eventGuests.wrap('<div class="position-relative"></div>').select2({
|
||||
placeholder: 'Select value',
|
||||
dropdownParent: eventGuests.parent(),
|
||||
closeOnSelect: false,
|
||||
templateResult: renderGuestAvatar,
|
||||
templateSelection: renderGuestAvatar,
|
||||
escapeMarkup: function (es) {
|
||||
return es;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Event start (flatpicker)
|
||||
if (eventStartDate) {
|
||||
var start = eventStartDate.flatpickr({
|
||||
enableTime: true,
|
||||
altFormat: 'Y-m-dTH:i:S',
|
||||
onReady: function (selectedDates, dateStr, instance) {
|
||||
if (instance.isMobile) {
|
||||
instance.mobileInput.setAttribute('step', null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Event end (flatpicker)
|
||||
if (eventEndDate) {
|
||||
var end = eventEndDate.flatpickr({
|
||||
enableTime: true,
|
||||
altFormat: 'Y-m-dTH:i:S',
|
||||
onReady: function (selectedDates, dateStr, instance) {
|
||||
if (instance.isMobile) {
|
||||
instance.mobileInput.setAttribute('step', null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Inline sidebar calendar (flatpicker)
|
||||
if (inlineCalendar) {
|
||||
inlineCalInstance = inlineCalendar.flatpickr({
|
||||
monthSelectorType: 'static',
|
||||
inline: true
|
||||
});
|
||||
}
|
||||
|
||||
// Event click function
|
||||
function eventClick(info) {
|
||||
eventToUpdate = info.event;
|
||||
if (eventToUpdate.url) {
|
||||
info.jsEvent.preventDefault();
|
||||
window.open(eventToUpdate.url, '_blank');
|
||||
}
|
||||
bsAddEventSidebar.show();
|
||||
// For update event set offcanvas title text: Update Event
|
||||
if (offcanvasTitle) {
|
||||
offcanvasTitle.innerHTML = 'Update Event';
|
||||
}
|
||||
btnSubmit.innerHTML = 'Update';
|
||||
btnSubmit.classList.add('btn-update-event');
|
||||
btnSubmit.classList.remove('btn-add-event');
|
||||
btnDeleteEvent.classList.remove('d-none');
|
||||
|
||||
eventTitle.value = eventToUpdate.title;
|
||||
start.setDate(eventToUpdate.start, true, 'Y-m-d');
|
||||
eventToUpdate.allDay === true ? (allDaySwitch.checked = true) : (allDaySwitch.checked = false);
|
||||
eventToUpdate.end !== null
|
||||
? end.setDate(eventToUpdate.end, true, 'Y-m-d')
|
||||
: end.setDate(eventToUpdate.start, true, 'Y-m-d');
|
||||
eventLabel.val(eventToUpdate.extendedProps.calendar).trigger('change');
|
||||
eventToUpdate.extendedProps.location !== undefined
|
||||
? (eventLocation.value = eventToUpdate.extendedProps.location)
|
||||
: null;
|
||||
eventToUpdate.extendedProps.guests !== undefined
|
||||
? eventGuests.val(eventToUpdate.extendedProps.guests).trigger('change')
|
||||
: null;
|
||||
eventToUpdate.extendedProps.description !== undefined
|
||||
? (eventDescription.value = eventToUpdate.extendedProps.description)
|
||||
: null;
|
||||
|
||||
// // Call removeEvent function
|
||||
// btnDeleteEvent.addEventListener('click', e => {
|
||||
// removeEvent(parseInt(eventToUpdate.id));
|
||||
// // eventToUpdate.remove();
|
||||
// bsAddEventSidebar.hide();
|
||||
// });
|
||||
}
|
||||
|
||||
// Modify sidebar toggler
|
||||
function modifyToggler() {
|
||||
const fcSidebarToggleButton = document.querySelector('.fc-sidebarToggle-button');
|
||||
fcSidebarToggleButton.classList.remove('fc-button-primary');
|
||||
fcSidebarToggleButton.classList.add('d-lg-none', 'd-inline-block', 'ps-0');
|
||||
while (fcSidebarToggleButton.firstChild) {
|
||||
fcSidebarToggleButton.firstChild.remove();
|
||||
}
|
||||
fcSidebarToggleButton.setAttribute('data-bs-toggle', 'sidebar');
|
||||
fcSidebarToggleButton.setAttribute('data-overlay', '');
|
||||
fcSidebarToggleButton.setAttribute('data-target', '#app-calendar-sidebar');
|
||||
fcSidebarToggleButton.insertAdjacentHTML('beforeend', '<i class="ti ti-menu-2 ti-sm"></i>');
|
||||
}
|
||||
|
||||
// Filter events by calender
|
||||
function selectedCalendars() {
|
||||
let selected = [],
|
||||
filterInputChecked = [].slice.call(document.querySelectorAll('.input-filter:checked'));
|
||||
|
||||
filterInputChecked.forEach(item => {
|
||||
selected.push(item.getAttribute('data-value'));
|
||||
});
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
// AXIOS: fetchEvents
|
||||
// * This will be called by fullCalendar to fetch events. Also this can be used to refetch events.
|
||||
// --------------------------------------------------------------------------------------------------
|
||||
function fetchEvents(info, successCallback) {
|
||||
// Fetch Events from API endpoint reference
|
||||
/* $.ajax(
|
||||
{
|
||||
url: '../../../app-assets/data/app-calendar-events.js',
|
||||
type: 'GET',
|
||||
success: function (result) {
|
||||
// Get requested calendars as Array
|
||||
var calendars = selectedCalendars();
|
||||
|
||||
return [result.events.filter(event => calendars.includes(event.extendedProps.calendar))];
|
||||
},
|
||||
error: function (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
); */
|
||||
|
||||
let calendars = selectedCalendars();
|
||||
// We are reading event object from app-calendar-events.js file directly by including that file above app-calendar file.
|
||||
// You should make an API call, look into above commented API call for reference
|
||||
let selectedEvents = currentEvents.filter(function (event) {
|
||||
// console.log(event.extendedProps.calendar.toLowerCase());
|
||||
return calendars.includes(event.extendedProps.calendar.toLowerCase());
|
||||
});
|
||||
// if (selectedEvents.length > 0) {
|
||||
successCallback(selectedEvents);
|
||||
// }
|
||||
}
|
||||
|
||||
// Init FullCalendar
|
||||
// ------------------------------------------------
|
||||
let calendar = new Calendar(calendarEl, {
|
||||
initialView: 'dayGridMonth',
|
||||
events: fetchEvents,
|
||||
plugins: [dayGridPlugin, interactionPlugin, listPlugin, timegridPlugin],
|
||||
editable: true,
|
||||
dragScroll: true,
|
||||
dayMaxEvents: 2,
|
||||
eventResizableFromStart: true,
|
||||
customButtons: {
|
||||
sidebarToggle: {
|
||||
text: 'Sidebar'
|
||||
}
|
||||
},
|
||||
headerToolbar: {
|
||||
start: 'sidebarToggle, prev,next, title',
|
||||
end: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
|
||||
},
|
||||
direction: direction,
|
||||
initialDate: new Date(),
|
||||
navLinks: true, // can click day/week names to navigate views
|
||||
eventClassNames: function ({ event: calendarEvent }) {
|
||||
const colorName = calendarsColor[calendarEvent._def.extendedProps.calendar];
|
||||
// Background Color
|
||||
return ['fc-event-' + colorName];
|
||||
},
|
||||
dateClick: function (info) {
|
||||
let date = moment(info.date).format('YYYY-MM-DD');
|
||||
resetValues();
|
||||
bsAddEventSidebar.show();
|
||||
|
||||
// For new event set offcanvas title text: Add Event
|
||||
if (offcanvasTitle) {
|
||||
offcanvasTitle.innerHTML = 'Add Event';
|
||||
}
|
||||
btnSubmit.innerHTML = 'Add';
|
||||
btnSubmit.classList.remove('btn-update-event');
|
||||
btnSubmit.classList.add('btn-add-event');
|
||||
btnDeleteEvent.classList.add('d-none');
|
||||
eventStartDate.value = date;
|
||||
eventEndDate.value = date;
|
||||
},
|
||||
eventClick: function (info) {
|
||||
eventClick(info);
|
||||
},
|
||||
datesSet: function () {
|
||||
modifyToggler();
|
||||
},
|
||||
viewDidMount: function () {
|
||||
modifyToggler();
|
||||
}
|
||||
});
|
||||
|
||||
// Render calendar
|
||||
calendar.render();
|
||||
// Modify sidebar toggler
|
||||
modifyToggler();
|
||||
|
||||
const eventForm = document.getElementById('eventForm');
|
||||
const fv = FormValidation.formValidation(eventForm, {
|
||||
fields: {
|
||||
eventTitle: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter event title '
|
||||
}
|
||||
}
|
||||
},
|
||||
eventStartDate: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter start date '
|
||||
}
|
||||
}
|
||||
},
|
||||
eventEndDate: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter end date '
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap5: new FormValidation.plugins.Bootstrap5({
|
||||
// Use this for enabling/changing valid/invalid class
|
||||
eleValidClass: '',
|
||||
rowSelector: function (field, ele) {
|
||||
// field is the field name & ele is the field element
|
||||
return '.mb-3';
|
||||
}
|
||||
}),
|
||||
submitButton: new FormValidation.plugins.SubmitButton(),
|
||||
// Submit the form when all fields are valid
|
||||
// defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
|
||||
autoFocus: new FormValidation.plugins.AutoFocus()
|
||||
}
|
||||
})
|
||||
.on('core.form.valid', function () {
|
||||
// Jump to the next step when all fields in the current step are valid
|
||||
isFormValid = true;
|
||||
})
|
||||
.on('core.form.invalid', function () {
|
||||
// if fields are invalid
|
||||
isFormValid = false;
|
||||
});
|
||||
|
||||
// Sidebar Toggle Btn
|
||||
if (btnToggleSidebar) {
|
||||
btnToggleSidebar.addEventListener('click', e => {
|
||||
btnCancel.classList.remove('d-none');
|
||||
});
|
||||
}
|
||||
|
||||
// Add Event
|
||||
// ------------------------------------------------
|
||||
function addEvent(eventData) {
|
||||
// ? Add new event data to current events object and refetch it to display on calender
|
||||
// ? You can write below code to AJAX call success response
|
||||
|
||||
currentEvents.push(eventData);
|
||||
calendar.refetchEvents();
|
||||
|
||||
// ? To add event directly to calender (won't update currentEvents object)
|
||||
// calendar.addEvent(eventData);
|
||||
}
|
||||
|
||||
// Update Event
|
||||
// ------------------------------------------------
|
||||
function updateEvent(eventData) {
|
||||
// ? Update existing event data to current events object and refetch it to display on calender
|
||||
// ? You can write below code to AJAX call success response
|
||||
eventData.id = parseInt(eventData.id);
|
||||
currentEvents[currentEvents.findIndex(el => el.id === eventData.id)] = eventData; // Update event by id
|
||||
calendar.refetchEvents();
|
||||
|
||||
// ? To update event directly to calender (won't update currentEvents object)
|
||||
// let propsToUpdate = ['id', 'title', 'url'];
|
||||
// let extendedPropsToUpdate = ['calendar', 'guests', 'location', 'description'];
|
||||
|
||||
// updateEventInCalendar(eventData, propsToUpdate, extendedPropsToUpdate);
|
||||
}
|
||||
|
||||
// Remove Event
|
||||
// ------------------------------------------------
|
||||
|
||||
function removeEvent(eventId) {
|
||||
// ? Delete existing event data to current events object and refetch it to display on calender
|
||||
// ? You can write below code to AJAX call success response
|
||||
currentEvents = currentEvents.filter(function (event) {
|
||||
return event.id != eventId;
|
||||
});
|
||||
calendar.refetchEvents();
|
||||
|
||||
// ? To delete event directly to calender (won't update currentEvents object)
|
||||
// removeEventInCalendar(eventId);
|
||||
}
|
||||
|
||||
// (Update Event In Calendar (UI Only)
|
||||
// ------------------------------------------------
|
||||
const updateEventInCalendar = (updatedEventData, propsToUpdate, extendedPropsToUpdate) => {
|
||||
const existingEvent = calendar.getEventById(updatedEventData.id);
|
||||
|
||||
// --- Set event properties except date related ----- //
|
||||
// ? Docs: https://fullcalendar.io/docs/Event-setProp
|
||||
// dateRelatedProps => ['start', 'end', 'allDay']
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (var index = 0; index < propsToUpdate.length; index++) {
|
||||
var propName = propsToUpdate[index];
|
||||
existingEvent.setProp(propName, updatedEventData[propName]);
|
||||
}
|
||||
|
||||
// --- Set date related props ----- //
|
||||
// ? Docs: https://fullcalendar.io/docs/Event-setDates
|
||||
existingEvent.setDates(updatedEventData.start, updatedEventData.end, {
|
||||
allDay: updatedEventData.allDay
|
||||
});
|
||||
|
||||
// --- Set event's extendedProps ----- //
|
||||
// ? Docs: https://fullcalendar.io/docs/Event-setExtendedProp
|
||||
// eslint-disable-next-line no-plusplus
|
||||
for (var index = 0; index < extendedPropsToUpdate.length; index++) {
|
||||
var propName = extendedPropsToUpdate[index];
|
||||
existingEvent.setExtendedProp(propName, updatedEventData.extendedProps[propName]);
|
||||
}
|
||||
};
|
||||
|
||||
// Remove Event In Calendar (UI Only)
|
||||
// ------------------------------------------------
|
||||
function removeEventInCalendar(eventId) {
|
||||
calendar.getEventById(eventId).remove();
|
||||
}
|
||||
|
||||
// Add new event
|
||||
// ------------------------------------------------
|
||||
btnSubmit.addEventListener('click', e => {
|
||||
if (btnSubmit.classList.contains('btn-add-event')) {
|
||||
if (isFormValid) {
|
||||
let newEvent = {
|
||||
id: calendar.getEvents().length + 1,
|
||||
title: eventTitle.value,
|
||||
start: eventStartDate.value,
|
||||
end: eventEndDate.value,
|
||||
startStr: eventStartDate.value,
|
||||
endStr: eventEndDate.value,
|
||||
display: 'block',
|
||||
extendedProps: {
|
||||
location: eventLocation.value,
|
||||
guests: eventGuests.val(),
|
||||
calendar: eventLabel.val(),
|
||||
description: eventDescription.value
|
||||
}
|
||||
};
|
||||
if (eventUrl.value) {
|
||||
newEvent.url = eventUrl.value;
|
||||
}
|
||||
if (allDaySwitch.checked) {
|
||||
newEvent.allDay = true;
|
||||
}
|
||||
addEvent(newEvent);
|
||||
bsAddEventSidebar.hide();
|
||||
}
|
||||
} else {
|
||||
// Update event
|
||||
// ------------------------------------------------
|
||||
if (isFormValid) {
|
||||
let eventData = {
|
||||
id: eventToUpdate.id,
|
||||
title: eventTitle.value,
|
||||
start: eventStartDate.value,
|
||||
end: eventEndDate.value,
|
||||
url: eventUrl.value,
|
||||
extendedProps: {
|
||||
location: eventLocation.value,
|
||||
guests: eventGuests.val(),
|
||||
calendar: eventLabel.val(),
|
||||
description: eventDescription.value
|
||||
},
|
||||
display: 'block',
|
||||
allDay: allDaySwitch.checked ? true : false
|
||||
};
|
||||
|
||||
updateEvent(eventData);
|
||||
bsAddEventSidebar.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Call removeEvent function
|
||||
btnDeleteEvent.addEventListener('click', e => {
|
||||
removeEvent(parseInt(eventToUpdate.id));
|
||||
// eventToUpdate.remove();
|
||||
bsAddEventSidebar.hide();
|
||||
});
|
||||
|
||||
// Reset event form inputs values
|
||||
// ------------------------------------------------
|
||||
function resetValues() {
|
||||
eventEndDate.value = '';
|
||||
eventUrl.value = '';
|
||||
eventStartDate.value = '';
|
||||
eventTitle.value = '';
|
||||
eventLocation.value = '';
|
||||
allDaySwitch.checked = false;
|
||||
eventGuests.val('').trigger('change');
|
||||
eventDescription.value = '';
|
||||
}
|
||||
|
||||
// When modal hides reset input values
|
||||
addEventSidebar.addEventListener('hidden.bs.offcanvas', function () {
|
||||
resetValues();
|
||||
});
|
||||
|
||||
// Hide left sidebar if the right sidebar is open
|
||||
btnToggleSidebar.addEventListener('click', e => {
|
||||
if (offcanvasTitle) {
|
||||
offcanvasTitle.innerHTML = 'Add Event';
|
||||
}
|
||||
btnSubmit.innerHTML = 'Add';
|
||||
btnSubmit.classList.remove('btn-update-event');
|
||||
btnSubmit.classList.add('btn-add-event');
|
||||
btnDeleteEvent.classList.add('d-none');
|
||||
appCalendarSidebar.classList.remove('show');
|
||||
appOverlay.classList.remove('show');
|
||||
});
|
||||
|
||||
// Calender filter functionality
|
||||
// ------------------------------------------------
|
||||
if (selectAll) {
|
||||
selectAll.addEventListener('click', e => {
|
||||
if (e.currentTarget.checked) {
|
||||
document.querySelectorAll('.input-filter').forEach(c => (c.checked = 1));
|
||||
} else {
|
||||
document.querySelectorAll('.input-filter').forEach(c => (c.checked = 0));
|
||||
}
|
||||
calendar.refetchEvents();
|
||||
});
|
||||
}
|
||||
|
||||
if (filterInput) {
|
||||
filterInput.forEach(item => {
|
||||
item.addEventListener('click', () => {
|
||||
document.querySelectorAll('.input-filter:checked').length < document.querySelectorAll('.input-filter').length
|
||||
? (selectAll.checked = false)
|
||||
: (selectAll.checked = true);
|
||||
calendar.refetchEvents();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Jump to date on sidebar(inline) calendar change
|
||||
inlineCalInstance.config.onChange.push(function (date) {
|
||||
calendar.changeView(calendar.view.type, moment(date[0]).format('YYYY-MM-DD'));
|
||||
modifyToggler();
|
||||
appCalendarSidebar.classList.remove('show');
|
||||
appOverlay.classList.remove('show');
|
||||
});
|
||||
})();
|
||||
});
|
||||
@ -1,208 +0,0 @@
|
||||
/**
|
||||
* App Chat
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
(function () {
|
||||
const chatContactsBody = document.querySelector('.app-chat-contacts .sidebar-body'),
|
||||
chatContactListItems = [].slice.call(
|
||||
document.querySelectorAll('.chat-contact-list-item:not(.chat-contact-list-item-title)')
|
||||
),
|
||||
chatHistoryBody = document.querySelector('.chat-history-body'),
|
||||
chatSidebarLeftBody = document.querySelector('.app-chat-sidebar-left .sidebar-body'),
|
||||
chatSidebarRightBody = document.querySelector('.app-chat-sidebar-right .sidebar-body'),
|
||||
chatUserStatus = [].slice.call(document.querySelectorAll(".form-check-input[name='chat-user-status']")),
|
||||
chatSidebarLeftUserAbout = $('.chat-sidebar-left-user-about'),
|
||||
formSendMessage = document.querySelector('.form-send-message'),
|
||||
messageInput = document.querySelector('.message-input'),
|
||||
searchInput = document.querySelector('.chat-search-input'),
|
||||
speechToText = $('.speech-to-text'), // ! jQuery dependency for speech to text
|
||||
userStatusObj = {
|
||||
active: 'avatar-online',
|
||||
offline: 'avatar-offline',
|
||||
away: 'avatar-away',
|
||||
busy: 'avatar-busy'
|
||||
};
|
||||
|
||||
// Initialize PerfectScrollbar
|
||||
// ------------------------------
|
||||
|
||||
// Chat contacts scrollbar
|
||||
if (chatContactsBody) {
|
||||
new PerfectScrollbar(chatContactsBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Chat history scrollbar
|
||||
if (chatHistoryBody) {
|
||||
new PerfectScrollbar(chatHistoryBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Sidebar left scrollbar
|
||||
if (chatSidebarLeftBody) {
|
||||
new PerfectScrollbar(chatSidebarLeftBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Sidebar right scrollbar
|
||||
if (chatSidebarRightBody) {
|
||||
new PerfectScrollbar(chatSidebarRightBody, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Scroll to bottom function
|
||||
function scrollToBottom() {
|
||||
chatHistoryBody.scrollTo(0, chatHistoryBody.scrollHeight);
|
||||
}
|
||||
scrollToBottom();
|
||||
|
||||
// User About Maxlength Init
|
||||
if (chatSidebarLeftUserAbout.length) {
|
||||
chatSidebarLeftUserAbout.maxlength({
|
||||
alwaysShow: true,
|
||||
warningClass: 'label label-success bg-success text-white',
|
||||
limitReachedClass: 'label label-danger',
|
||||
separator: '/',
|
||||
validate: true,
|
||||
threshold: 120
|
||||
});
|
||||
}
|
||||
|
||||
// Update user status
|
||||
chatUserStatus.forEach(el => {
|
||||
el.addEventListener('click', e => {
|
||||
let chatLeftSidebarUserAvatar = document.querySelector('.chat-sidebar-left-user .avatar'),
|
||||
value = e.currentTarget.value;
|
||||
//Update status in left sidebar user avatar
|
||||
chatLeftSidebarUserAvatar.removeAttribute('class');
|
||||
Helpers._addClass('avatar avatar-xl ' + userStatusObj[value] + '', chatLeftSidebarUserAvatar);
|
||||
//Update status in contacts sidebar user avatar
|
||||
let chatContactsUserAvatar = document.querySelector('.app-chat-contacts .avatar');
|
||||
chatContactsUserAvatar.removeAttribute('class');
|
||||
Helpers._addClass('flex-shrink-0 avatar ' + userStatusObj[value] + ' me-3', chatContactsUserAvatar);
|
||||
});
|
||||
});
|
||||
|
||||
// Select chat or contact
|
||||
chatContactListItems.forEach(chatContactListItem => {
|
||||
// Bind click event to each chat contact list item
|
||||
chatContactListItem.addEventListener('click', e => {
|
||||
// Remove active class from chat contact list item
|
||||
chatContactListItems.forEach(chatContactListItem => {
|
||||
chatContactListItem.classList.remove('active');
|
||||
});
|
||||
// Add active class to current chat contact list item
|
||||
e.currentTarget.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Filter Chats
|
||||
if (searchInput) {
|
||||
searchInput.addEventListener('keyup', e => {
|
||||
let searchValue = e.currentTarget.value.toLowerCase(),
|
||||
searchChatListItemsCount = 0,
|
||||
searchContactListItemsCount = 0,
|
||||
chatListItem0 = document.querySelector('.chat-list-item-0'),
|
||||
contactListItem0 = document.querySelector('.contact-list-item-0'),
|
||||
searchChatListItems = [].slice.call(
|
||||
document.querySelectorAll('#chat-list li:not(.chat-contact-list-item-title)')
|
||||
),
|
||||
searchContactListItems = [].slice.call(
|
||||
document.querySelectorAll('#contact-list li:not(.chat-contact-list-item-title)')
|
||||
);
|
||||
|
||||
// Search in chats
|
||||
searchChatContacts(searchChatListItems, searchChatListItemsCount, searchValue, chatListItem0);
|
||||
// Search in contacts
|
||||
searchChatContacts(searchContactListItems, searchContactListItemsCount, searchValue, contactListItem0);
|
||||
});
|
||||
}
|
||||
|
||||
// Search chat and contacts function
|
||||
function searchChatContacts(searchListItems, searchListItemsCount, searchValue, listItem0) {
|
||||
searchListItems.forEach(searchListItem => {
|
||||
let searchListItemText = searchListItem.textContent.toLowerCase();
|
||||
if (searchValue) {
|
||||
if (-1 < searchListItemText.indexOf(searchValue)) {
|
||||
searchListItem.classList.add('d-flex');
|
||||
searchListItem.classList.remove('d-none');
|
||||
searchListItemsCount++;
|
||||
} else {
|
||||
searchListItem.classList.add('d-none');
|
||||
}
|
||||
} else {
|
||||
searchListItem.classList.add('d-flex');
|
||||
searchListItem.classList.remove('d-none');
|
||||
searchListItemsCount++;
|
||||
}
|
||||
});
|
||||
// Display no search fount if searchListItemsCount == 0
|
||||
if (searchListItemsCount == 0) {
|
||||
listItem0.classList.remove('d-none');
|
||||
} else {
|
||||
listItem0.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
// Send Message
|
||||
formSendMessage.addEventListener('submit', e => {
|
||||
e.preventDefault();
|
||||
if (messageInput.value) {
|
||||
// Create a div and add a class
|
||||
let renderMsg = document.createElement('div');
|
||||
renderMsg.className = 'chat-message-text mt-2';
|
||||
renderMsg.innerHTML = '<p class="mb-0">' + messageInput.value + '</p>';
|
||||
document.querySelector('li:last-child .chat-message-wrapper').appendChild(renderMsg);
|
||||
messageInput.value = '';
|
||||
scrollToBottom();
|
||||
}
|
||||
});
|
||||
|
||||
// on click of chatHistoryHeaderMenu, Remove data-overlay attribute from chatSidebarLeftClose to resolve overlay overlapping issue for two sidebar
|
||||
let chatHistoryHeaderMenu = document.querySelector(".chat-history-header [data-target='#app-chat-contacts']"),
|
||||
chatSidebarLeftClose = document.querySelector('.app-chat-sidebar-left .close-sidebar');
|
||||
chatHistoryHeaderMenu.addEventListener('click', e => {
|
||||
chatSidebarLeftClose.removeAttribute('data-overlay');
|
||||
});
|
||||
// }
|
||||
|
||||
// Speech To Text
|
||||
if (speechToText.length) {
|
||||
var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition;
|
||||
if (SpeechRecognition !== undefined && SpeechRecognition !== null) {
|
||||
var recognition = new SpeechRecognition(),
|
||||
listening = false;
|
||||
speechToText.on('click', function () {
|
||||
const $this = $(this);
|
||||
recognition.onspeechstart = function () {
|
||||
listening = true;
|
||||
};
|
||||
if (listening === false) {
|
||||
recognition.start();
|
||||
}
|
||||
recognition.onerror = function (event) {
|
||||
listening = false;
|
||||
};
|
||||
recognition.onresult = function (event) {
|
||||
$this.closest('.form-send-message').find('.message-input').val(event.results[0][0].transcript);
|
||||
};
|
||||
recognition.onspeechend = function (event) {
|
||||
listening = false;
|
||||
recognition.stop();
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
})();
|
||||
});
|
||||
@ -1,380 +0,0 @@
|
||||
/**
|
||||
* App Email
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
(function () {
|
||||
const emailList = document.querySelector('.email-list'),
|
||||
emailListItems = [].slice.call(document.querySelectorAll('.email-list-item')),
|
||||
emailListItemInputs = [].slice.call(document.querySelectorAll('.email-list-item-input')),
|
||||
emailView = document.querySelector('.app-email-view-content'),
|
||||
emailFilters = document.querySelector('.email-filters'),
|
||||
emailFilterByFolders = [].slice.call(document.querySelectorAll('.email-filter-folders li')),
|
||||
emailEditor = document.querySelector('.email-editor'),
|
||||
appEmailSidebar = document.querySelector('.app-email-sidebar'),
|
||||
appOverlay = document.querySelector('.app-overlay'),
|
||||
emailReplyEditor = document.querySelector('.email-reply-editor'),
|
||||
bookmarkEmail = [].slice.call(document.querySelectorAll('.email-list-item-bookmark')),
|
||||
selectAllEmails = document.getElementById('email-select-all'),
|
||||
emailSearch = document.querySelector('.email-search-input'),
|
||||
toggleCC = document.querySelector('.email-compose-toggle-cc'),
|
||||
toggleBCC = document.querySelector('.email-compose-toggle-bcc'),
|
||||
emailCompose = document.querySelector('.app-email-compose'),
|
||||
emailListDelete = document.querySelector('.email-list-delete'),
|
||||
emailListRead = document.querySelector('.email-list-read'),
|
||||
refreshEmails = document.querySelector('.email-refresh'),
|
||||
emailViewContainer = document.getElementById('app-email-view'),
|
||||
emailFilterFolderLists = [].slice.call(document.querySelectorAll('.email-filter-folders li')),
|
||||
emailListItemActions = [].slice.call(document.querySelectorAll('.email-list-item-actions li'));
|
||||
|
||||
// Initialize PerfectScrollbar
|
||||
// ------------------------------
|
||||
// Email list scrollbar
|
||||
if (emailList) {
|
||||
let emailListInstance = new PerfectScrollbar(emailList, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Sidebar tags scrollbar
|
||||
if (emailFilters) {
|
||||
new PerfectScrollbar(emailFilters, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Email view scrollbar
|
||||
if (emailView) {
|
||||
new PerfectScrollbar(emailView, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
}
|
||||
|
||||
// Initialize Quill Editor
|
||||
// ------------------------------
|
||||
if (emailEditor) {
|
||||
new Quill('.email-editor', {
|
||||
modules: {
|
||||
toolbar: '.email-editor-toolbar'
|
||||
},
|
||||
placeholder: 'Write your message... ',
|
||||
theme: 'snow'
|
||||
});
|
||||
}
|
||||
|
||||
if (emailReplyEditor) {
|
||||
new Quill('.email-reply-editor', {
|
||||
modules: {
|
||||
toolbar: '.email-reply-toolbar'
|
||||
},
|
||||
placeholder: 'Write your message... ',
|
||||
theme: 'snow'
|
||||
});
|
||||
}
|
||||
|
||||
// Bookmark email
|
||||
if (bookmarkEmail) {
|
||||
bookmarkEmail.forEach(emailItem => {
|
||||
emailItem.addEventListener('click', e => {
|
||||
let emailItem = e.currentTarget.parentNode.parentNode;
|
||||
let starredAttr = emailItem.getAttribute('data-starred');
|
||||
e.stopPropagation();
|
||||
if (!starredAttr) {
|
||||
emailItem.setAttribute('data-starred', 'true');
|
||||
} else {
|
||||
emailItem.removeAttribute('data-starred');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Select all
|
||||
if (selectAllEmails) {
|
||||
selectAllEmails.addEventListener('click', e => {
|
||||
if (e.currentTarget.checked) {
|
||||
emailListItemInputs.forEach(c => (c.checked = 1));
|
||||
} else {
|
||||
emailListItemInputs.forEach(c => (c.checked = 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Select single email
|
||||
if (emailListItemInputs) {
|
||||
emailListItemInputs.forEach(emailListItemInput => {
|
||||
emailListItemInput.addEventListener('click', e => {
|
||||
e.stopPropagation();
|
||||
// Check input count to reset the indeterminate state
|
||||
let emailListItemInputCount = 0;
|
||||
emailListItemInputs.forEach(emailListItemInput => {
|
||||
if (emailListItemInput.checked) {
|
||||
emailListItemInputCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if (emailListItemInputCount < emailListItemInputs.length) {
|
||||
if (emailListItemInputCount == 0) {
|
||||
selectAllEmails.indeterminate = false;
|
||||
} else {
|
||||
selectAllEmails.indeterminate = true;
|
||||
}
|
||||
} else {
|
||||
if (emailListItemInputCount == emailListItemInputs.length) {
|
||||
selectAllEmails.indeterminate = false;
|
||||
selectAllEmails.checked = true;
|
||||
} else {
|
||||
selectAllEmails.indeterminate = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Search email based on searched text
|
||||
if (emailSearch) {
|
||||
emailSearch.addEventListener('keyup', e => {
|
||||
let searchValue = e.currentTarget.value.toLowerCase(),
|
||||
searchEmailListItems = {},
|
||||
selectedFolderFilter = document.querySelector('.email-filter-folders .active').getAttribute('data-target');
|
||||
|
||||
// Filter emails based on selected folders
|
||||
if (selectedFolderFilter != 'inbox') {
|
||||
searchEmailListItems = [].slice.call(
|
||||
document.querySelectorAll('.email-list-item[data-' + selectedFolderFilter + '="true"]')
|
||||
);
|
||||
} else {
|
||||
searchEmailListItems = [].slice.call(document.querySelectorAll('.email-list-item'));
|
||||
}
|
||||
|
||||
// console.log(searchValue);
|
||||
searchEmailListItems.forEach(searchEmailListItem => {
|
||||
let searchEmailListItemText = searchEmailListItem.textContent.toLowerCase();
|
||||
if (searchValue) {
|
||||
if (-1 < searchEmailListItemText.indexOf(searchValue)) {
|
||||
searchEmailListItem.classList.add('d-block');
|
||||
} else {
|
||||
searchEmailListItem.classList.add('d-none');
|
||||
}
|
||||
} else {
|
||||
searchEmailListItem.classList.remove('d-none');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Filter based on folder type (Inbox, Sent, Draft etc...)
|
||||
emailFilterByFolders.forEach(emailFilterByFolder => {
|
||||
emailFilterByFolder.addEventListener('click', e => {
|
||||
let currentTarget = e.currentTarget,
|
||||
currentTargetData = currentTarget.getAttribute('data-target');
|
||||
|
||||
appEmailSidebar.classList.remove('show');
|
||||
appOverlay.classList.remove('show');
|
||||
|
||||
// Remove active class from each folder filters
|
||||
Helpers._removeClass('active', emailFilterByFolders);
|
||||
// Add active class to selected folder filters
|
||||
currentTarget.classList.add('active');
|
||||
emailListItems.forEach(emailListItem => {
|
||||
// If folder filter is Inbox
|
||||
if (currentTargetData == 'inbox') {
|
||||
emailListItem.classList.add('d-block');
|
||||
emailListItem.classList.remove('d-none');
|
||||
} else if (emailListItem.hasAttribute('data-' + currentTargetData)) {
|
||||
emailListItem.classList.add('d-block');
|
||||
emailListItem.classList.remove('d-none');
|
||||
} else {
|
||||
emailListItem.classList.add('d-none');
|
||||
emailListItem.classList.remove('d-block');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Toggle CC/BCC input
|
||||
if (toggleBCC) {
|
||||
toggleBCC.addEventListener('click', e => {
|
||||
Helpers._toggleClass(document.querySelector('.email-compose-bcc'), 'd-block', 'd-none');
|
||||
});
|
||||
}
|
||||
|
||||
if (toggleCC) {
|
||||
toggleCC.addEventListener('click', e => {
|
||||
Helpers._toggleClass(document.querySelector('.email-compose-cc'), 'd-block', 'd-none');
|
||||
});
|
||||
}
|
||||
|
||||
// Empty compose email message inputs when modal is hidden
|
||||
emailCompose.addEventListener('hidden.bs.modal', event => {
|
||||
document.querySelector('.email-editor .ql-editor').innerHTML = '';
|
||||
$('#emailContacts').val('');
|
||||
initSelect2();
|
||||
});
|
||||
|
||||
// Delete multiple email
|
||||
if (emailListDelete) {
|
||||
emailListDelete.addEventListener('click', e => {
|
||||
emailListItemInputs.forEach(emailListItemInput => {
|
||||
if (emailListItemInput.checked) {
|
||||
emailListItemInput.parentNode.closest('li.email-list-item').remove();
|
||||
}
|
||||
});
|
||||
selectAllEmails.indeterminate = false;
|
||||
selectAllEmails.checked = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Mark as read
|
||||
if (emailListRead) {
|
||||
emailListRead.addEventListener('click', e => {
|
||||
emailListItemInputs.forEach(emailListItemInput => {
|
||||
if (emailListItemInput.checked) {
|
||||
emailListItemInput.checked = false;
|
||||
emailListItemInput.parentNode.closest('li.email-list-item').classList.add('email-marked-read');
|
||||
let emailItemEnvelop = emailListItemInput.parentNode
|
||||
.closest('li.email-list-item')
|
||||
.querySelector('.email-list-item-actions li');
|
||||
|
||||
if (Helpers._hasClass('email-read', emailItemEnvelop)) {
|
||||
emailItemEnvelop.classList.remove('email-read');
|
||||
emailItemEnvelop.classList.add('email-unread');
|
||||
emailItemEnvelop.querySelector('i').classList.remove('ti-mail-opened');
|
||||
emailItemEnvelop.querySelector('i').classList.add('ti-mail');
|
||||
}
|
||||
}
|
||||
});
|
||||
selectAllEmails.indeterminate = false;
|
||||
selectAllEmails.checked = false;
|
||||
});
|
||||
}
|
||||
|
||||
// Refresh Mails
|
||||
|
||||
if (refreshEmails && emailList) {
|
||||
let emailListJq = $('.email-list'),
|
||||
emailListInstance = new PerfectScrollbar(emailList, {
|
||||
wheelPropagation: false,
|
||||
suppressScrollX: true
|
||||
});
|
||||
// ? Using jquery vars due to BlockUI jQuery dependency
|
||||
refreshEmails.addEventListener('click', e => {
|
||||
emailListJq.block({
|
||||
message: '<div class="spinner-border text-primary" role="status"></div>',
|
||||
timeout: 1000,
|
||||
css: {
|
||||
backgroundColor: 'transparent',
|
||||
border: '0'
|
||||
},
|
||||
overlayCSS: {
|
||||
backgroundColor: '#000',
|
||||
opacity: 0.1
|
||||
},
|
||||
onBlock: function () {
|
||||
emailListInstance.settings.suppressScrollY = true;
|
||||
},
|
||||
onUnblock: function () {
|
||||
emailListInstance.settings.suppressScrollY = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Earlier msgs
|
||||
// ? Using jquery vars due to jQuery animation (slideToggle) dependency
|
||||
let earlierMsg = $('.email-earlier-msgs');
|
||||
if (earlierMsg.length) {
|
||||
earlierMsg.on('click', function () {
|
||||
let $this = $(this);
|
||||
$this.parents().find('.email-card-last').addClass('hide-pseudo');
|
||||
$this.next('.email-card-prev').slideToggle();
|
||||
$this.remove();
|
||||
});
|
||||
}
|
||||
|
||||
// Email contacts (select2)
|
||||
// ? Using jquery vars due to select2 jQuery dependency
|
||||
let emailContacts = $('#emailContacts');
|
||||
function initSelect2() {
|
||||
if (emailContacts.length) {
|
||||
function renderContactsAvatar(option) {
|
||||
if (!option.id) {
|
||||
return option.text;
|
||||
}
|
||||
let $avatar =
|
||||
"<div class='d-flex flex-wrap align-items-center'>" +
|
||||
"<div class='avatar avatar-xs me-2'>" +
|
||||
"<img src='" +
|
||||
assetsPath +
|
||||
'img/avatars/' +
|
||||
$(option.element).data('avatar') +
|
||||
"' alt='avatar' class='rounded-circle' />" +
|
||||
'</div>' +
|
||||
option.text +
|
||||
'</div>';
|
||||
|
||||
return $avatar;
|
||||
}
|
||||
emailContacts.wrap('<div class="position-relative"></div>').select2({
|
||||
placeholder: 'Select value',
|
||||
dropdownParent: emailContacts.parent(),
|
||||
closeOnSelect: false,
|
||||
templateResult: renderContactsAvatar,
|
||||
templateSelection: renderContactsAvatar,
|
||||
escapeMarkup: function (es) {
|
||||
return es;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
initSelect2();
|
||||
|
||||
// Scroll to bottom on reply click
|
||||
// ? Using jquery vars due to jQuery animation dependency
|
||||
let emailViewContent = $('.app-email-view-content');
|
||||
emailViewContent.find('.scroll-to-reply').on('click', function () {
|
||||
if (emailViewContent[0].scrollTop === 0) {
|
||||
emailViewContent.animate(
|
||||
{
|
||||
scrollTop: emailViewContent[0].scrollHeight
|
||||
},
|
||||
1500
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Close view on email filter folder list click
|
||||
if (emailFilterFolderLists) {
|
||||
emailFilterFolderLists.forEach(emailFilterFolderList => {
|
||||
emailFilterFolderList.addEventListener('click', e => {
|
||||
emailViewContainer.classList.remove('show');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Email List Items Actions
|
||||
if (emailListItemActions) {
|
||||
emailListItemActions.forEach(emailListItemAction => {
|
||||
emailListItemAction.addEventListener('click', e => {
|
||||
e.stopPropagation();
|
||||
let currentTarget = e.currentTarget;
|
||||
if (Helpers._hasClass('email-delete', currentTarget)) {
|
||||
currentTarget.parentNode.closest('li.email-list-item').remove();
|
||||
} else if (Helpers._hasClass('email-read', currentTarget)) {
|
||||
currentTarget.parentNode.closest('li.email-list-item').classList.add('email-marked-read');
|
||||
Helpers._toggleClass(currentTarget, 'email-read', 'email-unread');
|
||||
Helpers._toggleClass(currentTarget.querySelector('i'), 'ti-mail-opened', 'ti-mail');
|
||||
} else if (Helpers._hasClass('email-unread', currentTarget)) {
|
||||
currentTarget.parentNode.closest('li.email-list-item').classList.remove('email-marked-read');
|
||||
Helpers._toggleClass(currentTarget, 'email-read', 'email-unread');
|
||||
Helpers._toggleClass(currentTarget.querySelector('i'), 'ti-mail-opened', 'ti-mail');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
});
|
||||
@ -1,127 +0,0 @@
|
||||
/**
|
||||
* App Invoice - Add
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
const invoiceItemPriceList = document.querySelectorAll('.invoice-item-price'),
|
||||
invoiceItemQtyList = document.querySelectorAll('.invoice-item-qty'),
|
||||
invoiceDateList = document.querySelectorAll('.date-picker');
|
||||
|
||||
// Price
|
||||
if (invoiceItemPriceList) {
|
||||
invoiceItemPriceList.forEach(function (invoiceItemPrice) {
|
||||
new Cleave(invoiceItemPrice, {
|
||||
delimiter: '',
|
||||
numeral: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Qty
|
||||
if (invoiceItemQtyList) {
|
||||
invoiceItemQtyList.forEach(function (invoiceItemQty) {
|
||||
new Cleave(invoiceItemQty, {
|
||||
delimiter: '',
|
||||
numeral: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Datepicker
|
||||
if (invoiceDateList) {
|
||||
invoiceDateList.forEach(function (invoiceDateEl) {
|
||||
invoiceDateEl.flatpickr({
|
||||
monthSelectorType: 'static'
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// repeater (jquery)
|
||||
$(function () {
|
||||
var applyChangesBtn = $('.btn-apply-changes'),
|
||||
discount,
|
||||
tax1,
|
||||
tax2,
|
||||
discountInput,
|
||||
tax1Input,
|
||||
tax2Input,
|
||||
sourceItem = $('.source-item'),
|
||||
adminDetails = {
|
||||
'App Design': 'Designed UI kit & app pages.',
|
||||
'App Customization': 'Customization & Bug Fixes.',
|
||||
'ABC Template': 'Bootstrap 4 admin template.',
|
||||
'App Development': 'Native App Development.'
|
||||
};
|
||||
|
||||
// Prevent dropdown from closing on tax change
|
||||
$(document).on('click', '.tax-select', function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
// On tax change update it's value value
|
||||
function updateValue(listener, el) {
|
||||
listener.closest('.repeater-wrapper').find(el).text(listener.val());
|
||||
}
|
||||
|
||||
// Apply item changes btn
|
||||
if (applyChangesBtn.length) {
|
||||
$(document).on('click', '.btn-apply-changes', function (e) {
|
||||
var $this = $(this);
|
||||
tax1Input = $this.closest('.dropdown-menu').find('#taxInput1');
|
||||
tax2Input = $this.closest('.dropdown-menu').find('#taxInput2');
|
||||
discountInput = $this.closest('.dropdown-menu').find('#discountInput');
|
||||
tax1 = $this.closest('.repeater-wrapper').find('.tax-1');
|
||||
tax2 = $this.closest('.repeater-wrapper').find('.tax-2');
|
||||
discount = $('.discount');
|
||||
|
||||
if (tax1Input.val() !== null) {
|
||||
updateValue(tax1Input, tax1);
|
||||
}
|
||||
|
||||
if (tax2Input.val() !== null) {
|
||||
updateValue(tax2Input, tax2);
|
||||
}
|
||||
|
||||
if (discountInput.val().length) {
|
||||
$this
|
||||
.closest('.repeater-wrapper')
|
||||
.find(discount)
|
||||
.text(discountInput.val() + '%');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Repeater init
|
||||
if (sourceItem.length) {
|
||||
sourceItem.on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
sourceItem.repeater({
|
||||
show: function () {
|
||||
$(this).slideDown();
|
||||
// Initialize tooltip on load of each item
|
||||
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
},
|
||||
hide: function (e) {
|
||||
$(this).slideUp();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Item details select onchange
|
||||
$(document).on('change', '.item-details', function () {
|
||||
var $this = $(this),
|
||||
value = adminDetails[$this.val()];
|
||||
if ($this.next('textarea').length) {
|
||||
$this.next('textarea').val(value);
|
||||
} else {
|
||||
$this.after('<textarea class="form-control" rows="2">' + value + '</textarea>');
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,134 +0,0 @@
|
||||
/**
|
||||
* App Invoice - Edit
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
const invoiceItemPriceList = document.querySelectorAll('.invoice-item-price'),
|
||||
invoiceItemQtyList = document.querySelectorAll('.invoice-item-qty'),
|
||||
date = new Date(),
|
||||
invoiceDate = document.querySelector('.invoice-date'),
|
||||
dueDate = document.querySelector('.due-date');
|
||||
|
||||
// Price
|
||||
if (invoiceItemPriceList) {
|
||||
invoiceItemPriceList.forEach(function (invoiceItemPrice) {
|
||||
new Cleave(invoiceItemPrice, {
|
||||
delimiter: '',
|
||||
numeral: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Qty
|
||||
if (invoiceItemQtyList) {
|
||||
invoiceItemQtyList.forEach(function (invoiceItemQty) {
|
||||
new Cleave(invoiceItemQty, {
|
||||
delimiter: '',
|
||||
numeral: true
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Datepicker
|
||||
if (invoiceDate) {
|
||||
invoiceDate.flatpickr({
|
||||
monthSelectorType: 'static',
|
||||
defaultDate: date
|
||||
});
|
||||
}
|
||||
if (dueDate) {
|
||||
dueDate.flatpickr({
|
||||
monthSelectorType: 'static',
|
||||
defaultDate: new Date(date.getFullYear(), date.getMonth(), date.getDate() + 5)
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// repeater (jquery)
|
||||
$(function () {
|
||||
var applyChangesBtn = $('.btn-apply-changes'),
|
||||
discount,
|
||||
tax1,
|
||||
tax2,
|
||||
discountInput,
|
||||
taxInput1,
|
||||
taxInput2,
|
||||
sourceItem = $('.source-item'),
|
||||
adminDetails = {
|
||||
'App Design': 'Designed UI kit & app pages.',
|
||||
'App Customization': 'Customization & Bug Fixes.',
|
||||
'ABC Template': 'Bootstrap 4 admin template.',
|
||||
'App Development': 'Native App Development.'
|
||||
};
|
||||
|
||||
// Prevent dropdown from closing on tax change
|
||||
$(document).on('click', '.tax-select', function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
// On tax change update it's value value
|
||||
function updateValue(listener, el) {
|
||||
listener.closest('.repeater-wrapper').find(el).text(listener.val());
|
||||
}
|
||||
|
||||
// Apply item changes btn
|
||||
if (applyChangesBtn.length) {
|
||||
$(document).on('click', '.btn-apply-changes', function (e) {
|
||||
var $this = $(this);
|
||||
taxInput1 = $this.closest('.dropdown-menu').find('#taxInput1');
|
||||
taxInput2 = $this.closest('.dropdown-menu').find('#taxInput2');
|
||||
discountInput = $this.closest('.dropdown-menu').find('#discountInput');
|
||||
tax1 = $this.closest('.repeater-wrapper').find('.tax-1');
|
||||
tax2 = $this.closest('.repeater-wrapper').find('.tax-2');
|
||||
discount = $('.discount');
|
||||
|
||||
if (taxInput1.val() !== null) {
|
||||
updateValue(taxInput1, tax1);
|
||||
}
|
||||
|
||||
if (taxInput2.val() !== null) {
|
||||
updateValue(taxInput2, tax2);
|
||||
}
|
||||
|
||||
if (discountInput.val().length) {
|
||||
$this
|
||||
.closest('.repeater-wrapper')
|
||||
.find(discount)
|
||||
.text(discountInput.val() + '%');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Repeater init
|
||||
if (sourceItem.length) {
|
||||
sourceItem.on('submit', function (e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
sourceItem.repeater({
|
||||
show: function () {
|
||||
$(this).slideDown();
|
||||
// Initialize tooltip on load of each item
|
||||
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
},
|
||||
hide: function (e) {
|
||||
$(this).slideUp();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Item details select onchange
|
||||
$(document).on('change', '.item-details', function () {
|
||||
var $this = $(this),
|
||||
value = adminDetails[$this.val()];
|
||||
if ($this.next('textarea').length) {
|
||||
$this.next('textarea').val(value);
|
||||
} else {
|
||||
$this.after('<textarea class="form-control" rows="2">' + value + '</textarea>');
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,297 +0,0 @@
|
||||
/**
|
||||
* App Invoice List (jquery)
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
$(function () {
|
||||
// Variable declaration for table
|
||||
var dt_invoice_table = $('.invoice-list-table');
|
||||
|
||||
// Invoice datatable
|
||||
if (dt_invoice_table.length) {
|
||||
var dt_invoice = dt_invoice_table.DataTable({
|
||||
ajax: assetsPath + 'json/invoice-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'invoice_id' },
|
||||
{ data: 'invoice_status' },
|
||||
{ data: 'issued_date' },
|
||||
{ data: 'client_name' },
|
||||
{ data: 'total' },
|
||||
{ data: 'balance' },
|
||||
{ data: 'invoice_status' },
|
||||
{ data: 'action' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
responsivePriority: 2,
|
||||
searchable: false,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice ID
|
||||
targets: 1,
|
||||
render: function (data, type, full, meta) {
|
||||
var $invoice_id = full['invoice_id'];
|
||||
// Creates full output for row
|
||||
var $row_output = '<a href="app-invoice-preview.html">#' + $invoice_id + '</a>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice status
|
||||
targets: 2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $invoice_status = full['invoice_status'],
|
||||
$due_date = full['due_date'],
|
||||
$balance = full['balance'];
|
||||
var roleBadgeObj = {
|
||||
Sent: '<span class="badge badge-center rounded-pill bg-label-secondary w-px-30 h-px-30"><i class="ti ti-circle-check ti-sm"></i></span>',
|
||||
Draft:
|
||||
'<span class="badge badge-center rounded-pill bg-label-primary w-px-30 h-px-30"><i class="ti ti-device-floppy ti-sm"></i></span>',
|
||||
'Past Due':
|
||||
'<span class="badge badge-center rounded-pill bg-label-danger w-px-30 h-px-30"><i class="ti ti-info-circle ti-sm"></i></span>',
|
||||
'Partial Payment':
|
||||
'<span class="badge badge-center rounded-pill bg-label-success w-px-30 h-px-30"><i class="ti ti-circle-half-2 ti-sm"></i></span>',
|
||||
Paid: '<span class="badge badge-center rounded-pill bg-label-warning w-px-30 h-px-30"><i class="ti ti-chart-pie ti-sm"></i></span>',
|
||||
Downloaded:
|
||||
'<span class="badge badge-center rounded-pill bg-label-info w-px-30 h-px-30"><i class="ti ti-arrow-down-circle ti-sm"></i></span>'
|
||||
};
|
||||
return (
|
||||
"<span data-bs-toggle='tooltip' data-bs-html='true' title='<span>" +
|
||||
$invoice_status +
|
||||
'<br> <strong>Balance:</strong> ' +
|
||||
$balance +
|
||||
'<br> <strong>Due Date:</strong> ' +
|
||||
$due_date +
|
||||
"</span>'>" +
|
||||
roleBadgeObj[$invoice_status] +
|
||||
'</span>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Client name and Service
|
||||
targets: 3,
|
||||
responsivePriority: 4,
|
||||
render: function (data, type, full, meta) {
|
||||
var $name = full['client_name'],
|
||||
$service = full['service'],
|
||||
$image = full['avatar_image'],
|
||||
$rand_num = Math.floor(Math.random() * 11) + 1,
|
||||
$user_img = $rand_num + '.png';
|
||||
if ($image === true) {
|
||||
// For Avatar image
|
||||
var $output =
|
||||
'<img src="' + assetsPath + 'img/avatars/' + $user_img + '" alt="Avatar" class="rounded-circle">';
|
||||
} else {
|
||||
// For Avatar badge
|
||||
var stateNum = Math.floor(Math.random() * 6),
|
||||
states = ['success', 'danger', 'warning', 'info', 'primary', 'secondary'],
|
||||
$state = states[stateNum],
|
||||
$name = full['client_name'],
|
||||
$initials = $name.match(/\b\w/g) || [];
|
||||
$initials = (($initials.shift() || '') + ($initials.pop() || '')).toUpperCase();
|
||||
$output = '<span class="avatar-initial rounded-circle bg-label-' + $state + '">' + $initials + '</span>';
|
||||
}
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<div class="d-flex justify-content-start align-items-center">' +
|
||||
'<div class="avatar-wrapper">' +
|
||||
'<div class="avatar avatar-sm me-2">' +
|
||||
$output +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="d-flex flex-column">' +
|
||||
'<a href="pages-profile-user.html" class="text-body text-truncate"><span class="fw-semibold">' +
|
||||
$name +
|
||||
'</span></a>' +
|
||||
'<small class="text-truncate text-muted">' +
|
||||
$service +
|
||||
'</small>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Total Invoice Amount
|
||||
targets: 4,
|
||||
render: function (data, type, full, meta) {
|
||||
var $total = full['total'];
|
||||
return '<span class="d-none">' + $total + '</span>$' + $total;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Due Date
|
||||
targets: 5,
|
||||
render: function (data, type, full, meta) {
|
||||
var $due_date = new Date(full['due_date']);
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<span class="d-none">' +
|
||||
moment($due_date).format('YYYYMMDD') +
|
||||
'</span>' +
|
||||
moment($due_date).format('DD MMM YYYY');
|
||||
$due_date;
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Client Balance/Status
|
||||
targets: 6,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
var $balance = full['balance'];
|
||||
if ($balance === 0) {
|
||||
var $badge_class = 'bg-label-success';
|
||||
return '<span class="badge ' + $badge_class + '" text-capitalized> Paid </span>';
|
||||
} else {
|
||||
return '<span class="d-none">' + $balance + '</span>' + $balance;
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: 7,
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
title: 'Actions',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<div class="d-flex align-items-center">' +
|
||||
'<a href="javascript:;" data-bs-toggle="tooltip" class="text-body" data-bs-placement="top" title="Send Mail"><i class="ti ti-mail mx-2 ti-sm"></i></a>' +
|
||||
'<a href="app-invoice-preview.html" data-bs-toggle="tooltip" class="text-body" data-bs-placement="top" title="Preview Invoice"><i class="ti ti-eye mx-2 ti-sm"></i></a>' +
|
||||
'<div class="dropdown">' +
|
||||
'<a href="javascript:;" class="btn dropdown-toggle hide-arrow text-body p-0" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-sm"></i></a>' +
|
||||
'<div class="dropdown-menu dropdown-menu-end">' +
|
||||
'<a href="javascript:;" class="dropdown-item">Download</a>' +
|
||||
'<a href="app-invoice-edit.html" class="dropdown-item">Edit</a>' +
|
||||
'<a href="javascript:;" class="dropdown-item">Duplicate</a>' +
|
||||
'<div class="dropdown-divider"></div>' +
|
||||
'<a href="javascript:;" class="dropdown-item delete-record text-danger">Delete</a>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
dom:
|
||||
'<"row ms-2 me-3"' +
|
||||
'<"col-12 col-md-6 d-flex align-items-center justify-content-center justify-content-md-start gap-2"l<"dt-action-buttons text-xl-end text-lg-start text-md-end text-start mt-md-0 mt-3"B>>' +
|
||||
'<"col-12 col-md-6 d-flex align-items-center justify-content-end flex-column flex-md-row pe-3 gap-md-2"f<"invoice_status mb-3 mb-md-0">>' +
|
||||
'>t' +
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
language: {
|
||||
sLengthMenu: 'Show _MENU_',
|
||||
search: '',
|
||||
searchPlaceholder: 'Search Invoice'
|
||||
},
|
||||
// Buttons with Dropdown
|
||||
buttons: [
|
||||
{
|
||||
text: '<i class="ti ti-plus me-md-1"></i><span class="d-md-inline-block d-none">Create Invoice</span>',
|
||||
className: 'btn btn-primary',
|
||||
action: function (e, dt, button, config) {
|
||||
window.location = 'app-invoice-add.html';
|
||||
}
|
||||
}
|
||||
],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
// Adding role filter once table initialized
|
||||
this.api()
|
||||
.columns(7)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="UserRole" class="form-select"><option value=""> Select Status </option></select>'
|
||||
)
|
||||
.appendTo('.invoice_status')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '" class="text-capitalize">' + d + '</option>');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// On each datatable draw, initialize tooltip
|
||||
dt_invoice_table.on('draw.dt', function () {
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl, {
|
||||
boundary: document.body
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Delete Record
|
||||
$('.invoice-list-table tbody').on('click', '.delete-record', function () {
|
||||
dt_invoice.row($(this).parents('tr')).remove().draw();
|
||||
});
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
});
|
||||
@ -1,9 +0,0 @@
|
||||
/**
|
||||
* Invoice Print
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
window.print();
|
||||
})();
|
||||
@ -1,471 +0,0 @@
|
||||
/**
|
||||
* App Kanban
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(async function () {
|
||||
let boards;
|
||||
const kanbanSidebar = document.querySelector('.kanban-update-item-sidebar'),
|
||||
kanbanWrapper = document.querySelector('.kanban-wrapper'),
|
||||
commentEditor = document.querySelector('.comment-editor'),
|
||||
kanbanAddNewBoard = document.querySelector('.kanban-add-new-board'),
|
||||
kanbanAddNewInput = [].slice.call(document.querySelectorAll('.kanban-add-board-input')),
|
||||
kanbanAddBoardBtn = document.querySelector('.kanban-add-board-btn'),
|
||||
datePicker = document.querySelector('#due-date'),
|
||||
select2 = $('.select2'), // ! Using jquery vars due to select2 jQuery dependency
|
||||
assetsPath = document.querySelector('html').getAttribute('data-assets-path');
|
||||
|
||||
// Init kanban Offcanvas
|
||||
const kanbanOffcanvas = new bootstrap.Offcanvas(kanbanSidebar);
|
||||
|
||||
// Get kanban data
|
||||
const kanbanResponse = await fetch(assetsPath + 'json/kanban.json');
|
||||
if (!kanbanResponse.ok) {
|
||||
console.error('error', kanbanResponse);
|
||||
}
|
||||
boards = await kanbanResponse.json();
|
||||
|
||||
// datepicker init
|
||||
if (datePicker) {
|
||||
datePicker.flatpickr({
|
||||
monthSelectorType: 'static',
|
||||
altInput: true,
|
||||
altFormat: 'j F, Y',
|
||||
dateFormat: 'Y-m-d'
|
||||
});
|
||||
}
|
||||
|
||||
//! TODO: Update Event label and guest code to JS once select removes jQuery dependency
|
||||
// select2
|
||||
if (select2.length) {
|
||||
function renderLabels(option) {
|
||||
if (!option.id) {
|
||||
return option.text;
|
||||
}
|
||||
var $badge = "<div class='badge " + $(option.element).data('color') + " rounded-pill'> " + option.text + '</div>';
|
||||
return $badge;
|
||||
}
|
||||
|
||||
select2.each(function () {
|
||||
var $this = $(this);
|
||||
$this.wrap("<div class='position-relative'></div>").select2({
|
||||
placeholder: 'Select Label',
|
||||
dropdownParent: $this.parent(),
|
||||
templateResult: renderLabels,
|
||||
templateSelection: renderLabels,
|
||||
escapeMarkup: function (es) {
|
||||
return es;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Comment editor
|
||||
if (commentEditor) {
|
||||
new Quill(commentEditor, {
|
||||
modules: {
|
||||
toolbar: '.comment-toolbar'
|
||||
},
|
||||
placeholder: 'Write a Comment... ',
|
||||
theme: 'snow'
|
||||
});
|
||||
}
|
||||
|
||||
// Render board dropdown
|
||||
function renderBoardDropdown() {
|
||||
return (
|
||||
"<div class='dropdown'>" +
|
||||
"<i class='dropdown-toggle ti ti-dots-vertical cursor-pointer' id='board-dropdown' data-bs-toggle='dropdown' aria-haspopup='true' aria-expanded='false'></i>" +
|
||||
"<div class='dropdown-menu dropdown-menu-end' aria-labelledby='board-dropdown'>" +
|
||||
"<a class='dropdown-item delete-board' href='javascript:void(0)'> <i class='ti ti-trash ti-xs' me-1></i> <span class='align-middle'>Delete</span></a>" +
|
||||
"<a class='dropdown-item' href='javascript:void(0)'><i class='ti ti-edit ti-xs' me-1></i> <span class='align-middle'>Rename</span></a>" +
|
||||
"<a class='dropdown-item' href='javascript:void(0)'><i class='ti ti-archive ti-xs' me-1></i> <span class='align-middle'>Archive</span></a>" +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
// Render item dropdown
|
||||
function renderDropdown() {
|
||||
return (
|
||||
"<div class='dropdown kanban-tasks-item-dropdown'>" +
|
||||
"<i class='dropdown-toggle ti ti-dots-vertical' id='kanban-tasks-item-dropdown' data-bs-toggle='dropdown' aria-haspopup='true' aria-expanded='false'></i>" +
|
||||
"<div class='dropdown-menu dropdown-menu-end' aria-labelledby='kanban-tasks-item-dropdown'>" +
|
||||
"<a class='dropdown-item' href='javascript:void(0)'>Copy task link</a>" +
|
||||
"<a class='dropdown-item' href='javascript:void(0)'>Duplicate task</a>" +
|
||||
"<a class='dropdown-item delete-task' href='javascript:void(0)'>Delete</a>" +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
// Render header
|
||||
function renderHeader(color, text) {
|
||||
return (
|
||||
"<div class='d-flex justify-content-between flex-wrap align-items-center mb-2 pb-1'>" +
|
||||
"<div class='item-badges'> " +
|
||||
"<div class='badge rounded-pill bg-label-" +
|
||||
color +
|
||||
"'> " +
|
||||
text +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
renderDropdown() +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
// Render avatar
|
||||
function renderAvatar(images, pullUp, size, margin, members) {
|
||||
var $transition = pullUp ? ' pull-up' : '',
|
||||
$size = size ? 'avatar-' + size + '' : '',
|
||||
member = members == undefined ? ' ' : members.split(',');
|
||||
|
||||
return images == undefined
|
||||
? ' '
|
||||
: images
|
||||
.split(',')
|
||||
.map(function (img, index, arr) {
|
||||
var $margin = margin && index !== arr.length - 1 ? ' me-' + margin + '' : '';
|
||||
|
||||
return (
|
||||
"<div class='avatar " +
|
||||
$size +
|
||||
$margin +
|
||||
"'" +
|
||||
"data-bs-toggle='tooltip' data-bs-placement='top'" +
|
||||
"title='" +
|
||||
member[index] +
|
||||
"'" +
|
||||
'>' +
|
||||
"<img src='" +
|
||||
assetsPath +
|
||||
'img/avatars/' +
|
||||
img +
|
||||
"' alt='Avatar' class='rounded-circle " +
|
||||
$transition +
|
||||
"'>" +
|
||||
'</div>'
|
||||
);
|
||||
})
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
// Render footer
|
||||
function renderFooter(attachments, comments, assigned, members) {
|
||||
return (
|
||||
"<div class='d-flex justify-content-between align-items-center flex-wrap mt-2 pt-1'>" +
|
||||
"<div class='d-flex'> <span class='d-flex align-items-center me-2'><i class='ti ti-paperclip ti-xs me-1'></i>" +
|
||||
"<span class='attachments'>" +
|
||||
attachments +
|
||||
'</span>' +
|
||||
"</span> <span class='d-flex align-items-center ms-1'><i class='ti ti-message-dots ti-xs me-1'></i>" +
|
||||
'<span> ' +
|
||||
comments +
|
||||
' </span>' +
|
||||
'</span></div>' +
|
||||
"<div class='avatar-group d-flex align-items-center assigned-avatar'>" +
|
||||
renderAvatar(assigned, true, 'xs', null, members) +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
// Init kanban
|
||||
const kanban = new jKanban({
|
||||
element: '.kanban-wrapper',
|
||||
gutter: '15px',
|
||||
widthBoard: '250px',
|
||||
dragItems: true,
|
||||
boards: boards,
|
||||
dragBoards: true,
|
||||
addItemButton: true,
|
||||
buttonContent: '+ Add Item',
|
||||
itemAddOptions: {
|
||||
enabled: true, // add a button to board for easy item creation
|
||||
content: '+ Add New Item', // text or html content of the board button
|
||||
class: 'kanban-title-button btn', // default class of the button
|
||||
footer: false // position the button on footer
|
||||
},
|
||||
click: function (el) {
|
||||
let element = el;
|
||||
let title = element.getAttribute('data-eid')
|
||||
? element.querySelector('.kanban-text').textContent
|
||||
: element.textContent,
|
||||
date = element.getAttribute('data-due-date'),
|
||||
dateObj = new Date(),
|
||||
year = dateObj.getFullYear(),
|
||||
dateToUse = date
|
||||
? date + ', ' + year
|
||||
: dateObj.getDate() + ' ' + dateObj.toLocaleString('en', { month: 'long' }) + ', ' + year,
|
||||
label = element.getAttribute('data-badge-text'),
|
||||
avatars = element.getAttribute('data-assigned');
|
||||
|
||||
// Show kanban offcanvas
|
||||
kanbanOffcanvas.show();
|
||||
|
||||
// To get data on sidebar
|
||||
kanbanSidebar.querySelector('#title').value = title;
|
||||
kanbanSidebar.querySelector('#due-date').nextSibling.value = dateToUse;
|
||||
|
||||
// ! Using jQuery method to get sidebar due to select2 dependency
|
||||
$('.kanban-update-item-sidebar').find(select2).val(label).trigger('change');
|
||||
|
||||
// Remove & Update assigned
|
||||
kanbanSidebar.querySelector('.assigned').innerHTML = '';
|
||||
kanbanSidebar
|
||||
.querySelector('.assigned')
|
||||
.insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
renderAvatar(avatars, false, 'xs', '1', el.getAttribute('data-members')) +
|
||||
"<div class='avatar avatar-xs ms-1'>" +
|
||||
"<span class='avatar-initial rounded-circle bg-label-secondary'><i class='ti ti-plus ti-xs text-heading'></i></span>" +
|
||||
'</div>'
|
||||
);
|
||||
},
|
||||
|
||||
buttonClick: function (el, boardId) {
|
||||
const addNew = document.createElement('form');
|
||||
addNew.setAttribute('class', 'new-item-form');
|
||||
addNew.innerHTML =
|
||||
'<div class="mb-3">' +
|
||||
'<textarea class="form-control add-new-item" rows="2" placeholder="Add Content" autofocus required></textarea>' +
|
||||
'</div>' +
|
||||
'<div class="mb-3">' +
|
||||
'<button type="submit" class="btn btn-primary btn-sm me-2">Add</button>' +
|
||||
'<button type="button" class="btn btn-label-secondary btn-sm cancel-add-item">Cancel</button>' +
|
||||
'</div>';
|
||||
kanban.addForm(boardId, addNew);
|
||||
|
||||
addNew.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
const currentBoard = [].slice.call(
|
||||
document.querySelectorAll('.kanban-board[data-id=' + boardId + '] .kanban-item')
|
||||
);
|
||||
kanban.addElement(boardId, {
|
||||
title: "<span class='kanban-text'>" + e.target[0].value + '</span>',
|
||||
id: boardId + '-' + currentBoard.length + 1
|
||||
});
|
||||
|
||||
// add dropdown in new boards
|
||||
const kanbanText = [].slice.call(
|
||||
document.querySelectorAll('.kanban-board[data-id=' + boardId + '] .kanban-text')
|
||||
);
|
||||
kanbanText.forEach(function (e) {
|
||||
e.insertAdjacentHTML('beforebegin', renderDropdown());
|
||||
});
|
||||
|
||||
// prevent sidebar to open onclick dropdown buttons of new tasks
|
||||
const newTaskDropdown = [].slice.call(document.querySelectorAll('.kanban-item .kanban-tasks-item-dropdown'));
|
||||
if (newTaskDropdown) {
|
||||
newTaskDropdown.forEach(function (e) {
|
||||
e.addEventListener('click', function (el) {
|
||||
el.stopPropagation();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// delete tasks for new boards
|
||||
const deleteTask = [].slice.call(
|
||||
document.querySelectorAll('.kanban-board[data-id=' + boardId + '] .delete-task')
|
||||
);
|
||||
deleteTask.forEach(function (e) {
|
||||
e.addEventListener('click', function () {
|
||||
const id = this.closest('.kanban-item').getAttribute('data-eid');
|
||||
kanban.removeElement(id);
|
||||
});
|
||||
});
|
||||
addNew.remove();
|
||||
});
|
||||
|
||||
// Remove form on clicking cancel button
|
||||
addNew.querySelector('.cancel-add-item').addEventListener('click', function (e) {
|
||||
addNew.remove();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Kanban Wrapper scrollbar
|
||||
if (kanbanWrapper) {
|
||||
new PerfectScrollbar(kanbanWrapper);
|
||||
}
|
||||
|
||||
const kanbanContainer = document.querySelector('.kanban-container'),
|
||||
kanbanTitleBoard = [].slice.call(document.querySelectorAll('.kanban-title-board')),
|
||||
kanbanItem = [].slice.call(document.querySelectorAll('.kanban-item'));
|
||||
|
||||
// Render custom items
|
||||
if (kanbanItem) {
|
||||
kanbanItem.forEach(function (el) {
|
||||
const element = "<span class='kanban-text'>" + el.textContent + '</span>';
|
||||
let img = '';
|
||||
if (el.getAttribute('data-image') !== null) {
|
||||
img =
|
||||
"<img class='img-fluid rounded mb-2' src='" +
|
||||
assetsPath +
|
||||
'img/elements/' +
|
||||
el.getAttribute('data-image') +
|
||||
"'>";
|
||||
}
|
||||
el.textContent = '';
|
||||
if (el.getAttribute('data-badge') !== undefined && el.getAttribute('data-badge-text') !== undefined) {
|
||||
el.insertAdjacentHTML(
|
||||
'afterbegin',
|
||||
renderHeader(el.getAttribute('data-badge'), el.getAttribute('data-badge-text')) + img + element
|
||||
);
|
||||
}
|
||||
if (
|
||||
el.getAttribute('data-comments') !== undefined ||
|
||||
el.getAttribute('data-due-date') !== undefined ||
|
||||
el.getAttribute('data-assigned') !== undefined
|
||||
) {
|
||||
el.insertAdjacentHTML(
|
||||
'beforeend',
|
||||
renderFooter(
|
||||
el.getAttribute('data-attachments'),
|
||||
el.getAttribute('data-comments'),
|
||||
el.getAttribute('data-assigned'),
|
||||
el.getAttribute('data-members')
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// To initialize tooltips for rendered items
|
||||
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
|
||||
// prevent sidebar to open onclick dropdown buttons of tasks
|
||||
const tasksItemDropdown = [].slice.call(document.querySelectorAll('.kanban-tasks-item-dropdown'));
|
||||
if (tasksItemDropdown) {
|
||||
tasksItemDropdown.forEach(function (e) {
|
||||
e.addEventListener('click', function (el) {
|
||||
el.stopPropagation();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle add new input and actions add-new-btn
|
||||
if (kanbanAddBoardBtn) {
|
||||
kanbanAddBoardBtn.addEventListener('click', () => {
|
||||
kanbanAddNewInput.forEach(el => {
|
||||
el.value = '';
|
||||
el.classList.toggle('d-none');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Render add new inline with boards
|
||||
if (kanbanContainer) {
|
||||
kanbanContainer.appendChild(kanbanAddNewBoard);
|
||||
}
|
||||
|
||||
// Makes kanban title editable for rendered boards
|
||||
if (kanbanTitleBoard) {
|
||||
kanbanTitleBoard.forEach(function (elem) {
|
||||
elem.addEventListener('mouseenter', function () {
|
||||
this.contentEditable = 'true';
|
||||
});
|
||||
|
||||
// Appends delete icon with title
|
||||
elem.insertAdjacentHTML('afterend', renderBoardDropdown());
|
||||
});
|
||||
}
|
||||
|
||||
// To delete Board for rendered boards
|
||||
const deleteBoards = [].slice.call(document.querySelectorAll('.delete-board'));
|
||||
if (deleteBoards) {
|
||||
deleteBoards.forEach(function (elem) {
|
||||
elem.addEventListener('click', function () {
|
||||
const id = this.closest('.kanban-board').getAttribute('data-id');
|
||||
kanban.removeBoard(id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Delete task for rendered boards
|
||||
const deleteTask = [].slice.call(document.querySelectorAll('.delete-task'));
|
||||
if (deleteTask) {
|
||||
deleteTask.forEach(function (e) {
|
||||
e.addEventListener('click', function () {
|
||||
const id = this.closest('.kanban-item').getAttribute('data-eid');
|
||||
kanban.removeElement(id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Cancel btn add new input
|
||||
const cancelAddNew = document.querySelector('.kanban-add-board-cancel-btn');
|
||||
if (cancelAddNew) {
|
||||
cancelAddNew.addEventListener('click', function () {
|
||||
kanbanAddNewInput.forEach(el => {
|
||||
el.classList.toggle('d-none');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add new board
|
||||
if (kanbanAddNewBoard) {
|
||||
kanbanAddNewBoard.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
const thisEle = this,
|
||||
value = thisEle.querySelector('.form-control').value,
|
||||
id = value.replace(/\s+/g, '-').toLowerCase();
|
||||
kanban.addBoards([
|
||||
{
|
||||
id: id,
|
||||
title: value
|
||||
}
|
||||
]);
|
||||
|
||||
// Adds delete board option to new board, delete new boards & updates data-order
|
||||
const kanbanBoardLastChild = document.querySelectorAll('.kanban-board:last-child')[0];
|
||||
if (kanbanBoardLastChild) {
|
||||
const header = kanbanBoardLastChild.querySelector('.kanban-title-board');
|
||||
header.insertAdjacentHTML('afterend', renderBoardDropdown());
|
||||
|
||||
// To make newly added boards title editable
|
||||
kanbanBoardLastChild.querySelector('.kanban-title-board').addEventListener('mouseenter', function () {
|
||||
this.contentEditable = 'true';
|
||||
});
|
||||
}
|
||||
|
||||
// Add delete event to delete newly added boards
|
||||
const deleteNewBoards = kanbanBoardLastChild.querySelector('.delete-board');
|
||||
if (deleteNewBoards) {
|
||||
deleteNewBoards.addEventListener('click', function () {
|
||||
const id = this.closest('.kanban-board').getAttribute('data-id');
|
||||
kanban.removeBoard(id);
|
||||
});
|
||||
}
|
||||
|
||||
// Remove current append new add new form
|
||||
if (kanbanAddNewInput) {
|
||||
kanbanAddNewInput.forEach(el => {
|
||||
el.classList.add('d-none');
|
||||
});
|
||||
}
|
||||
|
||||
// To place inline add new btn after clicking add btn
|
||||
if (kanbanContainer) {
|
||||
kanbanContainer.appendChild(kanbanAddNewBoard);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Clear comment editor on close
|
||||
kanbanSidebar.addEventListener('hidden.bs.offcanvas', function () {
|
||||
kanbanSidebar.querySelector('.ql-editor').firstElementChild.innerHTML = '';
|
||||
});
|
||||
|
||||
// Re-init tooltip when offcanvas opens(Bootstrap bug)
|
||||
if (kanbanSidebar) {
|
||||
kanbanSidebar.addEventListener('shown.bs.offcanvas', function () {
|
||||
const tooltipTriggerList = [].slice.call(kanbanSidebar.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -1,516 +0,0 @@
|
||||
/**
|
||||
* Page User List
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// Datatable (jquery)
|
||||
$(function () {
|
||||
let borderColor, bodyBg, headingColor;
|
||||
|
||||
if (isDarkStyle) {
|
||||
borderColor = config.colors_dark.borderColor;
|
||||
bodyBg = config.colors_dark.bodyBg;
|
||||
headingColor = config.colors_dark.headingColor;
|
||||
} else {
|
||||
borderColor = config.colors.borderColor;
|
||||
bodyBg = config.colors.bodyBg;
|
||||
headingColor = config.colors.headingColor;
|
||||
}
|
||||
|
||||
// Variable declaration for table
|
||||
var dt_user_table = $('.datatables-users'),
|
||||
select2 = $('.select2'),
|
||||
userView = 'app-user-view-account.html',
|
||||
statusObj = {
|
||||
1: { title: 'Pending', class: 'bg-label-warning' },
|
||||
2: { title: 'Active', class: 'bg-label-success' },
|
||||
3: { title: 'Inactive', class: 'bg-label-secondary' }
|
||||
};
|
||||
|
||||
if (select2.length) {
|
||||
var $this = select2;
|
||||
$this.wrap('<div class="position-relative"></div>').select2({
|
||||
placeholder: 'Select Country',
|
||||
dropdownParent: $this.parent()
|
||||
});
|
||||
}
|
||||
|
||||
// Users datatable
|
||||
if (dt_user_table.length) {
|
||||
var dt_user = dt_user_table.DataTable({
|
||||
ajax: assetsPath + 'json/user-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'full_name' },
|
||||
{ data: 'role' },
|
||||
{ data: 'current_plan' },
|
||||
{ data: 'billing' },
|
||||
{ data: 'status' },
|
||||
{ data: 'action' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User full name and email
|
||||
targets: 1,
|
||||
responsivePriority: 4,
|
||||
render: function (data, type, full, meta) {
|
||||
var $name = full['full_name'],
|
||||
$email = full['email'],
|
||||
$image = full['avatar'];
|
||||
if ($image) {
|
||||
// For Avatar image
|
||||
var $output =
|
||||
'<img src="' + assetsPath + 'img/avatars/' + $image + '" alt="Avatar" class="rounded-circle">';
|
||||
} else {
|
||||
// For Avatar badge
|
||||
var stateNum = Math.floor(Math.random() * 6);
|
||||
var states = ['success', 'danger', 'warning', 'info', 'primary', 'secondary'];
|
||||
var $state = states[stateNum],
|
||||
$name = full['full_name'],
|
||||
$initials = $name.match(/\b\w/g) || [];
|
||||
$initials = (($initials.shift() || '') + ($initials.pop() || '')).toUpperCase();
|
||||
$output = '<span class="avatar-initial rounded-circle bg-label-' + $state + '">' + $initials + '</span>';
|
||||
}
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<div class="d-flex justify-content-start align-items-center user-name">' +
|
||||
'<div class="avatar-wrapper">' +
|
||||
'<div class="avatar avatar-sm me-3">' +
|
||||
$output +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="d-flex flex-column">' +
|
||||
'<a href="' +
|
||||
userView +
|
||||
'" class="text-body text-truncate"><span class="fw-semibold">' +
|
||||
$name +
|
||||
'</span></a>' +
|
||||
'<small class="text-muted">' +
|
||||
$email +
|
||||
'</small>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Role
|
||||
targets: 2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $role = full['role'];
|
||||
var roleBadgeObj = {
|
||||
Subscriber:
|
||||
'<span class="badge badge-center rounded-pill bg-label-warning w-px-30 h-px-30 me-2"><i class="ti ti-user ti-sm"></i></span>',
|
||||
Author:
|
||||
'<span class="badge badge-center rounded-pill bg-label-success w-px-30 h-px-30 me-2"><i class="ti ti-circle-check ti-sm"></i></span>',
|
||||
Maintainer:
|
||||
'<span class="badge badge-center rounded-pill bg-label-primary w-px-30 h-px-30 me-2"><i class="ti ti-chart-pie-2 ti-sm"></i></span>',
|
||||
Editor:
|
||||
'<span class="badge badge-center rounded-pill bg-label-info w-px-30 h-px-30 me-2"><i class="ti ti-edit ti-sm"></i></span>',
|
||||
Admin:
|
||||
'<span class="badge badge-center rounded-pill bg-label-secondary w-px-30 h-px-30 me-2"><i class="ti ti-device-laptop ti-sm"></i></span>'
|
||||
};
|
||||
return "<span class='text-truncate d-flex align-items-center'>" + roleBadgeObj[$role] + $role + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// Plans
|
||||
targets: 3,
|
||||
render: function (data, type, full, meta) {
|
||||
var $plan = full['current_plan'];
|
||||
|
||||
return '<span class="fw-semibold">' + $plan + '</span>';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User Status
|
||||
targets: 5,
|
||||
render: function (data, type, full, meta) {
|
||||
var $status = full['status'];
|
||||
|
||||
return (
|
||||
'<span class="badge ' +
|
||||
statusObj[$status].class +
|
||||
'" text-capitalized>' +
|
||||
statusObj[$status].title +
|
||||
'</span>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
title: 'Actions',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<div class="d-flex align-items-center">' +
|
||||
'<a href="javascript:;" class="text-body"><i class="ti ti-edit ti-sm me-2"></i></a>' +
|
||||
'<a href="javascript:;" class="text-body delete-record"><i class="ti ti-trash ti-sm mx-2"></i></a>' +
|
||||
'<a href="javascript:;" class="text-body dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical ti-sm mx-1"></i></a>' +
|
||||
'<div class="dropdown-menu dropdown-menu-end m-0">' +
|
||||
'<a href="' +
|
||||
userView +
|
||||
'" class="dropdown-item">View</a>' +
|
||||
'<a href="javascript:;" class="dropdown-item">Suspend</a>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
dom:
|
||||
'<"row me-2"' +
|
||||
'<"col-md-2"<"me-3"l>>' +
|
||||
'<"col-md-10"<"dt-action-buttons text-xl-end text-lg-start text-md-end text-start d-flex align-items-center justify-content-end flex-md-row flex-column mb-3 mb-md-0"fB>>' +
|
||||
'>t' +
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
language: {
|
||||
sLengthMenu: '_MENU_',
|
||||
search: '',
|
||||
searchPlaceholder: 'Search..'
|
||||
},
|
||||
// Buttons with Dropdown
|
||||
buttons: [
|
||||
{
|
||||
extend: 'collection',
|
||||
className: 'btn btn-label-secondary dropdown-toggle mx-3',
|
||||
text: '<i class="ti ti-screen-share me-1 ti-xs"></i>Export',
|
||||
buttons: [
|
||||
{
|
||||
extend: 'print',
|
||||
text: '<i class="ti ti-printer me-2" ></i>Print',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be print
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
},
|
||||
customize: function (win) {
|
||||
//customize print view for dark
|
||||
$(win.document.body)
|
||||
.css('color', headingColor)
|
||||
.css('border-color', borderColor)
|
||||
.css('background-color', bodyBg);
|
||||
$(win.document.body)
|
||||
.find('table')
|
||||
.addClass('compact')
|
||||
.css('color', 'inherit')
|
||||
.css('border-color', 'inherit')
|
||||
.css('background-color', 'inherit');
|
||||
}
|
||||
},
|
||||
{
|
||||
extend: 'csv',
|
||||
text: '<i class="ti ti-file-text me-2" ></i>Csv',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
extend: 'excel',
|
||||
text: '<i class="ti ti-file-spreadsheet me-2"></i>Excel',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
extend: 'pdf',
|
||||
text: '<i class="ti ti-file-code-2 me-2"></i>Pdf',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
extend: 'copy',
|
||||
text: '<i class="ti ti-copy me-2" ></i>Copy',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: {
|
||||
columns: [1, 2, 3, 4, 5],
|
||||
// prevent avatar to be display
|
||||
format: {
|
||||
body: function (inner, coldex, rowdex) {
|
||||
if (inner.length <= 0) return inner;
|
||||
var el = $.parseHTML(inner);
|
||||
var result = '';
|
||||
$.each(el, function (index, item) {
|
||||
if (item.classList !== undefined && item.classList.contains('user-name')) {
|
||||
result = result + item.lastChild.firstChild.textContent;
|
||||
} else if (item.innerText === undefined) {
|
||||
result = result + item.textContent;
|
||||
} else result = result + item.innerText;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '<i class="ti ti-plus me-0 me-sm-1 ti-xs"></i><span class="d-none d-sm-inline-block">Add New User</span>',
|
||||
className: 'add-new btn btn-primary',
|
||||
attr: {
|
||||
'data-bs-toggle': 'offcanvas',
|
||||
'data-bs-target': '#offcanvasAddUser'
|
||||
}
|
||||
}
|
||||
],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
// Adding role filter once table initialized
|
||||
this.api()
|
||||
.columns(2)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="UserRole" class="form-select text-capitalize"><option value=""> Select Role </option></select>'
|
||||
)
|
||||
.appendTo('.user_role')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '">' + d + '</option>');
|
||||
});
|
||||
});
|
||||
// Adding plan filter once table initialized
|
||||
this.api()
|
||||
.columns(3)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="UserPlan" class="form-select text-capitalize"><option value=""> Select Plan </option></select>'
|
||||
)
|
||||
.appendTo('.user_plan')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '">' + d + '</option>');
|
||||
});
|
||||
});
|
||||
// Adding status filter once table initialized
|
||||
this.api()
|
||||
.columns(5)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="FilterTransaction" class="form-select text-capitalize"><option value=""> Select Status </option></select>'
|
||||
)
|
||||
.appendTo('.user_status')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append(
|
||||
'<option value="' +
|
||||
statusObj[d].title +
|
||||
'" class="text-capitalize">' +
|
||||
statusObj[d].title +
|
||||
'</option>'
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Delete Record
|
||||
$('.datatables-users tbody').on('click', '.delete-record', function () {
|
||||
dt_user.row($(this).parents('tr')).remove().draw();
|
||||
});
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
});
|
||||
|
||||
// Validation & Phone mask
|
||||
(function () {
|
||||
const phoneMaskList = document.querySelectorAll('.phone-mask'),
|
||||
addNewUserForm = document.getElementById('addNewUserForm');
|
||||
|
||||
// Phone Number
|
||||
if (phoneMaskList) {
|
||||
phoneMaskList.forEach(function (phoneMask) {
|
||||
new Cleave(phoneMask, {
|
||||
phone: true,
|
||||
phoneRegionCode: 'US'
|
||||
});
|
||||
});
|
||||
}
|
||||
// Add New User Form Validation
|
||||
const fv = FormValidation.formValidation(addNewUserForm, {
|
||||
fields: {
|
||||
userFullname: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter fullname '
|
||||
}
|
||||
}
|
||||
},
|
||||
userEmail: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter your email'
|
||||
},
|
||||
emailAddress: {
|
||||
message: 'The value is not a valid email address'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap5: new FormValidation.plugins.Bootstrap5({
|
||||
// Use this for enabling/changing valid/invalid class
|
||||
eleValidClass: '',
|
||||
rowSelector: function (field, ele) {
|
||||
// field is the field name & ele is the field element
|
||||
return '.mb-3';
|
||||
}
|
||||
}),
|
||||
submitButton: new FormValidation.plugins.SubmitButton(),
|
||||
// Submit the form when all fields are valid
|
||||
// defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
|
||||
autoFocus: new FormValidation.plugins.AutoFocus()
|
||||
}
|
||||
});
|
||||
})();
|
||||
@ -1,378 +0,0 @@
|
||||
/**
|
||||
* App User View - Account (jquery)
|
||||
*/
|
||||
|
||||
$(function () {
|
||||
'use strict';
|
||||
|
||||
// Variable declaration for table
|
||||
var dt_project_table = $('.datatable-project'),
|
||||
dt_invoice_table = $('.datatable-invoice');
|
||||
|
||||
// Project datatable
|
||||
// --------------------------------------------------------------------
|
||||
if (dt_project_table.length) {
|
||||
var dt_project = dt_project_table.DataTable({
|
||||
ajax: assetsPath + 'json/projects-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'project_name' },
|
||||
{ data: 'total_task' },
|
||||
{ data: 'progress' },
|
||||
{ data: 'hours' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
searchable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// User full name and email
|
||||
targets: 1,
|
||||
responsivePriority: 1,
|
||||
render: function (data, type, full, meta) {
|
||||
var $name = full['project_name'],
|
||||
$framework = full['framework'],
|
||||
$image = full['project_image'];
|
||||
if ($image) {
|
||||
// For Avatar image
|
||||
var $output =
|
||||
'<img src="' +
|
||||
assetsPath +
|
||||
'img/icons/brands/' +
|
||||
$image +
|
||||
'" alt="Project Image" class="rounded-circle">';
|
||||
} else {
|
||||
// For Avatar badge
|
||||
var stateNum = Math.floor(Math.random() * 6) + 1;
|
||||
var states = ['success', 'danger', 'warning', 'info', 'dark', 'primary', 'secondary'];
|
||||
var $state = states[stateNum],
|
||||
$name = full['full_name'],
|
||||
$initials = $name.match(/\b\w/g) || [];
|
||||
$initials = (($initials.shift() || '') + ($initials.pop() || '')).toUpperCase();
|
||||
$output = '<span class="avatar-initial rounded-circle bg-label-' + $state + '">' + $initials + '</span>';
|
||||
}
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<div class="d-flex justify-content-left align-items-center">' +
|
||||
'<div class="avatar-wrapper">' +
|
||||
'<div class="avatar avatar-sm me-3">' +
|
||||
$output +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="d-flex flex-column">' +
|
||||
'<span class="text-truncate fw-semibold">' +
|
||||
$name +
|
||||
'</span>' +
|
||||
'<small class="text-muted">' +
|
||||
$framework +
|
||||
'</small>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: 2,
|
||||
orderable: false
|
||||
},
|
||||
{
|
||||
// Label
|
||||
targets: -2,
|
||||
responsivePriority: 3,
|
||||
render: function (data, type, full, meta) {
|
||||
var $progress = full['progress'] + '%',
|
||||
$color;
|
||||
switch (true) {
|
||||
case full['progress'] < 25:
|
||||
$color = 'bg-danger';
|
||||
break;
|
||||
case full['progress'] < 50:
|
||||
$color = 'bg-warning';
|
||||
break;
|
||||
case full['progress'] < 75:
|
||||
$color = 'bg-info';
|
||||
break;
|
||||
case full['progress'] <= 100:
|
||||
$color = 'bg-success';
|
||||
break;
|
||||
}
|
||||
return (
|
||||
'<div class="d-flex flex-column"><small class="mb-1">' +
|
||||
$progress +
|
||||
'</small>' +
|
||||
'<div class="progress w-100 me-3" style="height: 6px;">' +
|
||||
'<div class="progress-bar ' +
|
||||
$color +
|
||||
'" style="width: ' +
|
||||
$progress +
|
||||
'" aria-valuenow="' +
|
||||
$progress +
|
||||
'" aria-valuemin="0" aria-valuemax="100"></div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
targets: -1,
|
||||
orderable: false
|
||||
}
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
dom:
|
||||
'<"d-flex justify-content-between align-items-center flex-column flex-sm-row mx-4 row"' +
|
||||
'<"col-sm-4 col-12 d-flex align-items-center justify-content-sm-start justify-content-center"l>' +
|
||||
'<"col-sm-8 col-12 d-flex align-items-center justify-content-sm-end justify-content-center"f>' +
|
||||
'>t' +
|
||||
'<"d-flex justify-content-between mx-4 row"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
displayLength: 7,
|
||||
lengthMenu: [7, 10, 25, 50, 75, 100],
|
||||
language: {
|
||||
sLengthMenu: 'Show _MENU_',
|
||||
// search: '',
|
||||
searchPlaceholder: 'Search Project'
|
||||
},
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Invoice datatable
|
||||
// --------------------------------------------------------------------
|
||||
if (dt_invoice_table.length) {
|
||||
var dt_invoice = dt_invoice_table.DataTable({
|
||||
ajax: assetsPath + 'json/invoice-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'invoice_id' },
|
||||
{ data: 'invoice_status' },
|
||||
{ data: 'total' },
|
||||
{ data: 'issued_date' },
|
||||
{ data: 'action' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice ID
|
||||
targets: 1,
|
||||
render: function (data, type, full, meta) {
|
||||
var $invoice_id = full['invoice_id'];
|
||||
// Creates full output for row
|
||||
var $row_output = '<a href="app-invoice-preview.html"><span>#' + $invoice_id + '</span></a>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice status
|
||||
targets: 2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $invoice_status = full['invoice_status'],
|
||||
$due_date = full['due_date'],
|
||||
$balance = full['balance'];
|
||||
var roleBadgeObj = {
|
||||
Sent: '<span class="badge badge-center rounded-pill bg-label-secondary w-px-30 h-px-30"><i class="ti ti-circle-check ti-sm"></i></span>',
|
||||
Draft:
|
||||
'<span class="badge badge-center rounded-pill bg-label-primary w-px-30 h-px-30"><i class="ti ti-device-floppy ti-sm"></i></span>',
|
||||
'Past Due':
|
||||
'<span class="badge badge-center rounded-pill bg-label-danger w-px-30 h-px-30"><i class="ti ti-info-circle ti-sm"></i></span>',
|
||||
'Partial Payment':
|
||||
'<span class="badge badge-center rounded-pill bg-label-success w-px-30 h-px-30"><i class="ti ti-circle-half-2 ti-sm"></i></span>',
|
||||
Paid: '<span class="badge badge-center rounded-pill bg-label-warning w-px-30 h-px-30"><i class="ti ti-chart-pie ti-sm"></i></span>',
|
||||
Downloaded:
|
||||
'<span class="badge badge-center rounded-pill bg-label-info w-px-30 h-px-30"><i class="ti ti-arrow-down-circle ti-sm"></i></span>'
|
||||
};
|
||||
return (
|
||||
"<span data-bs-toggle='tooltip' data-bs-html='true' title='<span>" +
|
||||
$invoice_status +
|
||||
'<br> <strong>Balance:</strong> ' +
|
||||
$balance +
|
||||
'<br> <strong>Due Date:</strong> ' +
|
||||
$due_date +
|
||||
"</span>'>" +
|
||||
roleBadgeObj[$invoice_status] +
|
||||
'</span>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Total Invoice Amount
|
||||
targets: 3,
|
||||
render: function (data, type, full, meta) {
|
||||
var $total = full['total'];
|
||||
return '$' + $total;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
title: 'Actions',
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<div class="d-flex align-items-center">' +
|
||||
'<a href="javascript:;" class="text-body" data-bs-toggle="tooltip" title="Send Mail"><i class="ti ti-mail me-2 ti-sm"></i></a>' +
|
||||
'<a href="app-invoice-preview.html" class="text-body" data-bs-toggle="tooltip" title="Preview"><i class="ti ti-eye mx-2 ti-sm"></i></a>' +
|
||||
'<a href="javascript:;" class="text-body" data-bs-toggle="tooltip" title="Download"><i class="ti ti-dots-vertical mx-1 ti-sm"></i></a>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
dom:
|
||||
'<"row mx-4"' +
|
||||
'<"col-sm-6 col-12 d-flex align-items-center justify-content-center justify-content-sm-start mb-3 mb-md-0"l>' +
|
||||
'<"col-sm-6 col-12 d-flex align-items-center justify-content-center justify-content-sm-end"B>' +
|
||||
'>t' +
|
||||
'<"row mx-4"' +
|
||||
'<"col-md-12 col-lg-6 text-center text-lg-start pb-md-2 pb-lg-0"i>' +
|
||||
'<"col-md-12 col-lg-6 d-flex justify-content-center justify-content-lg-end"p>' +
|
||||
'>',
|
||||
language: {
|
||||
sLengthMenu: 'Show _MENU_',
|
||||
search: '',
|
||||
searchPlaceholder: 'Search Invoice'
|
||||
},
|
||||
// Buttons with Dropdown
|
||||
buttons: [
|
||||
{
|
||||
extend: 'collection',
|
||||
className: 'btn btn-label-secondary dropdown-toggle float-sm-end mb-3 mb-sm-0',
|
||||
text: '<i class="ti ti-screen-share ti-xs me-2"></i>Export',
|
||||
buttons: [
|
||||
{
|
||||
extend: 'print',
|
||||
text: '<i class="ti ti-printer me-2" ></i>Print',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: { columns: [1, 2, 3, 4] }
|
||||
},
|
||||
{
|
||||
extend: 'csv',
|
||||
text: '<i class="ti ti-file-text me-2" ></i>Csv',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: { columns: [1, 2, 3, 4] }
|
||||
},
|
||||
{
|
||||
extend: 'excel',
|
||||
text: '<i class="ti ti-file-spreadsheet me-2"></i>Excel',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: { columns: [1, 2, 3, 4] }
|
||||
},
|
||||
{
|
||||
extend: 'pdf',
|
||||
text: '<i class="ti ti-file-description me-2"></i>Pdf',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: { columns: [1, 2, 3, 4] }
|
||||
},
|
||||
{
|
||||
extend: 'copy',
|
||||
text: '<i class="ti ti-copy me-2" ></i>Copy',
|
||||
className: 'dropdown-item',
|
||||
exportOptions: { columns: [1, 2, 3, 4] }
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// On each datatable draw, initialize tooltip
|
||||
dt_invoice_table.on('draw.dt', function () {
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl, {
|
||||
boundary: document.body
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
});
|
||||
@ -1,57 +0,0 @@
|
||||
/**
|
||||
* App User View - Billing
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
// Cancel Subscription alert
|
||||
const cancelSubscription = document.querySelector('.cancel-subscription');
|
||||
|
||||
// Alert With Functional Confirm Button
|
||||
if (cancelSubscription) {
|
||||
cancelSubscription.onclick = function () {
|
||||
Swal.fire({
|
||||
text: 'Are you sure you would like to cancel your subscription?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-2',
|
||||
cancelButton: 'btn btn-label-secondary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Unsubscribed!',
|
||||
text: 'Your subscription cancelled successfully.',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
});
|
||||
} else if (result.dismiss === Swal.DismissReason.cancel) {
|
||||
Swal.fire({
|
||||
title: 'Cancelled',
|
||||
text: 'Unsubscription Cancelled!!',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// On edit address click, update text of add address modal
|
||||
const addressEdit = document.querySelector('.edit-address'),
|
||||
addressTitle = document.querySelector('.address-title'),
|
||||
addressSubTitle = document.querySelector('.address-subtitle');
|
||||
|
||||
addressEdit.onclick = function () {
|
||||
addressTitle.innerHTML = 'Edit Address'; // reset text
|
||||
addressSubTitle.innerHTML = 'Edit your current address';
|
||||
};
|
||||
})();
|
||||
@ -1,63 +0,0 @@
|
||||
/**
|
||||
* App User View - Security
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
const formChangePass = document.querySelector('#formChangePassword');
|
||||
|
||||
// Form validation for Change password
|
||||
if (formChangePass) {
|
||||
const fv = FormValidation.formValidation(formChangePass, {
|
||||
fields: {
|
||||
newPassword: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter new password'
|
||||
},
|
||||
stringLength: {
|
||||
min: 8,
|
||||
message: 'Password must be more than 8 characters'
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmPassword: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please confirm new password'
|
||||
},
|
||||
identical: {
|
||||
compare: function () {
|
||||
return formChangePass.querySelector('[name="newPassword"]').value;
|
||||
},
|
||||
message: 'The password and its confirm are not the same'
|
||||
},
|
||||
stringLength: {
|
||||
min: 8,
|
||||
message: 'Password must be more than 8 characters'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
trigger: new FormValidation.plugins.Trigger(),
|
||||
bootstrap5: new FormValidation.plugins.Bootstrap5({
|
||||
eleValidClass: '',
|
||||
rowSelector: '.form-password-toggle'
|
||||
}),
|
||||
submitButton: new FormValidation.plugins.SubmitButton(),
|
||||
// Submit the form when all fields are valid
|
||||
// defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
|
||||
autoFocus: new FormValidation.plugins.AutoFocus()
|
||||
},
|
||||
init: instance => {
|
||||
instance.on('plugins.message.placed', function (e) {
|
||||
if (e.element.parentElement.classList.contains('input-group')) {
|
||||
e.element.parentElement.insertAdjacentElement('afterend', e.messageElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -1,89 +0,0 @@
|
||||
/**
|
||||
* App User View - Suspend User Script
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
const suspendUser = document.querySelector('.suspend-user');
|
||||
|
||||
// Suspend User javascript
|
||||
if (suspendUser) {
|
||||
suspendUser.onclick = function () {
|
||||
Swal.fire({
|
||||
title: 'Are you sure?',
|
||||
text: "You won't be able to revert user!",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes, Suspend user!',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-2',
|
||||
cancelButton: 'btn btn-label-secondary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Suspended!',
|
||||
text: 'User has been suspended.',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
});
|
||||
} else if (result.dismiss === Swal.DismissReason.cancel) {
|
||||
Swal.fire({
|
||||
title: 'Cancelled',
|
||||
text: 'Cancelled Suspension :)',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
//? Billing page have multiple buttons
|
||||
// Cancel Subscription alert
|
||||
const cancelSubscription = document.querySelectorAll('.cancel-subscription');
|
||||
|
||||
// Alert With Functional Confirm Button
|
||||
if (cancelSubscription) {
|
||||
cancelSubscription.forEach(btnCancle => {
|
||||
btnCancle.onclick = function () {
|
||||
Swal.fire({
|
||||
text: 'Are you sure you would like to cancel your subscription?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Yes',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-primary me-2',
|
||||
cancelButton: 'btn btn-label-secondary'
|
||||
},
|
||||
buttonsStyling: false
|
||||
}).then(function (result) {
|
||||
if (result.value) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Unsubscribed!',
|
||||
text: 'Your subscription cancelled successfully.',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
});
|
||||
} else if (result.dismiss === Swal.DismissReason.cancel) {
|
||||
Swal.fire({
|
||||
title: 'Cancelled',
|
||||
text: 'Unsubscription Cancelled!!',
|
||||
icon: 'error',
|
||||
customClass: {
|
||||
confirmButton: 'btn btn-success'
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -1,114 +0,0 @@
|
||||
/**
|
||||
* Cards Actions
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
const collapseElementList = [].slice.call(document.querySelectorAll('.card-collapsible'));
|
||||
const expandElementList = [].slice.call(document.querySelectorAll('.card-expand'));
|
||||
const closeElementList = [].slice.call(document.querySelectorAll('.card-close'));
|
||||
|
||||
let cardDnD = document.getElementById('sortable-4');
|
||||
|
||||
// Collapsible card
|
||||
// --------------------------------------------------------------------
|
||||
if (collapseElementList) {
|
||||
collapseElementList.map(function (collapseElement) {
|
||||
collapseElement.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
// Collapse the element
|
||||
new bootstrap.Collapse(collapseElement.closest('.card').querySelector('.collapse'));
|
||||
// Toggle collapsed class in `.card-header` element
|
||||
collapseElement.closest('.card-header').classList.toggle('collapsed');
|
||||
// Toggle class ti-chevron-down & ti-chevron-right
|
||||
Helpers._toggleClass(collapseElement.firstElementChild, 'ti-chevron-down', 'ti-chevron-right');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Card Toggle fullscreen
|
||||
// --------------------------------------------------------------------
|
||||
if (expandElementList) {
|
||||
expandElementList.map(function (expandElement) {
|
||||
expandElement.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
// Toggle class ti-arrows-maximize & ti-arrows-minimize
|
||||
Helpers._toggleClass(expandElement.firstElementChild, 'ti-arrows-maximize', 'ti-arrows-minimize');
|
||||
|
||||
expandElement.closest('.card').classList.toggle('card-fullscreen');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Toggle fullscreen on esc key
|
||||
document.addEventListener('keyup', event => {
|
||||
event.preventDefault();
|
||||
//Esc button
|
||||
if (event.key === 'Escape') {
|
||||
const cardFullscreen = document.querySelector('.card-fullscreen');
|
||||
// Toggle class ti-arrows-maximize & ti-arrows-minimize
|
||||
|
||||
if (cardFullscreen) {
|
||||
Helpers._toggleClass(cardFullscreen.querySelector('.card-expand').firstChild, 'ti-arrows-maximize', 'ti-arrows-minimize');
|
||||
cardFullscreen.classList.toggle('card-fullscreen');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Card close
|
||||
// --------------------------------------------------------------------
|
||||
if (closeElementList) {
|
||||
closeElementList.map(function (closeElement) {
|
||||
closeElement.addEventListener('click', event => {
|
||||
event.preventDefault();
|
||||
closeElement.closest('.card').classList.add('d-none');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Sortable.js (Drag & Drop cards)
|
||||
// --------------------------------------------------------------------
|
||||
if (typeof cardDnD !== undefined && cardDnD !== null) {
|
||||
Sortable.create(cardDnD, {
|
||||
animation: 500,
|
||||
handle: '.card'
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
// Card reload (jquery)
|
||||
// --------------------------------------------------------------------
|
||||
$(function () {
|
||||
const cardReload = $('.card-reload');
|
||||
if (cardReload.length) {
|
||||
cardReload.on('click', function (e) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
$this.closest('.card').block({
|
||||
message:
|
||||
'<div class="sk-fold sk-primary"><div class="sk-fold-cube"></div><div class="sk-fold-cube"></div><div class="sk-fold-cube"></div><div class="sk-fold-cube"></div></div><h5>LOADING...</h5>',
|
||||
|
||||
css: {
|
||||
backgroundColor: 'transparent',
|
||||
border: '0'
|
||||
},
|
||||
overlayCSS: {
|
||||
backgroundColor: $('html').hasClass('dark-style') ? '#000' : '#fff',
|
||||
opacity: 0.55
|
||||
}
|
||||
});
|
||||
setTimeout(function () {
|
||||
$this.closest('.card').unblock();
|
||||
if ($this.closest('.card').find('.card-alert').length) {
|
||||
$this
|
||||
.closest('.card')
|
||||
.find('.card-alert')
|
||||
.html(
|
||||
'<div class="alert alert-danger alert-dismissible fade show" role="alert"><button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button><strong>Holy grail!</strong> Your success/error message here.</div>'
|
||||
);
|
||||
}
|
||||
}, 2500);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,166 +0,0 @@
|
||||
/**
|
||||
* Advanced Cards
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
let cardColor, headingColor, legendColor, labelColor;
|
||||
if (isDarkStyle) {
|
||||
cardColor = config.colors_dark.cardColor;
|
||||
labelColor = config.colors_dark.textMuted;
|
||||
legendColor = config.colors_dark.bodyColor;
|
||||
headingColor = config.colors_dark.headingColor;
|
||||
} else {
|
||||
cardColor = config.colors.cardColor;
|
||||
labelColor = config.colors.textMuted;
|
||||
legendColor = config.colors.bodyColor;
|
||||
headingColor = config.colors.headingColor;
|
||||
}
|
||||
|
||||
// Radial bar chart functions
|
||||
function radialBarChart(color, value) {
|
||||
const radialBarChartOpt = {
|
||||
chart: {
|
||||
height: 53,
|
||||
width: 43,
|
||||
type: 'radialBar'
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: {
|
||||
size: '33%'
|
||||
},
|
||||
dataLabels: {
|
||||
show: false
|
||||
},
|
||||
track: {
|
||||
background: config.colors_label.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
lineCap: 'round'
|
||||
},
|
||||
colors: [color],
|
||||
grid: {
|
||||
padding: {
|
||||
top: -15,
|
||||
bottom: -15,
|
||||
left: -5,
|
||||
right: -15
|
||||
}
|
||||
},
|
||||
series: [value],
|
||||
labels: ['Progress']
|
||||
};
|
||||
return radialBarChartOpt;
|
||||
}
|
||||
|
||||
// Progress Chart
|
||||
// --------------------------------------------------------------------
|
||||
// All progress chart
|
||||
const chartProgressList = document.querySelectorAll('.chart-progress');
|
||||
if (chartProgressList) {
|
||||
chartProgressList.forEach(function (chartProgressEl) {
|
||||
const color = config.colors[chartProgressEl.dataset.color],
|
||||
series = chartProgressEl.dataset.series;
|
||||
const optionsBundle = radialBarChart(color, series);
|
||||
const chart = new ApexCharts(chartProgressEl, optionsBundle);
|
||||
chart.render();
|
||||
});
|
||||
}
|
||||
|
||||
// Earning Reports Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const reportBarChartEl = document.querySelector('#reportBarChart'),
|
||||
reportBarChartConfig = {
|
||||
chart: {
|
||||
height: 200,
|
||||
type: 'bar',
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '60%',
|
||||
columnWidth: '60%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 4,
|
||||
distributed: true
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -20,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10
|
||||
}
|
||||
},
|
||||
colors: [
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [40, 95, 60, 45, 90, 50, 75]
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
};
|
||||
if (typeof reportBarChartEl !== undefined && reportBarChartEl !== null) {
|
||||
const barChart = new ApexCharts(reportBarChartEl, reportBarChartConfig);
|
||||
barChart.render();
|
||||
}
|
||||
|
||||
// swiper loop and autoplay
|
||||
// --------------------------------------------------------------------
|
||||
const swiperWithPagination = document.querySelector('#swiper-with-pagination-cards');
|
||||
if (swiperWithPagination) {
|
||||
new Swiper(swiperWithPagination, {
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 2500,
|
||||
disableOnInteraction: false
|
||||
},
|
||||
pagination: {
|
||||
clickable: true,
|
||||
el: '.swiper-pagination'
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
@ -1,113 +0,0 @@
|
||||
/**
|
||||
* Config
|
||||
* -------------------------------------------------------------------------------------
|
||||
* ! IMPORTANT: Make sure you clear the browser local storage In order to see the config changes in the template.
|
||||
* ! To clear local storage: (https://www.leadshook.com/help/how-to-clear-local-storage-in-google-chrome-browser/).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// JS global variables
|
||||
let config = {
|
||||
colors: {
|
||||
primary: '#7367f0',
|
||||
secondary: '#a8aaae',
|
||||
success: '#28c76f',
|
||||
info: '#00cfe8',
|
||||
warning: '#ff9f43',
|
||||
danger: '#ea5455',
|
||||
dark: '#4b4b4b',
|
||||
black: '#000',
|
||||
white: '#fff',
|
||||
cardColor: '#fff',
|
||||
bodyBg: '#f8f7fa',
|
||||
bodyColor: '#6f6b7d',
|
||||
headingColor: '#5d596c',
|
||||
textMuted: '#a5a3ae',
|
||||
borderColor: '#dbdade'
|
||||
},
|
||||
colors_label: {
|
||||
primary: '#7367f029',
|
||||
secondary: '#a8aaae29',
|
||||
success: '#28c76f29',
|
||||
info: '#00cfe829',
|
||||
warning: '#ff9f4329',
|
||||
danger: '#ea545529',
|
||||
dark: '#4b4b4b29'
|
||||
},
|
||||
colors_dark: {
|
||||
cardColor: '#2f3349',
|
||||
bodyBg: '#25293c',
|
||||
bodyColor: '#b6bee3',
|
||||
headingColor: '#cfd3ec',
|
||||
textMuted: '#7983bb',
|
||||
borderColor: '#434968'
|
||||
},
|
||||
enableMenuLocalStorage: true // Enable menu state with local storage support
|
||||
};
|
||||
|
||||
let assetsPath = document.documentElement.getAttribute('data-assets-path'),
|
||||
templateName = document.documentElement.getAttribute('data-template'),
|
||||
rtlSupport = true; // set true for rtl support (rtl + ltr), false for ltr only.
|
||||
|
||||
/**
|
||||
* TemplateCustomizer
|
||||
* ! You must use(include) template-customizer.js to use TemplateCustomizer settings
|
||||
* -----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// To use more themes, just push it to THEMES object.
|
||||
|
||||
/* TemplateCustomizer.THEMES.push({
|
||||
name: 'theme-raspberry',
|
||||
title: 'Raspberry'
|
||||
}); */
|
||||
|
||||
// To add more languages, just push it to LANGUAGES object.
|
||||
/*
|
||||
TemplateCustomizer.LANGUAGES.fr = { ... };
|
||||
*/
|
||||
|
||||
/**
|
||||
* TemplateCustomizer settings
|
||||
* -------------------------------------------------------------------------------------
|
||||
* cssPath: Core CSS file path
|
||||
* themesPath: Theme CSS file path
|
||||
* displayCustomizer: true(Show customizer), false(Hide customizer)
|
||||
* lang: To set default language, Add more langues and set default. Fallback language is 'en'
|
||||
* controls: [ 'rtl','style','layoutType','showDropdownOnHover','layoutNavbarFixed','layoutFooterFixed','themes'] | Show/Hide customizer controls
|
||||
* defaultTheme: 0(Default), 1(Semi Dark), 2(Bordered)
|
||||
* defaultStyle: 'light', 'dark' (Mode)
|
||||
* defaultTextDir: 'ltr', 'rtl' (rtlSupport must be true for rtl mode)
|
||||
* defaultLayoutType: 'static', 'fixed'
|
||||
* defaultMenuCollapsed: true, false
|
||||
* defaultNavbarFixed: true, false
|
||||
* defaultFooterFixed: true, false
|
||||
* defaultShowDropdownOnHover : true, false (for horizontal layout only)
|
||||
*/
|
||||
|
||||
if (typeof TemplateCustomizer !== 'undefined') {
|
||||
window.templateCustomizer = new TemplateCustomizer({
|
||||
cssPath: assetsPath + 'vendor/css' + (rtlSupport ? '/rtl' : '') + '/',
|
||||
themesPath: assetsPath + 'vendor/css' + (rtlSupport ? '/rtl' : '') + '/',
|
||||
displayCustomizer: true,
|
||||
// lang: 'fr',
|
||||
// defaultTheme: 2,
|
||||
// defaultStyle: 'light',
|
||||
// defaultTextDir: 'ltr',
|
||||
// defaultLayoutType: 'fixed',
|
||||
// defaultMenuCollapsed: true,
|
||||
// defaultNavbarFixed: true,
|
||||
// defaultFooterFixed: false
|
||||
defaultShowDropdownOnHover: true
|
||||
// controls: [
|
||||
// 'rtl',
|
||||
// 'style',
|
||||
// 'layoutType',
|
||||
// 'showDropdownOnHover',
|
||||
// 'layoutNavbarFixed',
|
||||
// 'layoutFooterFixed',
|
||||
// 'themes'
|
||||
// ],
|
||||
});
|
||||
}
|
||||
@ -1,662 +0,0 @@
|
||||
/**
|
||||
* Dashboard Analytics
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
let cardColor, headingColor, labelColor, shadeColor, grayColor;
|
||||
if (isDarkStyle) {
|
||||
cardColor = config.colors_dark.cardColor;
|
||||
labelColor = config.colors_dark.textMuted;
|
||||
headingColor = config.colors_dark.headingColor;
|
||||
shadeColor = 'dark';
|
||||
grayColor = '#5E6692'; // gray color is for stacked bar chart
|
||||
} else {
|
||||
cardColor = config.colors.cardColor;
|
||||
labelColor = config.colors.textMuted;
|
||||
headingColor = config.colors.headingColor;
|
||||
shadeColor = '';
|
||||
grayColor = '#817D8D';
|
||||
}
|
||||
|
||||
// swiper loop and autoplay
|
||||
// --------------------------------------------------------------------
|
||||
const swiperWithPagination = document.querySelector('#swiper-with-pagination-cards');
|
||||
if (swiperWithPagination) {
|
||||
new Swiper(swiperWithPagination, {
|
||||
loop: true,
|
||||
autoplay: {
|
||||
delay: 2500,
|
||||
disableOnInteraction: false
|
||||
},
|
||||
pagination: {
|
||||
clickable: true,
|
||||
el: '.swiper-pagination'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Revenue Generated Area Chart
|
||||
// --------------------------------------------------------------------
|
||||
const revenueGeneratedEl = document.querySelector('#revenueGenerated'),
|
||||
revenueGeneratedConfig = {
|
||||
chart: {
|
||||
height: 130,
|
||||
type: 'area',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: {
|
||||
show: false
|
||||
},
|
||||
sparkline: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
markers: {
|
||||
colors: 'transparent',
|
||||
strokeColors: 'transparent'
|
||||
},
|
||||
grid: {
|
||||
show: false
|
||||
},
|
||||
colors: [config.colors.success],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shade: shadeColor,
|
||||
shadeIntensity: 0.8,
|
||||
opacityFrom: 0.6,
|
||||
opacityTo: 0.1
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
stroke: {
|
||||
width: 2,
|
||||
curve: 'smooth'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [300, 350, 330, 380, 340, 400, 380]
|
||||
}
|
||||
],
|
||||
xaxis: {
|
||||
show: true,
|
||||
lines: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
stroke: {
|
||||
width: 0
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
stroke: {
|
||||
width: 0
|
||||
},
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
if (typeof revenueGeneratedEl !== undefined && revenueGeneratedEl !== null) {
|
||||
const revenueGenerated = new ApexCharts(revenueGeneratedEl, revenueGeneratedConfig);
|
||||
revenueGenerated.render();
|
||||
}
|
||||
|
||||
// Earning Reports Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const weeklyEarningReportsEl = document.querySelector('#weeklyEarningReports'),
|
||||
weeklyEarningReportsConfig = {
|
||||
chart: {
|
||||
height: 202,
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '60%',
|
||||
columnWidth: '38%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 4,
|
||||
distributed: true
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -30,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10
|
||||
}
|
||||
},
|
||||
colors: [
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [40, 65, 50, 45, 90, 55, 70]
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: {
|
||||
height: 199
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof weeklyEarningReportsEl !== undefined && weeklyEarningReportsEl !== null) {
|
||||
const weeklyEarningReports = new ApexCharts(weeklyEarningReportsEl, weeklyEarningReportsConfig);
|
||||
weeklyEarningReports.render();
|
||||
}
|
||||
|
||||
// Support Tracker - Radial Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const supportTrackerEl = document.querySelector('#supportTracker'),
|
||||
supportTrackerOptions = {
|
||||
series: [85],
|
||||
labels: ['Completed Task'],
|
||||
chart: {
|
||||
height: 360,
|
||||
type: 'radialBar'
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
offsetY: 10,
|
||||
startAngle: -140,
|
||||
endAngle: 130,
|
||||
hollow: {
|
||||
size: '65%'
|
||||
},
|
||||
track: {
|
||||
background: cardColor,
|
||||
strokeWidth: '100%'
|
||||
},
|
||||
dataLabels: {
|
||||
name: {
|
||||
offsetY: -20,
|
||||
color: labelColor,
|
||||
fontSize: '13px',
|
||||
fontWeight: '400',
|
||||
fontFamily: 'Public Sans'
|
||||
},
|
||||
value: {
|
||||
offsetY: 10,
|
||||
color: headingColor,
|
||||
fontSize: '38px',
|
||||
fontWeight: '600',
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: [config.colors.primary],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shade: 'dark',
|
||||
shadeIntensity: 0.5,
|
||||
gradientToColors: [config.colors.primary],
|
||||
inverseColors: true,
|
||||
opacityFrom: 1,
|
||||
opacityTo: 0.6,
|
||||
stops: [30, 70, 100]
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
dashArray: 10
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
top: -20,
|
||||
bottom: 5
|
||||
}
|
||||
},
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
},
|
||||
active: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: {
|
||||
height: 330
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
options: {
|
||||
chart: {
|
||||
height: 280
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof supportTrackerEl !== undefined && supportTrackerEl !== null) {
|
||||
const supportTracker = new ApexCharts(supportTrackerEl, supportTrackerOptions);
|
||||
supportTracker.render();
|
||||
}
|
||||
|
||||
// Total Earning Chart - Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const totalEarningChartEl = document.querySelector('#totalEarningChart'),
|
||||
totalEarningChartOptions = {
|
||||
series: [
|
||||
{
|
||||
name: 'Earning',
|
||||
data: [15, 10, 20, 8, 12, 18, 12, 5]
|
||||
},
|
||||
{
|
||||
name: 'Expense',
|
||||
data: [-7, -10, -7, -12, -6, -9, -5, -8]
|
||||
}
|
||||
],
|
||||
chart: {
|
||||
height: 230,
|
||||
parentHeightOffset: 0,
|
||||
stacked: true,
|
||||
type: 'bar',
|
||||
toolbar: { show: false }
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '18%',
|
||||
borderRadius: 5,
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded'
|
||||
}
|
||||
},
|
||||
colors: [config.colors.primary, grayColor],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -40,
|
||||
bottom: -20,
|
||||
left: -10,
|
||||
right: -2
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1468,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '22%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1197,
|
||||
options: {
|
||||
chart: {
|
||||
height: 228
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 8,
|
||||
columnWidth: '26%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 783,
|
||||
options: {
|
||||
chart: {
|
||||
height: 232
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '28%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 589,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '16%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 520,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '18%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 426,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 5,
|
||||
columnWidth: '20%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 381,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '24%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
},
|
||||
active: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (typeof totalEarningChartEl !== undefined && totalEarningChartEl !== null) {
|
||||
const totalEarningChart = new ApexCharts(totalEarningChartEl, totalEarningChartOptions);
|
||||
totalEarningChart.render();
|
||||
}
|
||||
|
||||
// For Datatable
|
||||
// --------------------------------------------------------------------
|
||||
var dt_projects_table = $('.datatables-projects');
|
||||
|
||||
if (dt_projects_table.length) {
|
||||
var dt_project = dt_projects_table.DataTable({
|
||||
ajax: assetsPath + 'json/user-profile.json',
|
||||
columns: [
|
||||
{ data: '' },
|
||||
{ data: 'id' },
|
||||
{ data: 'project_name' },
|
||||
{ data: 'project_leader' },
|
||||
{ data: '' },
|
||||
{ data: 'status' },
|
||||
{ data: '' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
searchable: false,
|
||||
orderable: false,
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// For Checkboxes
|
||||
targets: 1,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
responsivePriority: 3,
|
||||
checkboxes: true,
|
||||
render: function () {
|
||||
return '<input type="checkbox" class="dt-checkboxes form-check-input">';
|
||||
},
|
||||
checkboxes: {
|
||||
selectAllRender: '<input type="checkbox" class="form-check-input">'
|
||||
}
|
||||
},
|
||||
{
|
||||
// Avatar image/badge, Name and post
|
||||
targets: 2,
|
||||
responsivePriority: 4,
|
||||
render: function (data, type, full, meta) {
|
||||
var $user_img = full['project_img'],
|
||||
$name = full['project_name'],
|
||||
$date = full['date'];
|
||||
if ($user_img) {
|
||||
// For Avatar image
|
||||
var $output =
|
||||
'<img src="' + assetsPath + 'img/icons/brands/' + $user_img + '" alt="Avatar" class="rounded-circle">';
|
||||
} else {
|
||||
// For Avatar badge
|
||||
var stateNum = Math.floor(Math.random() * 6);
|
||||
var states = ['success', 'danger', 'warning', 'info', 'primary', 'secondary'];
|
||||
var $state = states[stateNum],
|
||||
$name = full['project_name'],
|
||||
$initials = $name.match(/\b\w/g) || [];
|
||||
$initials = (($initials.shift() || '') + ($initials.pop() || '')).toUpperCase();
|
||||
$output = '<span class="avatar-initial rounded-circle bg-label-' + $state + '">' + $initials + '</span>';
|
||||
}
|
||||
// Creates full output for row
|
||||
var $row_output =
|
||||
'<div class="d-flex justify-content-left align-items-center">' +
|
||||
'<div class="avatar-wrapper">' +
|
||||
'<div class="avatar me-2">' +
|
||||
$output +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="d-flex flex-column">' +
|
||||
'<span class="text-truncate fw-semibold">' +
|
||||
$name +
|
||||
'</span>' +
|
||||
'<small class="text-truncate text-muted">' +
|
||||
$date +
|
||||
'</small>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Teams
|
||||
targets: 4,
|
||||
orderable: false,
|
||||
searchable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
var $team = full['team'],
|
||||
$output;
|
||||
$output = '<div class="d-flex align-items-center avatar-group">';
|
||||
for (var i = 0; i < $team.length; i++) {
|
||||
$output +=
|
||||
'<div class="avatar avatar-sm">' +
|
||||
'<img src="' +
|
||||
assetsPath +
|
||||
'img/avatars/' +
|
||||
$team[i] +
|
||||
'" alt="Avatar" class="rounded-circle pull-up">' +
|
||||
'</div>';
|
||||
}
|
||||
$output += '</div>';
|
||||
return $output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Label
|
||||
targets: -2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $status_number = full['status'];
|
||||
return (
|
||||
'<div class="d-flex align-items-center">' +
|
||||
'<div class="progress w-100 me-3" style="height: 6px;">' +
|
||||
'<div class="progress-bar" style="width: ' +
|
||||
$status_number +
|
||||
'" aria-valuenow="' +
|
||||
$status_number +
|
||||
'" aria-valuemin="0" aria-valuemax="100"></div>' +
|
||||
'</div>' +
|
||||
'<span>' +
|
||||
$status_number +
|
||||
'</span></div>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
searchable: false,
|
||||
title: 'Actions',
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<div class="d-inline-block">' +
|
||||
'<a href="javascript:;" class="btn btn-sm btn-icon dropdown-toggle hide-arrow" data-bs-toggle="dropdown"><i class="ti ti-dots-vertical"></i></a>' +
|
||||
'<div class="dropdown-menu dropdown-menu-end m-0">' +
|
||||
'<a href="javascript:;" class="dropdown-item">Details</a>' +
|
||||
'<a href="javascript:;" class="dropdown-item">Archive</a>' +
|
||||
'<div class="dropdown-divider"></div>' +
|
||||
'<a href="javascript:;" class="dropdown-item text-danger delete-record">Delete</a>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
}
|
||||
],
|
||||
order: [[2, 'desc']],
|
||||
dom: '<"card-header pb-0 pt-sm-0"<"head-label text-center"><"d-flex justify-content-center justify-content-md-end"f>>t<"row mx-2"<"col-sm-12 col-md-6"i><"col-sm-12 col-md-6"p>>',
|
||||
displayLength: 5,
|
||||
lengthMenu: [5, 10, 25, 50, 75, 100],
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of "' + data['project_name'] + '" Project';
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$('div.head-label').html('<h5 class="card-title mb-0">Projects</h5>');
|
||||
}
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
})();
|
||||
@ -1,859 +0,0 @@
|
||||
/**
|
||||
* Dashboard CRM
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
(function () {
|
||||
let cardColor, labelColor, shadeColor, legendColor, borderColor;
|
||||
if (isDarkStyle) {
|
||||
cardColor = config.colors_dark.cardColor;
|
||||
labelColor = config.colors_dark.textMuted;
|
||||
legendColor = config.colors_dark.bodyColor;
|
||||
borderColor = config.colors_dark.borderColor;
|
||||
shadeColor = 'dark';
|
||||
} else {
|
||||
cardColor = config.colors.cardColor;
|
||||
labelColor = config.colors.textMuted;
|
||||
legendColor = config.colors.bodyColor;
|
||||
borderColor = config.colors.borderColor;
|
||||
shadeColor = '';
|
||||
}
|
||||
|
||||
// Sales last year Area Chart
|
||||
// --------------------------------------------------------------------
|
||||
const salesLastYearEl = document.querySelector('#salesLastYear'),
|
||||
salesLastYearConfig = {
|
||||
chart: {
|
||||
height: 78,
|
||||
type: 'area',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: {
|
||||
show: false
|
||||
},
|
||||
sparkline: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
markers: {
|
||||
colors: 'transparent',
|
||||
strokeColors: 'transparent'
|
||||
},
|
||||
grid: {
|
||||
show: false
|
||||
},
|
||||
colors: [config.colors.success],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
shade: shadeColor,
|
||||
shadeIntensity: 0.8,
|
||||
opacityFrom: 0.6,
|
||||
opacityTo: 0.25
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
stroke: {
|
||||
width: 2,
|
||||
curve: 'smooth'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [200, 55, 400, 250]
|
||||
}
|
||||
],
|
||||
xaxis: {
|
||||
show: true,
|
||||
lines: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
stroke: {
|
||||
width: 0
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
stroke: {
|
||||
width: 0
|
||||
},
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
if (typeof salesLastYearEl !== undefined && salesLastYearEl !== null) {
|
||||
const salesLastYear = new ApexCharts(salesLastYearEl, salesLastYearConfig);
|
||||
salesLastYear.render();
|
||||
}
|
||||
|
||||
// Sessions Last Month - Staked Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const sessionsLastMonthEl = document.querySelector('#sessionsLastMonth'),
|
||||
sessionsLastMonthConfig = {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 78,
|
||||
parentHeightOffset: 0,
|
||||
stacked: true,
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'PRODUCT A',
|
||||
data: [4, 3, 6, 4, 3]
|
||||
},
|
||||
{
|
||||
name: 'PRODUCT B',
|
||||
data: [-3, -4, -3, -2, -3]
|
||||
}
|
||||
],
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '30%',
|
||||
barHeight: '100%',
|
||||
borderRadius: 5,
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded'
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: 1,
|
||||
lineCap: 'round',
|
||||
colors: [cardColor]
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
colors: [config.colors.primary, config.colors.success],
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -41,
|
||||
right: -10,
|
||||
left: -8,
|
||||
bottom: -22
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
show: false
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1300,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '50%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1200,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '20%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6,
|
||||
columnWidth: '20%'
|
||||
}
|
||||
},
|
||||
chart: {
|
||||
height: 80
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 900,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 782,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '30%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 426,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 5,
|
||||
columnWidth: '35%'
|
||||
}
|
||||
},
|
||||
chart: {
|
||||
height: 78
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 376,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
},
|
||||
active: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (typeof sessionsLastMonthEl !== undefined && sessionsLastMonthEl !== null) {
|
||||
const sessionsLastMonth = new ApexCharts(sessionsLastMonthEl, sessionsLastMonthConfig);
|
||||
sessionsLastMonth.render();
|
||||
}
|
||||
|
||||
// Revenue Growth Chart
|
||||
// --------------------------------------------------------------------
|
||||
const revenueGrowthEl = document.querySelector('#revenueGrowth'),
|
||||
revenueGrowthConfig = {
|
||||
chart: {
|
||||
height: 170,
|
||||
type: 'bar',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '80%',
|
||||
columnWidth: '30%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 6,
|
||||
distributed: true
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -20,
|
||||
bottom: -12,
|
||||
left: -10,
|
||||
right: 0
|
||||
}
|
||||
},
|
||||
colors: [
|
||||
config.colors_label.success,
|
||||
config.colors_label.success,
|
||||
config.colors_label.success,
|
||||
config.colors_label.success,
|
||||
config.colors.success,
|
||||
config.colors_label.success,
|
||||
config.colors_label.success
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [25, 40, 55, 70, 85, 70, 55]
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['M', 'T', 'W', 'T', 'F', 'S', 'S'],
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1471,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '50%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1350,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '57%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1032,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '60%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 992,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40%',
|
||||
borderRadius: 8
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 855,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '50%',
|
||||
borderRadius: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 440,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '40%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 381,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '45%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof revenueGrowthEl !== undefined && revenueGrowthEl !== null) {
|
||||
const revenueGrowth = new ApexCharts(revenueGrowthEl, revenueGrowthConfig);
|
||||
revenueGrowth.render();
|
||||
}
|
||||
|
||||
// Earning Reports Tabs Function
|
||||
function EarningReportsBarChart(arrayData, highlightData) {
|
||||
const basicColor = config.colors_label.primary,
|
||||
highlightColor = config.colors.primary;
|
||||
var colorArr = [];
|
||||
|
||||
for (let i = 0; i < arrayData.length; i++) {
|
||||
if (i === highlightData) {
|
||||
colorArr.push(highlightColor);
|
||||
} else {
|
||||
colorArr.push(basicColor);
|
||||
}
|
||||
}
|
||||
|
||||
const earningReportBarChartOpt = {
|
||||
chart: {
|
||||
height: 258,
|
||||
parentHeightOffset: 0,
|
||||
type: 'bar',
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '32%',
|
||||
startingShape: 'rounded',
|
||||
borderRadius: 7,
|
||||
distributed: true,
|
||||
dataLabels: {
|
||||
position: 'top'
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10
|
||||
}
|
||||
},
|
||||
colors: colorArr,
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter: function (val) {
|
||||
return val + 'k';
|
||||
},
|
||||
offsetY: -25,
|
||||
style: {
|
||||
fontSize: '15px',
|
||||
colors: [legendColor],
|
||||
fontWeight: '600',
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: arrayData
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
|
||||
axisBorder: {
|
||||
show: true,
|
||||
color: borderColor
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -15,
|
||||
formatter: function (val) {
|
||||
return '$' + parseInt(val / 1) + 'k';
|
||||
},
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans'
|
||||
},
|
||||
min: 0,
|
||||
max: 60000,
|
||||
tickAmount: 6
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '41%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 590,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '61%',
|
||||
borderRadius: 5
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
right: 0,
|
||||
left: -20
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
fontWeight: '400'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
return earningReportBarChartOpt;
|
||||
}
|
||||
var chartJson = 'earning-reports-charts.json';
|
||||
// Earning Chart JSON data
|
||||
var earningReportsChart = $.ajax({
|
||||
url: assetsPath + 'json/' + chartJson, //? Use your own search api instead
|
||||
dataType: 'json',
|
||||
async: false
|
||||
}).responseJSON;
|
||||
|
||||
// Earning Reports Tabs Orders
|
||||
// --------------------------------------------------------------------
|
||||
const earningReportsTabsOrdersEl = document.querySelector('#earningReportsTabsOrders'),
|
||||
earningReportsTabsOrdersConfig = EarningReportsBarChart(
|
||||
earningReportsChart['data'][0]['chart_data'],
|
||||
earningReportsChart['data'][0]['active_option']
|
||||
);
|
||||
if (typeof earningReportsTabsOrdersEl !== undefined && earningReportsTabsOrdersEl !== null) {
|
||||
const earningReportsTabsOrders = new ApexCharts(earningReportsTabsOrdersEl, earningReportsTabsOrdersConfig);
|
||||
earningReportsTabsOrders.render();
|
||||
}
|
||||
// Earning Reports Tabs Sales
|
||||
// --------------------------------------------------------------------
|
||||
const earningReportsTabsSalesEl = document.querySelector('#earningReportsTabsSales'),
|
||||
earningReportsTabsSalesConfig = EarningReportsBarChart(
|
||||
earningReportsChart['data'][1]['chart_data'],
|
||||
earningReportsChart['data'][1]['active_option']
|
||||
);
|
||||
if (typeof earningReportsTabsSalesEl !== undefined && earningReportsTabsSalesEl !== null) {
|
||||
const earningReportsTabsSales = new ApexCharts(earningReportsTabsSalesEl, earningReportsTabsSalesConfig);
|
||||
earningReportsTabsSales.render();
|
||||
}
|
||||
// Earning Reports Tabs Profit
|
||||
// --------------------------------------------------------------------
|
||||
const earningReportsTabsProfitEl = document.querySelector('#earningReportsTabsProfit'),
|
||||
earningReportsTabsProfitConfig = EarningReportsBarChart(
|
||||
earningReportsChart['data'][2]['chart_data'],
|
||||
earningReportsChart['data'][2]['active_option']
|
||||
);
|
||||
if (typeof earningReportsTabsProfitEl !== undefined && earningReportsTabsProfitEl !== null) {
|
||||
const earningReportsTabsProfit = new ApexCharts(earningReportsTabsProfitEl, earningReportsTabsProfitConfig);
|
||||
earningReportsTabsProfit.render();
|
||||
}
|
||||
// Earning Reports Tabs Income
|
||||
// --------------------------------------------------------------------
|
||||
const earningReportsTabsIncomeEl = document.querySelector('#earningReportsTabsIncome'),
|
||||
earningReportsTabsIncomeConfig = EarningReportsBarChart(
|
||||
earningReportsChart['data'][3]['chart_data'],
|
||||
earningReportsChart['data'][3]['active_option']
|
||||
);
|
||||
if (typeof earningReportsTabsIncomeEl !== undefined && earningReportsTabsIncomeEl !== null) {
|
||||
const earningReportsTabsIncome = new ApexCharts(earningReportsTabsIncomeEl, earningReportsTabsIncomeConfig);
|
||||
earningReportsTabsIncome.render();
|
||||
}
|
||||
|
||||
// Sales Last 6 Months - Radar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const salesLastMonthEl = document.querySelector('#salesLastMonth'),
|
||||
salesLastMonthConfig = {
|
||||
series: [
|
||||
{
|
||||
name: 'Sales',
|
||||
data: [32, 27, 27, 30, 25, 25]
|
||||
},
|
||||
{
|
||||
name: 'Visits',
|
||||
data: [25, 35, 20, 20, 20, 20]
|
||||
}
|
||||
],
|
||||
chart: {
|
||||
height: 340,
|
||||
type: 'radar',
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
radar: {
|
||||
polygons: {
|
||||
strokeColors: borderColor,
|
||||
connectorColors: borderColor
|
||||
}
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
show: false,
|
||||
width: 0
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
fontSize: '13px',
|
||||
position: 'bottom',
|
||||
labels: {
|
||||
colors: legendColor,
|
||||
useSeriesColors: false
|
||||
},
|
||||
markers: {
|
||||
height: 10,
|
||||
width: 10,
|
||||
offsetX: -3
|
||||
},
|
||||
itemMargin: {
|
||||
horizontal: 10
|
||||
},
|
||||
onItemHover: {
|
||||
highlightDataSeries: false
|
||||
}
|
||||
},
|
||||
colors: [config.colors.primary, config.colors.info],
|
||||
fill: {
|
||||
opacity: [1, 0.85]
|
||||
},
|
||||
markers: {
|
||||
size: 0
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: 0,
|
||||
bottom: -5
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
|
||||
labels: {
|
||||
show: true,
|
||||
style: {
|
||||
colors: [labelColor, labelColor, labelColor, labelColor, labelColor, labelColor],
|
||||
fontSize: '13px',
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
show: false,
|
||||
min: 0,
|
||||
max: 40,
|
||||
tickAmount: 4
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 769,
|
||||
options: {
|
||||
chart: {
|
||||
height: 400
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof salesLastMonthEl !== undefined && salesLastMonthEl !== null) {
|
||||
const salesLastMonth = new ApexCharts(salesLastMonthEl, salesLastMonthConfig);
|
||||
salesLastMonth.render();
|
||||
}
|
||||
|
||||
// Progress Chart
|
||||
// --------------------------------------------------------------------
|
||||
// Radial bar chart functions
|
||||
function radialBarChart(color, value) {
|
||||
const radialBarChartOpt = {
|
||||
chart: {
|
||||
height: 53,
|
||||
width: 43,
|
||||
type: 'radialBar'
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: {
|
||||
size: '33%'
|
||||
},
|
||||
dataLabels: {
|
||||
show: false
|
||||
},
|
||||
track: {
|
||||
background: config.colors_label.secondary
|
||||
}
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
lineCap: 'round'
|
||||
},
|
||||
colors: [color],
|
||||
grid: {
|
||||
padding: {
|
||||
top: -15,
|
||||
bottom: -15,
|
||||
left: -5,
|
||||
right: -15
|
||||
}
|
||||
},
|
||||
series: [value],
|
||||
labels: ['Progress']
|
||||
};
|
||||
return radialBarChartOpt;
|
||||
}
|
||||
// All progress chart
|
||||
const chartProgressList = document.querySelectorAll('.chart-progress');
|
||||
if (chartProgressList) {
|
||||
chartProgressList.forEach(function (chartProgressEl) {
|
||||
const color = config.colors[chartProgressEl.dataset.color],
|
||||
series = chartProgressEl.dataset.series;
|
||||
const optionsBundle = radialBarChart(color, series);
|
||||
const chart = new ApexCharts(chartProgressEl, optionsBundle);
|
||||
chart.render();
|
||||
});
|
||||
}
|
||||
|
||||
// Project Status - Line Chart
|
||||
// --------------------------------------------------------------------
|
||||
const projectStatusEl = document.querySelector('#projectStatusChart'),
|
||||
projectStatusConfig = {
|
||||
chart: {
|
||||
height: 240,
|
||||
type: 'area',
|
||||
toolbar: false
|
||||
},
|
||||
markers: {
|
||||
strokeColor: 'transparent'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [2000, 2000, 4000, 4000, 3050, 3050, 2000, 2000, 3050, 3050, 4700, 4700, 2750, 2750, 5700, 5700]
|
||||
}
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
left: -10,
|
||||
right: -5
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
width: 3,
|
||||
curve: 'straight'
|
||||
},
|
||||
colors: [config.colors.warning],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
opacityFrom: 0.6,
|
||||
opacityTo: 0.15,
|
||||
stops: [0, 95, 100]
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
lines: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
min: 1000,
|
||||
max: 6000,
|
||||
tickAmount: 5
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
if (typeof projectStatusEl !== undefined && projectStatusEl !== null) {
|
||||
const projectStatus = new ApexCharts(projectStatusEl, projectStatusConfig);
|
||||
projectStatus.render();
|
||||
}
|
||||
})();
|
||||
@ -1,984 +0,0 @@
|
||||
/**
|
||||
* Dashboard eCommerce
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
(function () {
|
||||
let cardColor, labelColor, headingColor, borderColor, legendColor;
|
||||
|
||||
if (isDarkStyle) {
|
||||
cardColor = config.colors_dark.cardColor;
|
||||
labelColor = config.colors_dark.textMuted;
|
||||
legendColor = config.colors_dark.bodyColor;
|
||||
headingColor = config.colors_dark.headingColor;
|
||||
borderColor = config.colors_dark.borderColor;
|
||||
} else {
|
||||
cardColor = config.colors.cardColor;
|
||||
labelColor = config.colors.textMuted;
|
||||
legendColor = config.colors.bodyColor;
|
||||
headingColor = config.colors.headingColor;
|
||||
borderColor = config.colors.borderColor;
|
||||
}
|
||||
|
||||
// Donut Chart Colors
|
||||
const chartColors = {
|
||||
donut: {
|
||||
series1: config.colors.success,
|
||||
series2: '#28c76fb3',
|
||||
series3: '#28c76f80',
|
||||
series4: config.colors_label.success
|
||||
}
|
||||
};
|
||||
|
||||
// Expenses Radial Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const expensesRadialChartEl = document.querySelector('#expensesChart'),
|
||||
expensesRadialChartConfig = {
|
||||
chart: {
|
||||
height: 145,
|
||||
sparkline: {
|
||||
enabled: true
|
||||
},
|
||||
parentHeightOffset: 0,
|
||||
type: 'radialBar'
|
||||
},
|
||||
colors: [config.colors.warning],
|
||||
series: [78],
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
offsetY: 0,
|
||||
startAngle: -90,
|
||||
endAngle: 90,
|
||||
hollow: {
|
||||
size: '65%'
|
||||
},
|
||||
track: {
|
||||
strokeWidth: '45%',
|
||||
background: borderColor
|
||||
},
|
||||
dataLabels: {
|
||||
name: {
|
||||
show: false
|
||||
},
|
||||
value: {
|
||||
fontSize: '22px',
|
||||
color: headingColor,
|
||||
fontWeight: 600,
|
||||
offsetY: -5
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
bottom: 5
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
lineCap: 'round'
|
||||
},
|
||||
labels: ['Progress'],
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1442,
|
||||
options: {
|
||||
chart: {
|
||||
height: 120
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
dataLabels: {
|
||||
value: {
|
||||
fontSize: '18px'
|
||||
}
|
||||
},
|
||||
hollow: {
|
||||
size: '60%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: {
|
||||
height: 136
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: {
|
||||
size: '65%'
|
||||
},
|
||||
dataLabels: {
|
||||
value: {
|
||||
fontSize: '18px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
options: {
|
||||
chart: {
|
||||
height: 120
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: {
|
||||
size: '55%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 426,
|
||||
options: {
|
||||
chart: {
|
||||
height: 145
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: {
|
||||
size: '65%'
|
||||
}
|
||||
}
|
||||
},
|
||||
dataLabels: {
|
||||
value: {
|
||||
offsetY: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 376,
|
||||
options: {
|
||||
chart: {
|
||||
height: 105
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
hollow: {
|
||||
size: '60%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof expensesRadialChartEl !== undefined && expensesRadialChartEl !== null) {
|
||||
const expensesRadialChart = new ApexCharts(expensesRadialChartEl, expensesRadialChartConfig);
|
||||
expensesRadialChart.render();
|
||||
}
|
||||
|
||||
// Profit last month Line Chart
|
||||
// --------------------------------------------------------------------
|
||||
const profitLastMonthEl = document.querySelector('#profitLastMonth'),
|
||||
profitLastMonthConfig = {
|
||||
chart: {
|
||||
height: 90,
|
||||
type: 'line',
|
||||
parentHeightOffset: 0,
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
borderColor: borderColor,
|
||||
strokeDashArray: 6,
|
||||
xaxis: {
|
||||
lines: {
|
||||
show: true,
|
||||
colors: '#000'
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
padding: {
|
||||
top: -18,
|
||||
left: -4,
|
||||
right: 7,
|
||||
bottom: -10
|
||||
}
|
||||
},
|
||||
colors: [config.colors.info],
|
||||
stroke: {
|
||||
width: 2
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [0, 25, 10, 40, 25, 55]
|
||||
}
|
||||
],
|
||||
tooltip: {
|
||||
shared: false,
|
||||
intersect: true,
|
||||
x: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
markers: {
|
||||
size: 3.5,
|
||||
fillColor: config.colors.info,
|
||||
strokeColors: 'transparent',
|
||||
strokeWidth: 3.2,
|
||||
discrete: [
|
||||
{
|
||||
seriesIndex: 0,
|
||||
dataPointIndex: 5,
|
||||
fillColor: cardColor,
|
||||
strokeColor: config.colors.info,
|
||||
size: 5,
|
||||
shape: 'circle'
|
||||
}
|
||||
],
|
||||
hover: {
|
||||
size: 5.5
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1442,
|
||||
options: {
|
||||
chart: {
|
||||
height: 100
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: {
|
||||
height: 86
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
options: {
|
||||
chart: {
|
||||
height: 93
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof profitLastMonthEl !== undefined && profitLastMonthEl !== null) {
|
||||
const profitLastMonth = new ApexCharts(profitLastMonthEl, profitLastMonthConfig);
|
||||
profitLastMonth.render();
|
||||
}
|
||||
|
||||
// Generated Leads Chart
|
||||
// --------------------------------------------------------------------
|
||||
const generatedLeadsChartEl = document.querySelector('#generatedLeadsChart'),
|
||||
generatedLeadsChartConfig = {
|
||||
chart: {
|
||||
height: 147,
|
||||
width: 130,
|
||||
parentHeightOffset: 0,
|
||||
type: 'donut'
|
||||
},
|
||||
labels: ['Electronic', 'Sports', 'Decor', 'Fashion'],
|
||||
series: [45, 58, 30, 50],
|
||||
colors: [
|
||||
chartColors.donut.series1,
|
||||
chartColors.donut.series2,
|
||||
chartColors.donut.series3,
|
||||
chartColors.donut.series4
|
||||
],
|
||||
stroke: {
|
||||
width: 0
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false,
|
||||
formatter: function (val, opt) {
|
||||
return parseInt(val) + '%';
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
theme: false
|
||||
},
|
||||
grid: {
|
||||
padding: {
|
||||
top: 15,
|
||||
right: -20,
|
||||
left: -20
|
||||
}
|
||||
},
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
pie: {
|
||||
donut: {
|
||||
size: '70%',
|
||||
labels: {
|
||||
show: true,
|
||||
value: {
|
||||
fontSize: '1.375rem',
|
||||
fontFamily: 'Public Sans',
|
||||
color: headingColor,
|
||||
fontWeight: 600,
|
||||
offsetY: -15,
|
||||
formatter: function (val) {
|
||||
return parseInt(val) + '%';
|
||||
}
|
||||
},
|
||||
name: {
|
||||
offsetY: 20,
|
||||
fontFamily: 'Public Sans'
|
||||
},
|
||||
total: {
|
||||
show: true,
|
||||
showAlways: true,
|
||||
color: config.colors.success,
|
||||
fontSize: '.8125rem',
|
||||
label: 'Total',
|
||||
fontFamily: 'Public Sans',
|
||||
formatter: function (w) {
|
||||
return '184';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: {
|
||||
height: 172,
|
||||
width: 160
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
options: {
|
||||
chart: {
|
||||
height: 178
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 426,
|
||||
options: {
|
||||
chart: {
|
||||
height: 147
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof generatedLeadsChartEl !== undefined && generatedLeadsChartEl !== null) {
|
||||
const generatedLeadsChart = new ApexCharts(generatedLeadsChartEl, generatedLeadsChartConfig);
|
||||
generatedLeadsChart.render();
|
||||
}
|
||||
|
||||
// Total Revenue Report Chart - Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const totalRevenueChartEl = document.querySelector('#totalRevenueChart'),
|
||||
totalRevenueChartOptions = {
|
||||
series: [
|
||||
{
|
||||
name: 'Earning',
|
||||
data: [270, 210, 180, 200, 250, 280, 250, 270, 150]
|
||||
},
|
||||
{
|
||||
name: 'Expense',
|
||||
data: [-140, -160, -180, -150, -100, -60, -80, -100, -180]
|
||||
}
|
||||
],
|
||||
chart: {
|
||||
height: 365,
|
||||
parentHeightOffset: 0,
|
||||
stacked: true,
|
||||
type: 'bar',
|
||||
toolbar: { show: false }
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: false,
|
||||
columnWidth: '40%',
|
||||
borderRadius: 10,
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded'
|
||||
}
|
||||
},
|
||||
colors: [config.colors.primary, config.colors.warning],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
width: 6,
|
||||
lineCap: 'round',
|
||||
colors: [cardColor]
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
horizontalAlign: 'left',
|
||||
position: 'top',
|
||||
fontFamily: 'Public Sans',
|
||||
markers: {
|
||||
height: 12,
|
||||
width: 12,
|
||||
radius: 12,
|
||||
offsetX: -3,
|
||||
offsetY: 2
|
||||
},
|
||||
labels: {
|
||||
colors: legendColor
|
||||
},
|
||||
itemMargin: {
|
||||
horizontal: 5
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
bottom: -8,
|
||||
top: 20
|
||||
}
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep'],
|
||||
labels: {
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
offsetX: -16,
|
||||
style: {
|
||||
fontSize: '13px',
|
||||
colors: labelColor,
|
||||
fontFamily: 'Public Sans'
|
||||
}
|
||||
},
|
||||
min: -200,
|
||||
max: 300,
|
||||
tickAmount: 5
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1700,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '43%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1441,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '52%'
|
||||
}
|
||||
},
|
||||
chart: {
|
||||
height: 375
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1300,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '62%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '70%'
|
||||
}
|
||||
},
|
||||
chart: {
|
||||
height: 390
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 991,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '38%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 850,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '48%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 449,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '70%'
|
||||
}
|
||||
},
|
||||
chart: {
|
||||
height: 360
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
offsetY: -5
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 394,
|
||||
options: {
|
||||
plotOptions: {
|
||||
bar: {
|
||||
columnWidth: '88%'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
states: {
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
},
|
||||
active: {
|
||||
filter: {
|
||||
type: 'none'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if (typeof totalRevenueChartEl !== undefined && totalRevenueChartEl !== null) {
|
||||
const totalRevenueChart = new ApexCharts(totalRevenueChartEl, totalRevenueChartOptions);
|
||||
totalRevenueChart.render();
|
||||
}
|
||||
|
||||
// Total Revenue Report Budget Line Chart
|
||||
const budgetChartEl = document.querySelector('#budgetChart'),
|
||||
budgetChartOptions = {
|
||||
chart: {
|
||||
height: 100,
|
||||
toolbar: { show: false },
|
||||
zoom: { enabled: false },
|
||||
type: 'line'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Last Month',
|
||||
data: [20, 10, 30, 16, 24, 5, 40, 23, 28, 5, 30]
|
||||
},
|
||||
{
|
||||
name: 'This Month',
|
||||
data: [50, 40, 60, 46, 54, 35, 70, 53, 58, 35, 60]
|
||||
}
|
||||
],
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
dashArray: [5, 0],
|
||||
width: [1, 2]
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
colors: [borderColor, config.colors.primary],
|
||||
grid: {
|
||||
show: false,
|
||||
borderColor: borderColor,
|
||||
padding: {
|
||||
top: -30,
|
||||
bottom: -15,
|
||||
left: 25
|
||||
}
|
||||
},
|
||||
markers: {
|
||||
size: 0
|
||||
},
|
||||
xaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
axisBorder: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false
|
||||
}
|
||||
};
|
||||
if (typeof budgetChartEl !== undefined && budgetChartEl !== null) {
|
||||
const budgetChart = new ApexCharts(budgetChartEl, budgetChartOptions);
|
||||
budgetChart.render();
|
||||
}
|
||||
|
||||
// Earning Reports Bar Chart
|
||||
// --------------------------------------------------------------------
|
||||
const reportBarChartEl = document.querySelector('#reportBarChart'),
|
||||
reportBarChartConfig = {
|
||||
chart: {
|
||||
height: 230,
|
||||
type: 'bar',
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
barHeight: '60%',
|
||||
columnWidth: '60%',
|
||||
startingShape: 'rounded',
|
||||
endingShape: 'rounded',
|
||||
borderRadius: 4,
|
||||
distributed: true
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
show: false,
|
||||
padding: {
|
||||
top: -20,
|
||||
bottom: 0,
|
||||
left: -10,
|
||||
right: -10
|
||||
}
|
||||
},
|
||||
colors: [
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors.primary,
|
||||
config.colors_label.primary,
|
||||
config.colors_label.primary
|
||||
],
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: [40, 95, 60, 45, 90, 50, 75]
|
||||
}
|
||||
],
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
|
||||
axisBorder: {
|
||||
show: false
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '13px'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
responsive: [
|
||||
{
|
||||
breakpoint: 1025,
|
||||
options: {
|
||||
chart: {
|
||||
height: 190
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
breakpoint: 769,
|
||||
options: {
|
||||
chart: {
|
||||
height: 250
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
if (typeof reportBarChartEl !== undefined && reportBarChartEl !== null) {
|
||||
const barChart = new ApexCharts(reportBarChartEl, reportBarChartConfig);
|
||||
barChart.render();
|
||||
}
|
||||
|
||||
// Variable declaration for table
|
||||
var dt_invoice_table = $('.datatable-invoice');
|
||||
// Invoice datatable
|
||||
// --------------------------------------------------------------------
|
||||
if (dt_invoice_table.length) {
|
||||
var dt_invoice = dt_invoice_table.DataTable({
|
||||
ajax: assetsPath + 'json/invoice-list.json', // JSON file to add data
|
||||
columns: [
|
||||
// columns according to JSON
|
||||
{ data: '' },
|
||||
{ data: 'invoice_id' },
|
||||
{ data: 'invoice_status' },
|
||||
{ data: 'total' },
|
||||
{ data: 'issued_date' },
|
||||
{ data: 'invoice_status' },
|
||||
{ data: 'action' }
|
||||
],
|
||||
columnDefs: [
|
||||
{
|
||||
// For Responsive
|
||||
className: 'control',
|
||||
responsivePriority: 2,
|
||||
targets: 0,
|
||||
render: function (data, type, full, meta) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice ID
|
||||
targets: 1,
|
||||
render: function (data, type, full, meta) {
|
||||
var $invoice_id = full['invoice_id'];
|
||||
// Creates full output for row
|
||||
var $row_output = '<a href="app-invoice-preview.html"><span>#' + $invoice_id + '</span></a>';
|
||||
return $row_output;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice status
|
||||
targets: 2,
|
||||
render: function (data, type, full, meta) {
|
||||
var $invoice_status = full['invoice_status'],
|
||||
$due_date = full['due_date'],
|
||||
$balance = full['balance'];
|
||||
var roleBadgeObj = {
|
||||
Sent: '<span class="badge badge-center rounded-pill bg-label-secondary w-px-30 h-px-30"><i class="ti ti-circle-check ti-sm"></i></span>',
|
||||
Draft:
|
||||
'<span class="badge badge-center rounded-pill bg-label-primary w-px-30 h-px-30"><i class="ti ti-device-floppy ti-sm"></i></span>',
|
||||
'Past Due':
|
||||
'<span class="badge badge-center rounded-pill bg-label-danger w-px-30 h-px-30"><i class="ti ti-info-circle ti-sm"></i></span>',
|
||||
'Partial Payment':
|
||||
'<span class="badge badge-center rounded-pill bg-label-success w-px-30 h-px-30"><i class="ti ti-circle-half-2 ti-sm"></i></span>',
|
||||
Paid: '<span class="badge badge-center rounded-pill bg-label-warning w-px-30 h-px-30"><i class="ti ti-chart-pie ti-sm"></i></span>',
|
||||
Downloaded:
|
||||
'<span class="badge badge-center rounded-pill bg-label-info w-px-30 h-px-30"><i class="ti ti-arrow-down-circle ti-sm"></i></span>'
|
||||
};
|
||||
return (
|
||||
"<span data-bs-toggle='tooltip' data-bs-html='true' title='<span>" +
|
||||
$invoice_status +
|
||||
'<br> <strong>Balance:</strong> ' +
|
||||
$balance +
|
||||
'<br> <strong>Due Date:</strong> ' +
|
||||
$due_date +
|
||||
"</span>'>" +
|
||||
roleBadgeObj[$invoice_status] +
|
||||
'</span>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Total Invoice Amount
|
||||
targets: 3,
|
||||
render: function (data, type, full, meta) {
|
||||
var $total = full['total'];
|
||||
return '$' + $total;
|
||||
}
|
||||
},
|
||||
{
|
||||
// Actions
|
||||
targets: -1,
|
||||
title: 'Actions',
|
||||
orderable: false,
|
||||
render: function (data, type, full, meta) {
|
||||
return (
|
||||
'<div class="d-flex align-items-center">' +
|
||||
'<a href="javascript:;" class="text-body" data-bs-toggle="tooltip" title="Send Mail"><i class="ti ti-mail me-2 ti-sm"></i></a>' +
|
||||
'<a href="app-invoice-preview.html" class="text-body" data-bs-toggle="tooltip" title="Preview"><i class="ti ti-eye mx-2 ti-sm"></i></a>' +
|
||||
'<a href="javascript:;" class="text-body" data-bs-toggle="tooltip" title="Download"><i class="ti ti-dots-vertical mx-1 ti-sm"></i></a>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
// Invoice Status
|
||||
targets: -2,
|
||||
visible: false
|
||||
}
|
||||
],
|
||||
order: [[1, 'desc']],
|
||||
dom:
|
||||
'<"row ms-2 me-3"' +
|
||||
'<"col-12 col-md-6 d-flex align-items-center justify-content-center justify-content-md-start gap-2"l<"dt-action-buttons text-xl-end text-lg-start text-md-end text-start mt-md-0 mt-3"B>>' +
|
||||
'<"col-12 col-md-6 d-flex align-items-center justify-content-end flex-column flex-md-row pe-3 gap-md-2"f<"invoice_status mb-3 mb-md-0">>' +
|
||||
'>t' +
|
||||
'<"row mx-2"' +
|
||||
'<"col-sm-12 col-md-6"i>' +
|
||||
'<"col-sm-12 col-md-6"p>' +
|
||||
'>',
|
||||
displayLength: 7,
|
||||
lengthMenu: [7, 10, 25, 50, 75, 100],
|
||||
language: {
|
||||
sLengthMenu: '_MENU_',
|
||||
search: '',
|
||||
searchPlaceholder: 'Search Invoice'
|
||||
},
|
||||
// Buttons
|
||||
buttons: [
|
||||
{
|
||||
text: '<i class="ti ti-plus me-md-2"></i><span class="d-md-inline-block d-none">Create Invoice</span>',
|
||||
className: 'btn btn-primary',
|
||||
action: function (e, dt, button, config) {
|
||||
window.location = 'app-invoice-add.html';
|
||||
}
|
||||
}
|
||||
],
|
||||
// For responsive popup
|
||||
responsive: {
|
||||
details: {
|
||||
display: $.fn.dataTable.Responsive.display.modal({
|
||||
header: function (row) {
|
||||
var data = row.data();
|
||||
return 'Details of ' + data['full_name'];
|
||||
}
|
||||
}),
|
||||
type: 'column',
|
||||
renderer: function (api, rowIdx, columns) {
|
||||
var data = $.map(columns, function (col, i) {
|
||||
return col.title !== '' // ? Do not show row in modal popup if title is blank (for check box)
|
||||
? '<tr data-dt-row="' +
|
||||
col.rowIndex +
|
||||
'" data-dt-column="' +
|
||||
col.columnIndex +
|
||||
'">' +
|
||||
'<td>' +
|
||||
col.title +
|
||||
':' +
|
||||
'</td> ' +
|
||||
'<td>' +
|
||||
col.data +
|
||||
'</td>' +
|
||||
'</tr>'
|
||||
: '';
|
||||
}).join('');
|
||||
|
||||
return data ? $('<table class="table"/><tbody />').append(data) : false;
|
||||
}
|
||||
}
|
||||
},
|
||||
initComplete: function () {
|
||||
// Adding role filter once table initialized
|
||||
this.api()
|
||||
.columns(5)
|
||||
.every(function () {
|
||||
var column = this;
|
||||
var select = $(
|
||||
'<select id="UserRole" class="form-select"><option value=""> Select Status </option></select>'
|
||||
)
|
||||
.appendTo('.invoice_status')
|
||||
.on('change', function () {
|
||||
var val = $.fn.dataTable.util.escapeRegex($(this).val());
|
||||
column.search(val ? '^' + val + '$' : '', true, false).draw();
|
||||
});
|
||||
|
||||
column
|
||||
.data()
|
||||
.unique()
|
||||
.sort()
|
||||
.each(function (d, j) {
|
||||
select.append('<option value="' + d + '" class="text-capitalize">' + d + '</option>');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
// On each datatable draw, initialize tooltip
|
||||
dt_invoice_table.on('draw.dt', function () {
|
||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||
return new bootstrap.Tooltip(tooltipTriggerEl, {
|
||||
boundary: document.body
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Filter form control to default size
|
||||
// ? setTimeout used for multilingual table initialization
|
||||
setTimeout(() => {
|
||||
$('.dataTables_filter .form-control').removeClass('form-control-sm');
|
||||
$('.dataTables_length .form-select').removeClass('form-select-sm');
|
||||
}, 300);
|
||||
})();
|
||||
@ -1,272 +0,0 @@
|
||||
/*! Bootstrap integration for DataTables' Editor
|
||||
* © SpryMedia Ltd - datatables.net/license
|
||||
*/
|
||||
|
||||
(function( factory ){
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( ['jquery', 'datatables.net-bs', 'datatables.net-editor'], function ( $ ) {
|
||||
return factory( $, window, document );
|
||||
} );
|
||||
}
|
||||
else if ( typeof exports === 'object' ) {
|
||||
// CommonJS
|
||||
var jq = require('jquery');
|
||||
var cjsRequires = function (root, $) {
|
||||
if ( ! $.fn.dataTable ) {
|
||||
require('datatables.net-bs')(root, $);
|
||||
}
|
||||
|
||||
if ( ! $.fn.dataTable.Editor ) {
|
||||
require('datatables.net-editor')(root, $);
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
module.exports = function (root, $) {
|
||||
if ( ! root ) {
|
||||
// CommonJS environments without a window global must pass a
|
||||
// root. This will give an error otherwise
|
||||
root = window;
|
||||
}
|
||||
|
||||
if ( ! $ ) {
|
||||
$ = jq( root );
|
||||
}
|
||||
|
||||
cjsRequires( root, $ );
|
||||
return factory( $, root, root.document );
|
||||
};
|
||||
}
|
||||
else {
|
||||
cjsRequires( window, jq );
|
||||
module.exports = factory( jq, window, window.document );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Browser
|
||||
factory( jQuery, window, document );
|
||||
}
|
||||
}(function( $, window, document, undefined ) {
|
||||
'use strict';
|
||||
var DataTable = $.fn.dataTable;
|
||||
|
||||
|
||||
var Editor = DataTable.Editor;
|
||||
|
||||
/*
|
||||
* Set the default display controller to be our bootstrap control
|
||||
*/
|
||||
DataTable.Editor.defaults.display = "bootstrap";
|
||||
|
||||
|
||||
/*
|
||||
* Change the default classes from Editor to be classes for Bootstrap
|
||||
*/
|
||||
$.extend( true, $.fn.dataTable.Editor.classes, {
|
||||
"header": {
|
||||
"wrapper": "DTE_Header modal-header",
|
||||
title: {
|
||||
tag: 'h4',
|
||||
class: 'modal-title'
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"wrapper": "DTE_Body modal-body"
|
||||
},
|
||||
"footer": {
|
||||
"wrapper": "DTE_Footer modal-footer"
|
||||
},
|
||||
"form": {
|
||||
"tag": "form-horizontal",
|
||||
"button": "btn btn-default",
|
||||
"buttonInternal": "btn btn-default"
|
||||
},
|
||||
"field": {
|
||||
"wrapper": "DTE_Field",
|
||||
"label": "col-lg-4 control-label",
|
||||
"input": "col-lg-8 controls",
|
||||
"error": "error has-error",
|
||||
"msg-labelInfo": "help-block",
|
||||
"msg-info": "help-block",
|
||||
"msg-message": "help-block",
|
||||
"msg-error": "help-block",
|
||||
"multiValue": "well well-sm multi-value",
|
||||
"multiInfo": "small",
|
||||
"multiRestore": "well well-sm multi-restore"
|
||||
}
|
||||
} );
|
||||
|
||||
$.extend( true, DataTable.ext.buttons, {
|
||||
create: {
|
||||
formButtons: {
|
||||
className: 'btn-primary'
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
formButtons: {
|
||||
className: 'btn-primary'
|
||||
}
|
||||
},
|
||||
remove: {
|
||||
formButtons: {
|
||||
className: 'btn-danger'
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
DataTable.Editor.fieldTypes.datatable.tableClass = 'table';
|
||||
|
||||
let shown = false;
|
||||
let fullyShown = false;
|
||||
|
||||
const dom = {
|
||||
// Note that `modal-dialog-scrollable` is BS4.3+ only. It has no effect on 4.0-4.2
|
||||
content: $(
|
||||
'<div class="modal fade DTED">'+
|
||||
'<div class="modal-dialog">'+
|
||||
'<div class="modal-content"></div>'+
|
||||
'</div>'+
|
||||
'</div>'
|
||||
),
|
||||
close: $('<button class="close">×</div>')
|
||||
};
|
||||
|
||||
/*
|
||||
* Bootstrap display controller - this is effectively a proxy to the Bootstrap
|
||||
* modal control.
|
||||
*/
|
||||
DataTable.Editor.display.bootstrap = $.extend( true, {}, DataTable.Editor.models.displayController, {
|
||||
init: function ( dte ) {
|
||||
// Add `form-control` to required elements
|
||||
dte.on( 'displayOrder.dtebs open.dtebs', function ( e, display, action, form ) {
|
||||
$.each( dte.s.fields, function ( key, field ) {
|
||||
$('input:not([type=checkbox]):not([type=radio]), select, textarea', field.node() )
|
||||
.addClass( 'form-control' );
|
||||
} );
|
||||
} );
|
||||
|
||||
return DataTable.Editor.display.bootstrap;
|
||||
},
|
||||
|
||||
open: function ( dte, append, callback ) {
|
||||
$(append).addClass('modal-content');
|
||||
|
||||
// Special class for DataTable buttons in the form
|
||||
$(append).find('div.DTE_Field_Type_datatable div.dt-buttons')
|
||||
.removeClass('btn-group')
|
||||
.addClass('btn-group-vertical');
|
||||
|
||||
var content = dom.content.find('div.modal-dialog');
|
||||
content.children().detach();
|
||||
content.append( append );
|
||||
|
||||
// Setup events on each show
|
||||
dom.close
|
||||
.attr('title', dte.i18n.close)
|
||||
.off('click.dte-bs3')
|
||||
.on('click.dte-bs3', function () {
|
||||
dte.close('icon');
|
||||
})
|
||||
.prependTo($('div.modal-header', dom.content));
|
||||
|
||||
// This is a bit horrible, but if you mousedown and then drag out of the modal container, we don't
|
||||
// want to trigger a background action.
|
||||
var allowBackgroundClick = false;
|
||||
$(document)
|
||||
.off('mousedown.dte-bs3')
|
||||
.on('mousedown.dte-bs3', 'div.modal', function (e) {
|
||||
if ( ! shown ) {
|
||||
return;
|
||||
}
|
||||
|
||||
allowBackgroundClick = $(e.target).hasClass('modal') && shown
|
||||
? true
|
||||
: false;
|
||||
} );
|
||||
|
||||
$(document)
|
||||
.off('click.dte-bs3')
|
||||
.on('click.dte-bs3', 'div.modal', function (e) {
|
||||
if ( $(e.target).hasClass('modal') && allowBackgroundClick ) {
|
||||
dte.background();
|
||||
}
|
||||
|
||||
if ( ! $(e.target).hasClass('modal') ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If scrollbar shown
|
||||
if ($('div.modal-dialog').height() > $(e.target).height()) {
|
||||
// And if clicking inside it - do nothing
|
||||
if (e.pageX >= document.body.offsetWidth - DataTable.__browser.barWidth) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// All checks pass - do background action
|
||||
dte.background();
|
||||
} );
|
||||
|
||||
if ( shown ) {
|
||||
if ( callback ) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
shown = true;
|
||||
fullyShown = false;
|
||||
|
||||
$(dom.content)
|
||||
.one('shown.bs.modal', function () {
|
||||
// Can only give elements focus when shown
|
||||
if ( dte.s.setFocus ) {
|
||||
dte.s.setFocus.focus();
|
||||
}
|
||||
|
||||
if ( callback ) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
.one('hidden', function () {
|
||||
shown = false;
|
||||
})
|
||||
.appendTo( 'body' )
|
||||
.modal( {
|
||||
backdrop: "static",
|
||||
keyboard: false
|
||||
} );
|
||||
|
||||
dom.close.prependTo($('div.modal-header', dom.content));
|
||||
},
|
||||
|
||||
close: function ( dte, callback ) {
|
||||
if ( ! shown ) {
|
||||
if ( callback ) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$(dom.content)
|
||||
.one( 'hidden.bs.modal', function () {
|
||||
$(this).detach();
|
||||
} )
|
||||
.modal('hide');
|
||||
|
||||
shown = false;
|
||||
|
||||
if ( callback ) {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
node: function ( dte ) {
|
||||
return dom.content[0];
|
||||
}
|
||||
} );
|
||||
|
||||
|
||||
return Editor;
|
||||
}));
|
||||
@ -1,4 +0,0 @@
|
||||
/*! Bootstrap integration for DataTables' Editor
|
||||
* © SpryMedia Ltd - datatables.net/license
|
||||
*/
|
||||
!function(o){var d,n;"function"==typeof define&&define.amd?define(["jquery","datatables.net-bs","datatables.net-editor"],function(e){return o(e,window,document)}):"object"==typeof exports?(d=require("jquery"),n=function(e,t){t.fn.dataTable||require("datatables.net-bs")(e,t),t.fn.dataTable.Editor||require("datatables.net-editor")(e,t)},"undefined"==typeof window?module.exports=function(e,t){return e=e||window,t=t||d(e),n(e,t),o(t,0,e.document)}:(n(window,d),module.exports=o(d,window,window.document))):o(jQuery,window,document)}(function(a,e,l,t){"use strict";var s=a.fn.dataTable,o=s.Editor;s.Editor.defaults.display="bootstrap",a.extend(!0,a.fn.dataTable.Editor.classes,{header:{wrapper:"DTE_Header modal-header",title:{tag:"h4",class:"modal-title"}},body:{wrapper:"DTE_Body modal-body"},footer:{wrapper:"DTE_Footer modal-footer"},form:{tag:"form-horizontal",button:"btn btn-default",buttonInternal:"btn btn-default"},field:{wrapper:"DTE_Field",label:"col-lg-4 control-label",input:"col-lg-8 controls",error:"error has-error","msg-labelInfo":"help-block","msg-info":"help-block","msg-message":"help-block","msg-error":"help-block",multiValue:"well well-sm multi-value",multiInfo:"small",multiRestore:"well well-sm multi-restore"}}),a.extend(!0,s.ext.buttons,{create:{formButtons:{className:"btn-primary"}},edit:{formButtons:{className:"btn-primary"}},remove:{formButtons:{className:"btn-danger"}}});let r=!(s.Editor.fieldTypes.datatable.tableClass="table");const i={content:a('<div class="modal fade DTED"><div class="modal-dialog"><div class="modal-content"></div></div></div>'),close:a('<button class="close">×</div>')};return s.Editor.display.bootstrap=a.extend(!0,{},s.Editor.models.displayController,{init:function(n){return n.on("displayOrder.dtebs open.dtebs",function(e,t,o,d){a.each(n.s.fields,function(e,t){a("input:not([type=checkbox]):not([type=radio]), select, textarea",t.node()).addClass("form-control")})}),s.Editor.display.bootstrap},open:function(t,e,o){a(e).addClass("modal-content"),a(e).find("div.DTE_Field_Type_datatable div.dt-buttons").removeClass("btn-group").addClass("btn-group-vertical");var d=i.content.find("div.modal-dialog"),n=(d.children().detach(),d.append(e),i.close.attr("title",t.i18n.close).off("click.dte-bs3").on("click.dte-bs3",function(){t.close("icon")}).prependTo(a("div.modal-header",i.content)),!1);a(l).off("mousedown.dte-bs3").on("mousedown.dte-bs3","div.modal",function(e){r&&(n=!(!a(e.target).hasClass("modal")||!r))}),a(l).off("click.dte-bs3").on("click.dte-bs3","div.modal",function(e){a(e.target).hasClass("modal")&&n&&t.background(),!a(e.target).hasClass("modal")||a("div.modal-dialog").height()>a(e.target).height()&&e.pageX>=l.body.offsetWidth-s.__browser.barWidth||t.background()}),r?o&&o():(r=!0,a(i.content).one("shown.bs.modal",function(){t.s.setFocus&&t.s.setFocus.focus(),o&&o()}).one("hidden",function(){r=!1}).appendTo("body").modal({backdrop:"static",keyboard:!1}),i.close.prependTo(a("div.modal-header",i.content)))},close:function(e,t){r&&(a(i.content).one("hidden.bs.modal",function(){a(this).detach()}).modal("hide"),r=!1),t&&t()},node:function(e){return i.content[0]}}),o});
|
||||
@ -1,4 +0,0 @@
|
||||
/*! Bootstrap integration for DataTables' Editor
|
||||
* © SpryMedia Ltd - datatables.net/license
|
||||
*/
|
||||
import jQuery from"jquery";import DataTable from"datatables.net-bs";import Editor from"datatables.net-editor";let $=jQuery;var Editor=DataTable.Editor;DataTable.Editor.defaults.display="bootstrap",$.extend(!0,$.fn.dataTable.Editor.classes,{header:{wrapper:"DTE_Header modal-header",title:{tag:"h4",class:"modal-title"}},body:{wrapper:"DTE_Body modal-body"},footer:{wrapper:"DTE_Footer modal-footer"},form:{tag:"form-horizontal",button:"btn btn-default",buttonInternal:"btn btn-default"},field:{wrapper:"DTE_Field",label:"col-lg-4 control-label",input:"col-lg-8 controls",error:"error has-error","msg-labelInfo":"help-block","msg-info":"help-block","msg-message":"help-block","msg-error":"help-block",multiValue:"well well-sm multi-value",multiInfo:"small",multiRestore:"well well-sm multi-restore"}}),$.extend(!0,DataTable.ext.buttons,{create:{formButtons:{className:"btn-primary"}},edit:{formButtons:{className:"btn-primary"}},remove:{formButtons:{className:"btn-danger"}}});let shown=!(DataTable.Editor.fieldTypes.datatable.tableClass="table"),fullyShown=!1;const dom={content:$('<div class="modal fade DTED"><div class="modal-dialog"><div class="modal-content"></div></div></div>'),close:$('<button class="close">×</div>')};DataTable.Editor.display.bootstrap=$.extend(!0,{},DataTable.Editor.models.displayController,{init:function(d){return d.on("displayOrder.dtebs open.dtebs",function(o,t,e,a){$.each(d.s.fields,function(o,t){$("input:not([type=checkbox]):not([type=radio]), select, textarea",t.node()).addClass("form-control")})}),DataTable.Editor.display.bootstrap},open:function(t,o,e){$(o).addClass("modal-content"),$(o).find("div.DTE_Field_Type_datatable div.dt-buttons").removeClass("btn-group").addClass("btn-group-vertical");var a=dom.content.find("div.modal-dialog"),d=(a.children().detach(),a.append(o),dom.close.attr("title",t.i18n.close).off("click.dte-bs3").on("click.dte-bs3",function(){t.close("icon")}).prependTo($("div.modal-header",dom.content)),!1);$(document).off("mousedown.dte-bs3").on("mousedown.dte-bs3","div.modal",function(o){shown&&(d=!(!$(o.target).hasClass("modal")||!shown))}),$(document).off("click.dte-bs3").on("click.dte-bs3","div.modal",function(o){$(o.target).hasClass("modal")&&d&&t.background(),!$(o.target).hasClass("modal")||$("div.modal-dialog").height()>$(o.target).height()&&o.pageX>=document.body.offsetWidth-DataTable.__browser.barWidth||t.background()}),shown?e&&e():(shown=!0,fullyShown=!1,$(dom.content).one("shown.bs.modal",function(){t.s.setFocus&&t.s.setFocus.focus(),e&&e()}).one("hidden",function(){shown=!1}).appendTo("body").modal({backdrop:"static",keyboard:!1}),dom.close.prependTo($("div.modal-header",dom.content)))},close:function(o,t){shown&&($(dom.content).one("hidden.bs.modal",function(){$(this).detach()}).modal("hide"),shown=!1),t&&t()},node:function(o){return dom.content[0]}});export default Editor;
|
||||