closed admin panel

This commit is contained in:
akosse 2020-01-29 11:26:01 +03:00
parent 75ccbff934
commit aa501900e4
29 changed files with 876 additions and 17 deletions

View File

@ -6,6 +6,7 @@ use yii\web\Controller;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use common\models\LoginForm; use common\models\LoginForm;
use yii\helpers\Url;
/** /**
* Site controller * Site controller
@ -18,20 +19,6 @@ class SiteController extends Controller
public function behaviors() public function behaviors()
{ {
return [ return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [ 'verbs' => [
'class' => VerbFilter::className(), 'class' => VerbFilter::className(),
'actions' => [ 'actions' => [
@ -76,10 +63,14 @@ class SiteController extends Controller
$model = new LoginForm(); $model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) { if ($model->load(Yii::$app->request->post()) && $model->login()) {
if (\Yii::$app->user->can('secure')) {
return $this->goBack(); return $this->goBack();
} else {
Yii::$app->user->logout();
return $this->redirect(Url::to('/card/user-card'));
}
} else { } else {
$model->password = ''; $model->password = '';
return $this->render('login', [ return $this->render('login', [
'model' => $model, 'model' => $model,
]); ]);

View File

@ -8,6 +8,7 @@ use common\models\UserCardAccesses;
use Yii; use Yii;
use common\models\Accesses; use common\models\Accesses;
use app\modules\accesses\models\AccessesSearch; use app\modules\accesses\models\AccessesSearch;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -29,6 +30,15 @@ class AccessesController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -10,12 +10,39 @@ use common\models\FieldsValueNew;
use DateTime; use DateTime;
use Yii; use Yii;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\db\Query; use yii\db\Query;
class BalanceController extends Controller class BalanceController extends Controller
{ {
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
];
}
public function actionIndex() public function actionIndex()
{ {
$searchModel = new BalanceSearch(); $searchModel = new BalanceSearch();

View File

@ -6,6 +6,8 @@ use backend\modules\card\models\UserCardSearch;
use common\classes\Debug; use common\classes\Debug;
use Yii; use Yii;
use yii\data\ArrayDataProvider; use yii\data\ArrayDataProvider;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\Controller; use yii\web\Controller;
/** /**
@ -13,6 +15,30 @@ use yii\web\Controller;
*/ */
class CalendarController extends Controller class CalendarController extends Controller
{ {
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
];
}
/** /**
* Renders the index view for the module * Renders the index view for the module
* @return string * @return string

View File

@ -14,6 +14,7 @@ use backend\modules\card\models\UserCard;
use backend\modules\card\models\UserCardSearch; use backend\modules\card\models\UserCardSearch;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\db\Expression; use yii\db\Expression;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -35,6 +36,15 @@ class UserCardController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -7,6 +7,7 @@ use Yii;
use backend\modules\company\models\Company; use backend\modules\company\models\Company;
use backend\modules\company\models\CompanySearch; use backend\modules\company\models\CompanySearch;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -28,6 +29,15 @@ class CompanyController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -9,6 +9,7 @@ use Yii;
use backend\modules\hh\models\Hh; use backend\modules\hh\models\Hh;
use backend\modules\hh\models\HhSearch; use backend\modules\hh\models\HhSearch;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -30,6 +31,15 @@ class HhController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -6,6 +6,7 @@ use common\models\Hh;
use Yii; use Yii;
use backend\modules\hh\models\HhJob; use backend\modules\hh\models\HhJob;
use backend\modules\hh\models\HhJobSearch; use backend\modules\hh\models\HhJobSearch;
use yii\filters\AccessControl;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
@ -28,6 +29,15 @@ class HhJobController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -6,6 +6,7 @@ use backend\modules\holiday\models\Holiday;
use backend\modules\holiday\models\HolidaySearch; use backend\modules\holiday\models\HolidaySearch;
use common\classes\Debug; use common\classes\Debug;
use Yii; use Yii;
use yii\filters\AccessControl;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
@ -24,6 +25,15 @@ class HolidayController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -7,6 +7,8 @@ use Yii;
use backend\modules\notes\models\Note; use backend\modules\notes\models\Note;
use common\models\FieldsValueNew; use common\models\FieldsValueNew;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
@ -15,6 +17,30 @@ use yii\web\NotFoundHttpException;
*/ */
class NotesController extends Controller class NotesController extends Controller
{ {
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['POST'],
],
],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
];
}
/** /**
* Renders the index view for the module * Renders the index view for the module
* @return string * @return string

View File

@ -11,6 +11,7 @@ use Yii;
use backend\modules\project\models\Project; use backend\modules\project\models\Project;
use backend\modules\project\models\ProjectSearch; use backend\modules\project\models\ProjectSearch;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -32,6 +33,15 @@ class ProjectController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -7,6 +7,7 @@ use common\models\UseField;
use Yii; use Yii;
use backend\modules\settings\models\AdditionalFields; use backend\modules\settings\models\AdditionalFields;
use backend\modules\settings\models\AdditionalFieldsSearch; use backend\modules\settings\models\AdditionalFieldsSearch;
use yii\filters\AccessControl;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
@ -29,6 +30,15 @@ class AdditionalFieldsController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -5,6 +5,7 @@ namespace backend\modules\settings\controllers;
use Yii; use Yii;
use backend\modules\settings\models\Position; use backend\modules\settings\models\Position;
use backend\modules\settings\models\PositionSearch; use backend\modules\settings\models\PositionSearch;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -26,6 +27,15 @@ class PositionController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -5,6 +5,7 @@ namespace backend\modules\settings\controllers;
use Yii; use Yii;
use backend\modules\settings\models\Skill; use backend\modules\settings\models\Skill;
use backend\modules\settings\models\SkillSearch; use backend\modules\settings\models\SkillSearch;
use yii\filters\AccessControl;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -26,6 +27,15 @@ class SkillController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -6,6 +6,7 @@ use common\models\UseStatus;
use Yii; use Yii;
use backend\modules\settings\models\Status; use backend\modules\settings\models\Status;
use backend\modules\settings\models\StatusSearch; use backend\modules\settings\models\StatusSearch;
use yii\filters\AccessControl;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
@ -28,6 +29,15 @@ class StatusController extends Controller
'delete' => ['POST'], 'delete' => ['POST'],
], ],
], ],
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['admin'],
],
],
],
]; ];
} }

View File

@ -9,6 +9,12 @@ return [
'cache' => [ 'cache' => [
'class' => 'yii\caching\FileCache', 'class' => 'yii\caching\FileCache',
], ],
'authManager' => [
'class' => 'yii\rbac\DbManager',
// 'itemFile' => '@common/components/rbac/items.php',
// 'assignmentFile' => '@common/components/rbac/assignments.php',
// 'ruleFile' => '@common/components/rbac/rules.php'
],
], ],
'controllerMap' => [ 'controllerMap' => [
'elfinder' => [ 'elfinder' => [

View File

@ -0,0 +1,59 @@
<?php
namespace common\models;
use Yii;
/**
* This is the model class for table "auth_assignment".
*
* @property string $item_name
* @property string $user_id
* @property int $created_at
*
* @property AuthItem $itemName
*/
class AuthAssignment extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'auth_assignment';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['item_name', 'user_id'], 'required'],
[['created_at'], 'integer'],
[['item_name', 'user_id'], 'string', 'max' => 64],
[['item_name', 'user_id'], 'unique', 'targetAttribute' => ['item_name', 'user_id']],
[['item_name'], 'exist', 'skipOnError' => true, 'targetClass' => AuthItem::className(), 'targetAttribute' => ['item_name' => 'name']],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'item_name' => 'Item Name',
'user_id' => 'User ID',
'created_at' => 'Created At',
];
}
/**
* @return \yii\db\ActiveQuery
*/
public function getItemName()
{
return $this->hasOne(AuthItem::className(), ['name' => 'item_name']);
}
}

View File

@ -6,6 +6,7 @@ use common\classes\Debug;
use Yii; use Yii;
use yii\behaviors\TimestampBehavior; use yii\behaviors\TimestampBehavior;
use yii\db\Expression; use yii\db\Expression;
use yii\filters\AccessControl;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
/** /**

View File

@ -27,7 +27,7 @@
"nkovacs/yii2-datetimepicker": "*", "nkovacs/yii2-datetimepicker": "*",
"mirocow/yii2-eav": "*", "mirocow/yii2-eav": "*",
"kartik-v/yii2-widget-fileinput": "^1.0", "kartik-v/yii2-widget-fileinput": "^1.0",
"2amigos/yii2-file-upload-widget": "~1.0" "2amigos/yii2-file-upload-widget": "~1.0",
}, },
"require-dev": { "require-dev": {
"yiisoft/yii2-debug": "~2.0.0", "yiisoft/yii2-debug": "~2.0.0",

View File

@ -22,6 +22,12 @@ return [
], ],
], ],
'components' => [ 'components' => [
'user' => [
'identityClass' => 'common\models\User',
'class' => 'yii\web\User',
'enableSession' => false,
'enableAutoLogin' => false,
],
'log' => [ 'log' => [
'targets' => [ 'targets' => [
[ [

View File

@ -0,0 +1,36 @@
<?php
namespace console\controllers;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app->authManager;
$secure = $auth->createPermission('secure');
$secure->description = 'Admin panel';
$auth->add($secure);
$front = $auth->createPermission('front');
$front->description = 'Frontend';
$auth->add($front);
$user = $auth->createRole('user');
$auth->add($user);
$auth->addChild($user, $front);
$admin = $auth->createRole('admin');
$auth->add($admin);
$auth->addChild($admin, $secure);
$auth->addChild($admin, $user);
$auth->assign($user, 2);
$auth->assign($admin, 1);
}
}

View File

@ -1,6 +1,8 @@
<?php <?php
namespace frontend\models; namespace frontend\models;
use common\classes\Debug;
use Yii;
use yii\base\Model; use yii\base\Model;
use common\models\User; use common\models\User;
@ -52,6 +54,11 @@ class SignupForm extends Model
$user->email = $this->email; $user->email = $this->email;
$user->setPassword($this->password); $user->setPassword($this->password);
$user->generateAuthKey(); $user->generateAuthKey();
$user->save();
$auth = Yii::$app->authManager;
$authorRole = $auth->getRole('user');
$auth->assign($authorRole, $user->id);
return $user->save() ? $user : null; return $user->save() ? $user : null;
} }

20
node_modules/sticky-table-headers/composer.json generated vendored Normal file
View File

@ -0,0 +1,20 @@
{
"name": "jmosbech/sticky-table-headers",
"description": "jQuery sticky table headers plugin",
"keywords": [
"jquery",
"sticky",
"table",
"headers"
],
"homepage": "https://github.com/jmosbech/StickyTableHeaders",
"authors": [
{
"name": "Jonas Mosbech"
}
],
"support": {
"issues": "https://github.com/jmosbech/StickyTableHeaders/issues"
},
"license": "MIT"
}

View File

@ -0,0 +1,325 @@
/*! Copyright (c) Jonas Mosbech - https://github.com/jmosbech/StickyTableHeaders
MIT license info: https://github.com/jmosbech/StickyTableHeaders/blob/master/license.txt */
;(function ($, window, undefined) {
'use strict';
var name = 'stickyTableHeaders',
id = 0,
defaults = {
fixedOffset: 0,
leftOffset: 0,
marginTop: 0,
objDocument: document,
objHead: 'head',
objWindow: window,
scrollableArea: window,
cacheHeaderHeight: false,
zIndex: 3
};
function Plugin (el, options) {
// To avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this;
// Access to jQuery and DOM versions of element
base.$el = $(el);
base.el = el;
base.id = id++;
// Listen for destroyed, call teardown
base.$el.bind('destroyed',
$.proxy(base.teardown, base));
// Cache DOM refs for performance reasons
base.$clonedHeader = null;
base.$originalHeader = null;
// Cache header height for performance reasons
base.cachedHeaderHeight = null;
// Keep track of state
base.isSticky = false;
base.hasBeenSticky = false;
base.leftOffset = null;
base.topOffset = null;
base.init = function () {
base.setOptions(options);
base.$el.each(function () {
var $this = $(this);
// remove padding on <table> to fix issue #7
$this.css('padding', 0);
base.$originalHeader = $('thead:first', this);
base.$clonedHeader = base.$originalHeader.clone();
$this.trigger('clonedHeader.' + name, [base.$clonedHeader]);
base.$clonedHeader.addClass('tableFloatingHeader');
base.$clonedHeader.css({display: 'none', opacity: 0.0});
base.$originalHeader.addClass('tableFloatingHeaderOriginal');
base.$originalHeader.after(base.$clonedHeader);
base.$printStyle = $('<style type="text/css" media="print">' +
'.tableFloatingHeader{display:none !important;}' +
'.tableFloatingHeaderOriginal{position:static !important;}' +
'</style>');
base.$head.append(base.$printStyle);
});
base.$clonedHeader.find("input, select").attr("disabled", true);
base.updateWidth();
base.toggleHeaders();
base.bind();
};
base.destroy = function (){
base.$el.unbind('destroyed', base.teardown);
base.teardown();
};
base.teardown = function(){
if (base.isSticky) {
base.$originalHeader.css('position', 'static');
}
$.removeData(base.el, 'plugin_' + name);
base.unbind();
base.$clonedHeader.remove();
base.$originalHeader.removeClass('tableFloatingHeaderOriginal');
base.$originalHeader.css('visibility', 'visible');
base.$printStyle.remove();
base.el = null;
base.$el = null;
};
base.bind = function(){
base.$scrollableArea.on('scroll.' + name, base.toggleHeaders);
if (!base.isWindowScrolling) {
base.$window.on('scroll.' + name + base.id, base.setPositionValues);
base.$window.on('resize.' + name + base.id, base.toggleHeaders);
}
base.$scrollableArea.on('resize.' + name, base.toggleHeaders);
base.$scrollableArea.on('resize.' + name, base.updateWidth);
};
base.unbind = function(){
// unbind window events by specifying handle so we don't remove too much
base.$scrollableArea.off('.' + name, base.toggleHeaders);
if (!base.isWindowScrolling) {
base.$window.off('.' + name + base.id, base.setPositionValues);
base.$window.off('.' + name + base.id, base.toggleHeaders);
}
base.$scrollableArea.off('.' + name, base.updateWidth);
};
// We debounce the functions bound to the scroll and resize events
base.debounce = function (fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
};
base.toggleHeaders = base.debounce(function () {
if (base.$el) {
base.$el.each(function () {
var $this = $(this),
newLeft,
newTopOffset = base.isWindowScrolling ? (
isNaN(base.options.fixedOffset) ?
base.options.fixedOffset.outerHeight() :
base.options.fixedOffset
) :
base.$scrollableArea.offset().top + (!isNaN(base.options.fixedOffset) ? base.options.fixedOffset : 0),
offset = $this.offset(),
scrollTop = base.$scrollableArea.scrollTop() + newTopOffset,
scrollLeft = base.$scrollableArea.scrollLeft(),
headerHeight,
scrolledPastTop = base.isWindowScrolling ?
scrollTop > offset.top :
newTopOffset > offset.top,
notScrolledPastBottom;
if (scrolledPastTop) {
headerHeight = base.options.cacheHeaderHeight ? base.cachedHeaderHeight : base.$clonedHeader.height();
notScrolledPastBottom = (base.isWindowScrolling ? scrollTop : 0) <
(offset.top + $this.height() - headerHeight - (base.isWindowScrolling ? 0 : newTopOffset));
}
if (scrolledPastTop && notScrolledPastBottom) {
newLeft = offset.left - scrollLeft + base.options.leftOffset;
base.$originalHeader.css({
'position': 'fixed',
'margin-top': base.options.marginTop,
'top': 0,
'left': newLeft,
'z-index': base.options.zIndex
});
base.leftOffset = newLeft;
base.topOffset = newTopOffset;
base.$clonedHeader.css('display', '');
if (!base.isSticky) {
base.isSticky = true;
// make sure the width is correct: the user might have resized the browser while in static mode
base.updateWidth();
$this.trigger('enabledStickiness.' + name);
}
base.setPositionValues();
} else if (base.isSticky) {
base.$originalHeader.css('position', 'static');
base.$clonedHeader.css('display', 'none');
base.isSticky = false;
base.resetWidth($('td,th', base.$clonedHeader), $('td,th', base.$originalHeader));
$this.trigger('disabledStickiness.' + name);
}
});
}
}, 0);
base.setPositionValues = base.debounce(function () {
var winScrollTop = base.$window.scrollTop(),
winScrollLeft = base.$window.scrollLeft();
if (!base.isSticky ||
winScrollTop < 0 || winScrollTop + base.$window.height() > base.$document.height() ||
winScrollLeft < 0 || winScrollLeft + base.$window.width() > base.$document.width()) {
return;
}
base.$originalHeader.css({
'top': base.topOffset - (base.isWindowScrolling ? 0 : winScrollTop),
'left': base.leftOffset - (base.isWindowScrolling ? 0 : winScrollLeft)
});
}, 0);
base.updateWidth = base.debounce(function () {
if (!base.isSticky) {
return;
}
// Copy cell widths from clone
if (!base.$originalHeaderCells) {
base.$originalHeaderCells = $('th,td', base.$originalHeader);
}
if (!base.$clonedHeaderCells) {
base.$clonedHeaderCells = $('th,td', base.$clonedHeader);
}
var cellWidths = base.getWidth(base.$clonedHeaderCells);
base.setWidth(cellWidths, base.$clonedHeaderCells, base.$originalHeaderCells);
// Copy row width from whole table
base.$originalHeader.css('width', base.$clonedHeader.width());
// If we're caching the height, we need to update the cached value when the width changes
if (base.options.cacheHeaderHeight) {
base.cachedHeaderHeight = base.$clonedHeader.height();
}
}, 0);
base.getWidth = function ($clonedHeaders) {
var widths = [];
$clonedHeaders.each(function (index) {
var width, $this = $(this);
if ($this.css('box-sizing') === 'border-box') {
var boundingClientRect = $this[0].getBoundingClientRect();
if(boundingClientRect.width) {
width = boundingClientRect.width; // #39: border-box bug
} else {
width = boundingClientRect.right - boundingClientRect.left; // ie8 bug: getBoundingClientRect() does not have a width property
}
} else {
var $origTh = $('th', base.$originalHeader);
if ($origTh.css('border-collapse') === 'collapse') {
if (window.getComputedStyle) {
width = parseFloat(window.getComputedStyle(this, null).width);
} else {
// ie8 only
var leftPadding = parseFloat($this.css('padding-left'));
var rightPadding = parseFloat($this.css('padding-right'));
// Needs more investigation - this is assuming constant border around this cell and it's neighbours.
var border = parseFloat($this.css('border-width'));
width = $this.outerWidth() - leftPadding - rightPadding - border;
}
} else {
width = $this.width();
}
}
widths[index] = width;
});
return widths;
};
base.setWidth = function (widths, $clonedHeaders, $origHeaders) {
$clonedHeaders.each(function (index) {
var width = widths[index];
$origHeaders.eq(index).css({
'min-width': width,
'max-width': width
});
});
};
base.resetWidth = function ($clonedHeaders, $origHeaders) {
$clonedHeaders.each(function (index) {
var $this = $(this);
$origHeaders.eq(index).css({
'min-width': $this.css('min-width'),
'max-width': $this.css('max-width')
});
});
};
base.setOptions = function (options) {
base.options = $.extend({}, defaults, options);
base.$window = $(base.options.objWindow);
base.$head = $(base.options.objHead);
base.$document = $(base.options.objDocument);
base.$scrollableArea = $(base.options.scrollableArea);
base.isWindowScrolling = base.$scrollableArea[0] === base.$window[0];
};
base.updateOptions = function (options) {
base.setOptions(options);
// scrollableArea might have changed
base.unbind();
base.bind();
base.updateWidth();
base.toggleHeaders();
};
// Run initializer
base.init();
}
// A plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[name] = function ( options ) {
return this.each(function () {
var instance = $.data(this, 'plugin_' + name);
if (instance) {
if (typeof options === 'string') {
instance[options].apply(instance);
} else {
instance.updateOptions(options);
}
} else if(options !== 'destroy') {
$.data(this, 'plugin_' + name, new Plugin( this, options ));
}
});
};
})(jQuery, window);

File diff suppressed because one or more lines are too long

20
node_modules/sticky-table-headers/license.txt generated vendored Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2011 Jonas Mosbech
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

63
node_modules/sticky-table-headers/package.json generated vendored Normal file
View File

@ -0,0 +1,63 @@
{
"_from": "sticky-table-headers",
"_id": "sticky-table-headers@0.1.24",
"_inBundle": false,
"_integrity": "sha1-euofB5HKOgKwhgzYhe11ehrL84E=",
"_location": "/sticky-table-headers",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "sticky-table-headers",
"name": "sticky-table-headers",
"escapedName": "sticky-table-headers",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/sticky-table-headers/-/sticky-table-headers-0.1.24.tgz",
"_shasum": "7aea1f0791ca3a02b0860cd885ed757a1acbf381",
"_spec": "sticky-table-headers",
"_where": "/var/www/domains/guild",
"author": {
"name": "Jonas Mosbech",
"email": "https://github.com/jmosbech"
},
"bugs": {
"url": "https://github.com/jmosbech/StickyTableHeaders/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "jQuery sticky table headers plugin",
"devDependencies": {
"grunt": "~1.0.1",
"grunt-bower-version": "^0.1.1",
"grunt-contrib-jshint": "~1.1.0",
"grunt-contrib-uglify": "~3.3.0"
},
"homepage": "https://github.com/jmosbech/StickyTableHeaders#readme",
"keywords": [
"jquery",
"sticky",
"table",
"headers",
"jquery-plugin",
"ecosystem:jquery"
],
"license": "MIT",
"main": "js/jquery.stickytableheaders.js",
"name": "sticky-table-headers",
"repository": {
"type": "git",
"url": "git+https://github.com/jmosbech/StickyTableHeaders.git"
},
"scripts": {
"build": "grunt"
},
"unpkg": "js/jquery.stickytableheaders.min.js",
"version": "0.1.24"
}

119
node_modules/sticky-table-headers/readme.md generated vendored Normal file
View File

@ -0,0 +1,119 @@
StickyTableHeaders
==================
So what's it good for? Well, let's say you want to display a long list of fairly uniform tabluar data, like [stock exchange listings](http://online.barrons.com/public/page/majormarket-nysecomposite-A.html) or [sport statistics](https://sports.yahoo.com/nfl/stats/weekly/?sortStatId=PASSING_YARDS&selectedTable=7) but you don't want your users to get lost in the data as they scroll down on the page.
StickyTableHeaders to the rescue: By applying the StickyTableHeaders jQuery plugin to the table, the column headers will stick to the top of the viewport as you scroll down.
Go ahead and [try out a demo](http://jsfiddle.net/jmosbech/stFcx/).
The code is based on [this proof of concept](http://stackoverflow.com/questions/1030043/html-table-headers-always-visible-at-top-of-window-when-viewing-a-large-table/1041566#1041566).
Installation
------------
The best way to install is using [npm](https://www.npmjs.com/):
```bash
npm install sticky-table-headers
```
or [Bower](http://bower.io/):
```bash
bower install StickyTableHeaders
```
or by loading it directly from the [unpkg CDN](https://unpkg.com/sticky-table-headers):
```
<script src="https://unpkg.com/sticky-table-headers"></script>
```
Usage
-----
Initializing the plugin is pretty straight forward:
```js
$('table').stickyTableHeaders();
```
### Tear down
To remove the plugin:
```js
$('table').stickyTableHeaders('destroy');
```
### Trigger an update manually
```js
$(window).trigger('resize.stickyTableHeaders');
```
### Options
You can initialize the plugin with an options map to tweak the behavior. The following options are supported:
#### `fixedOffset`
A number or jQuery object specifying how much the sticky header should be offset from the top of the page:
```js
$('table').stickyTableHeaders({fixedOffset: $('#header')});
```
#### `scrollableArea`
A DOM element or jQuery object. Allows you to overwrite which surrounding element is scrolling. Defaults to `window`. [Check this demo for an example](https://github.com/jmosbech/StickyTableHeaders/tree/master/demo/scrollable-div.html):
```js
$('table').stickyTableHeaders({scrollableArea: $('.scrollable-area')});
```
#### `cacheHeaderHeight`
Performance tweak: When set to `true` the plugin will only recalculate the height of the header cells when the width of the table changes.
Default value: `false`
```js
$('table').stickyTableHeaders({cacheHeaderHeight: true});
```
#### z-index
The plugin uses z-index to make the thead overlay the body. You can override the z-index value by passing in a `zIndex` option:
```js
$('table').stickyTableHeaders({zIndex: 999});
```
### Reinitialize
As described in [pull request #33](https://github.com/jmosbech/StickyTableHeaders/pull/33) responsive pages might need to reinitialize the plugin when the user resizes his browser. This is can be done by calling the plugin with the new options:
```js
$('table').stickyTableHeaders({fixedOffset: [new-offset]});
```
### Events
The plugin triggers the following events on the targeted `<table>` element:
- `clonedHeader.stickyTableHeaders`: When the header clone is created.
- `enabledStickiness.stickyTableHeaders`: When the sticky header is enabled.
- `disabledStickiness.stickyTableHeaders`: When the sticky header is disabled.
Confused?
---------
If any of this is confusing, please check out the [/demo](https://github.com/jmosbech/StickyTableHeaders/tree/master/demo) folder. There are a couple of examples in there. E.g. you can see how to use it with Twitter Bootstrap.
Known Issues
------------
- Internet Explorer: You need to set the padding of the `<th>`s explicitly in the css in order to make the plugin work
- Internet Explorer: Adding horizontal margin to the table causes the header to be misaligned when scrolling. (Issue #10)
- Using the plugin together with [tablesorter](http://tablesorter.com/docs/) breaks in Internet Explorer 8
Browser Support
---------------
The plugin has been verified to work in:
- Chrome 35
- Firefox 29
- Internet Explorer 8-11
- Safari 5
NOTE: It does not work in Internet Explorer 7 (but it degrades nicely)

11
package-lock.json generated Normal file
View File

@ -0,0 +1,11 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"sticky-table-headers": {
"version": "0.1.24",
"resolved": "https://registry.npmjs.org/sticky-table-headers/-/sticky-table-headers-0.1.24.tgz",
"integrity": "sha1-euofB5HKOgKwhgzYhe11ehrL84E="
}
}
}