Repository: sbstjn/timesheet.js
Branch: master
Commit: 1354b057500d
Files: 19
Total size: 30.1 KB
Directory structure:
gitextract_snamz3o5/
├── .gitignore
├── .jshintignore
├── .jshintrc
├── Gruntfile.js
├── LICENSE.md
├── README.md
├── bower.json
├── package.json
├── serve.js
├── source/
│ ├── index.haml
│ ├── javascripts/
│ │ ├── lib.js
│ │ ├── main.js
│ │ └── timesheet.js
│ ├── snippets/
│ │ └── example-date.js
│ └── stylesheets/
│ ├── _normalize.sass
│ ├── style.sass
│ ├── timesheet-white.sass
│ └── timesheet.sass
└── test/
└── timesheet.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
# git config --global core.excludesfile ~/.gitignore_global
# Ignore bundler config
/.bundle
# Ignore the build directory
/build
# Ignore cache
/.sass-cache
/.cache
# Built gh-pages
/gh-pages
# Ignore .DS_store file
.DS_Store
# Ignore Node.js modules
node_modules
================================================
FILE: .jshintignore
================================================
================================================
FILE: .jshintrc
================================================
{
"bitwise": false,
"boss": true,
"browser": true,
"camelcase": true,
"curly": true,
"devel": true,
"eqeqeq": true,
"es3": true,
"expr": true,
"forin": true,
"freeze": true,
"globalstrict": false,
"immed": true,
"indent": 2,
"jquery": true,
"latedef": true,
"laxcomma": true,
"multistr": false,
"newcap": true,
"noarg": true,
"noempty": true,
"nonew": true,
"notypeof": false,
"plusplus": false,
"quotmark": "single",
"regexp": true,
"strict": true,
"trailing": true,
"undef": true,
"unused": true,
"maxparams": 5,
"maxdepth": 4,
"maxstatements": 20,
"maxcomplexity": 10,
"globals": {"module": true, "require": true, "suite": true, "test": true, "__dirname": true}
}
================================================
FILE: Gruntfile.js
================================================
module.exports = function(grunt) {
'use strict';
var fs = require('fs');
grunt.initConfig({
uglify: {
options: {
mangle: false
},
my_target: {
files: {
'dist/timesheet.min.js': ['source/javascripts/timesheet.js']
}
}
},
sass: {
gh: {
options: {
style: 'compressed'
},
files: {
'gh-pages/styles/style.css': 'source/stylesheets/style.sass'
}
},
dist: {
options: {
style: 'compressed'
},
files: {
'dist/timesheet.min.css': 'source/stylesheets/timesheet.sass',
'dist/timesheet-white.min.css': 'source/stylesheets/timesheet-white.sass'
}
}
},
jshint: {
all: {
src: [
'source/javascripts/*.js'
],
options: {
jshintrc: '.jshintrc'
}
}
},
simplemocha: {
options: {
globals: ['should'],
timeout: 3000,
ignoreLeaks: false,
grep: '',
ui: 'tdd',
reporter: 'spec'
},
all: { src: ['test/**/*.js'] }
},
express: {
options: {
port: 8080
},
dev: {
options: {
script: __dirname + '/serve.js'
}
}
},
watch: {
scripts: {
files: 'source/javascripts/*.js',
tasks: ['simplemocha', 'jshint', 'uglify'],
options: {
interrupt: true,
}
},
styles: {
files: 'source/stylesheets/*.sass',
tasks: ['sass'],
options: {
interrupt: true,
}
}
},
haml: {
gh: {
files: {
'gh-pages/index.html': 'source/index.haml'
},
options: {
context: {
code: fs.readFileSync(__dirname + '/source/snippets/example-date.js')
}
}
}
},
copy: {
gh: {
files: [
{expand: false, src: __dirname + '/source/javascripts/lib.js', dest: __dirname + '/gh-pages/script/lib.js'},
{expand: false, src: __dirname + '/source/javascripts/main.js', dest: __dirname + '/gh-pages/script/main.js'},
{expand: false, src: __dirname + '/dist/timesheet.min.js', dest: __dirname + '/gh-pages/script/timesheet.min.js'},
{expand: false, src: __dirname + '/dist/timesheet.min.css', dest: __dirname + '/gh-pages/styles/timesheet.css'},
{expand: false, src: __dirname + '/dist/timesheet-white.min.css', dest: __dirname + '/gh-pages/styles/timesheet-white.css'},
{expand: false, src: __dirname + '/dist/timesheet.min.css.map', dest: __dirname + '/gh-pages/styles/timesheet.css.map'},
{expand: false, src: __dirname + '/dist/timesheet-white.min.css.map', dest: __dirname + '/gh-pages/styles/timesheet-white.css.map'}
]
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-haml');
// Default task
grunt.registerTask('default', ['build']);
grunt.registerTask('build', ['simplemocha', 'jshint', 'uglify', 'sass']);
grunt.registerTask('server', ['express:dev', 'watch' ])
grunt.registerTask('gh', ['build', 'haml:gh', 'sass:gh', 'copy:gh']);
};
================================================
FILE: LICENSE.md
================================================
# The MIT License (MIT)
Copyright (c) 2014-2015 Sebastian Müller
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.
================================================
FILE: README.md
================================================
# Timesheet.js
Simple JavaScript library to create HTML time sheets. Wrapped in an example project using Middleman …

You only have to include `dist/timesheet.js` and `dist/timesheet.css` in your HTML and initialize Timesheet.js with:
```HTML
```
```javascript
new Timesheet('timesheet', 2002, 2013, [
['2002', '09/2002', 'A freaking awesome time', 'lorem'],
['06/2002', '09/2003', 'Some great memories', 'ipsum'],
['2003', 'Had very bad luck'],
['10/2003', '2006', 'At least had fun', 'dolor'],
['02/2005', '05/2006', 'Enjoyed those times as well', 'ipsum'],
['07/2005', '09/2005', 'Bad luck again', 'default'],
['10/2005', '2008', 'For a long time nothing happened', 'dolor'],
['01/2008', '05/2009', 'LOST Season #4', 'lorem'],
['01/2009', '05/2009', 'LOST Season #4', 'lorem'],
['02/2010', '05/2010', 'LOST Season #5', 'lorem'],
['09/2008', '06/2010', 'FRINGE #1 & #2', 'ipsum']
]);
```
### Bower
`$ > bower install https://github.com/sbstjn/timesheet.js.git`
## Grunt commands
Use `grunt` to build all JavaScript and StyleSheet files located inside `dist/`.
Use `grunt server` to start a local web server on [localhost:8080](http://localhost:8080) to customize Timesheet.js, afterwards run `grunt` to compile all needed files.
Use `grunt gh` to generate the site and files available at [sbstjn.github.io/timesheet.js](http://sbstjn.github.io/timesheet.js) into the `gh-pages` folder.
## License
Timesheet.js is licensed under MIT License.
================================================
FILE: bower.json
================================================
{
"name": "timesheet.js",
"homepage": "https://sbstjn.github.io/timesheet.js/",
"authors": [
"sbstjn "
],
"description": "With Timesheet.js you can easily create simple time and data sheets or timelines using HTML5, JavaScript and CSS3. Yep, it's a Vanilla JS library!",
"main": ["dist/timesheet.min.js", "dist/timesheet.min.css"],
"moduleType": [
"amd"
],
"keywords": [
"timeline",
"timesheet",
"timebar",
"line",
"bar",
"graph",
"visualize",
"chart"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"screen.png",
"source",
"Gruntfile.js",
"package.json"
]
}
================================================
FILE: package.json
================================================
{
"name": "timesheet.js",
"version": "1.0.1",
"description": "With Timesheet.js you can easily create simple time and data sheets or timelines using HTML5, JavaScript and CSS3. Yep, it's a Vanilla JS library!",
"author": "sbstjn ",
"devDependencies": {
"consolidate": "^0.13.1",
"express": "^4.12.4",
"grunt": "~0.4.1",
"grunt-cli": "~0.1.11",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-jshint": "~0.7.2",
"grunt-contrib-sass": "^0.7.3",
"grunt-contrib-uglify": "^0.4.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-express-server": "^0.5.1",
"grunt-haml": "^0.9.0",
"grunt-jslint": "~1.1.1",
"grunt-simple-mocha": "^0.4.0",
"haml": "^0.4.3",
"hamljs": "^0.6.2",
"node-sass": "^3.2.0"
}
}
================================================
FILE: serve.js
================================================
var express = require('express');
var sass = require('node-sass');
var fs = require('fs');
var app = express();
var engines = require('consolidate');
app.engine('haml', engines.haml);
app.set('views', __dirname + '/source');
app.get('/script/lib.js', function(req, res) {
res.end(fs.readFileSync(__dirname + '/source/javascripts/lib.js'));
});
app.get('/script/main.js', function(req, res) {
res.end(fs.readFileSync(__dirname + '/source/javascripts/main.js'));
});
app.get('/script/timesheet.min.js', function(req, res) {
res.end(fs.readFileSync(__dirname + '/dist/timesheet.min.js'));
});
app.get('/styles/timesheet.css', function(req, res) {
res.end(fs.readFileSync(__dirname + '/dist/timesheet.min.css'));
});
app.get('/styles/timesheet-white.css', function(req, res) {
res.end(fs.readFileSync(__dirname + '/dist/timesheet-white.min.css'));
});
app.get('/styles/style.css', function(req, res) {
sass.render({
file: __dirname + '/source/stylesheets/style.sass',
outputStyle: req.query.style || ""
}, function(err, result) {
res.end(result.css.toString());
});
});
app.get('/', function (req, res) {
res.render('index.haml', {
code: fs.readFileSync(__dirname + '/source/snippets/example-date.js') + ''
});
});
var server = app.listen(process.env.PORT || 3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
================================================
FILE: source/index.haml
================================================
!!! 5
%html
%head
%title Timesheet.js - Beautiful time tables with HTML, JavaScript and CSS …
%meta{charset: 'utf-8'}
%meta{content: 'IE=edge,chrome=1', 'http-equiv': 'X-UA-Compatible'}
%meta{property: 'og:title', content: 'Timesheet.js - Beautiful time tables with HTML, JavaScript and CSS …'}
%meta{property: 'og:description', content: 'With Timesheet.js you can easily create simple time and data sheets or timelines using HTML5, JavaScript and CSS3. Yep, it\'s a Vanilla JS library!'}
%meta{property: 'og:url', content: 'https://sbstjn.github.io/timesheet.js/'}
%meta{property: 'og:image', content: 'https://raw.githubusercontent.com/sbstjn/timesheet.js/master/screen.png'}
%meta{property: 'fb:admins', content: '669118929'}
%script{type: 'text/javascript', src: './script/lib.js'}
%script{type: 'text/javascript', src: './script/timesheet.min.js'}
%script{type: 'text/javascript', src: './script/main.js'}
%link{rel: 'stylesheet', type: "text/css", href: "./styles/style.css"}
%link{rel: 'stylesheet', type: "text/css", href: "./styles/timesheet.css"}
%link{rel: 'stylesheet', type: "text/css", href: "./styles/timesheet-white.css"}
%link{rel: 'stylesheet', type: "text/css", href: "https://fonts.jimstatic.com/css?family=Oxygen+Mono:400,600,800"}
%link{rel: 'stylesheet', type: "text/css", href: "https://fonts.jimstatic.com/css?family=Open+Sans:400,600,800"}
%link{rel: 'stylesheet', type: "text/css", href: "https://fonts.jimstatic.com/css?family=Signika+Negative:300,400,600,700"}
%body.black
#box
#box-inner
%h1
Timesheet.js
%p Visualize your data and events with sexy HTML5 and CSS3. Create simple time sheets with sneaky JavaScript. Style them with CSS and have mobile fun as well …
#timesheet-default
%p Just include Timesheet.js and configure your data. No external dependencies, no jQuery needed and of course no Angular.JS! Just a few lines JavaScript to generate a beautiful HTML5 layout and some really delicious CSS to be customized by almighty you.
%code
%pre!='<script src="/javascripts/timesheet.js" type="text/javascript" />'
%p Create a simple time sheet based on a JS array of events:
%code
%pre!=code
%p It's that simple to use Timesheet.js. So, have a nice day, thank you for smoking and maybe try using Timesheet.js with custom styles …
%p.footer Timesheet.js is licensed under MIT License
Cheers to Cheeaun and Ilya
❤
dark | light
%span
================================================
FILE: source/javascripts/lib.js
================================================
(function() {
'use strict';
var Lib = {
/* http://www.dustindiaz.com/smallest-domready-ever */
/* jshint -W030 */
ready: function r(f){ /in/.test(document.readyState)?setTimeout(function () {Lib.ready(f);},9):f(); }
};
window.Lib = Lib;
})();
================================================
FILE: source/javascripts/main.js
================================================
/* global Lib, Timesheet */
(function(){
'use strict';
Lib.ready(function() {
console.log('ads');
/* jshint -W031 */
new Timesheet('timesheet-default', 2002, 2013, [
['2002', '09/2002', 'A freaking awesome time', 'lorem'],
['06/2002', '09/2003', 'Some great memories', 'ipsum'],
['2003', 'Had very bad luck'],
['10/2003', '2006', 'At least had fun', 'dolor'],
['02/2005', '05/2006', 'Enjoyed those times as well', 'ipsum'],
['07/2005', '09/2005', 'Bad luck again', 'default'],
['10/2005', '2008', 'For a long time nothing happened', 'dolor'],
['01/2008', '05/2009', 'LOST Season #4', 'lorem'],
['01/2009', '05/2009', 'LOST Season #4', 'sit'],
['02/2010', '05/2010', 'LOST Season #5', 'lorem'],
['09/2008', '06/2010', 'FRINGE #1 & #2', 'ipsum']
]);
document.querySelector('#switch-dark').addEventListener('click', function() {
document.querySelector('body').className = 'index black';
});
document.querySelector('#switch-light').addEventListener('click', function() {
document.querySelector('body').className = 'index white';
});
});
})();
================================================
FILE: source/javascripts/timesheet.js
================================================
(function() {
'use strict';
/**
* Initialize a Timesheet
*/
var Timesheet = function(container, min, max, data) {
this.data = [];
this.year = {
min: min,
max: max
};
this.parse(data || []);
if (typeof document !== 'undefined') {
this.container = (typeof container === 'string') ? document.querySelector('#'+container) : container;
this.drawSections();
this.insertData();
}
};
/**
* Insert data into Timesheet
*/
Timesheet.prototype.insertData = function() {
var html = [];
var widthMonth = this.container.querySelector('.scale section').offsetWidth;
for (var n = 0, m = this.data.length; n < m; n++) {
var cur = this.data[n];
var bubble = this.createBubble(widthMonth, this.year.min, cur.start, cur.end);
var line = [
'',
'' + bubble.getDateLabel() + ' ',
'' + cur.label + ''
].join('');
html.push('' + line + '');
}
this.container.innerHTML += '';
};
/**
* Draw section labels
*/
Timesheet.prototype.drawSections = function() {
var html = [];
for (var c = this.year.min; c <= this.year.max; c++) {
html.push('');
}
this.container.className = 'timesheet color-scheme-default';
this.container.innerHTML = '' + html.join('') + '
';
};
/**
* Parse data string
*/
Timesheet.prototype.parseDate = function(date) {
if (date.indexOf('/') === -1) {
date = new Date(parseInt(date, 10), 0, 1);
date.hasMonth = false;
} else {
date = date.split('/');
date = new Date(parseInt(date[1], 10), parseInt(date[0], 10)-1, 1);
date.hasMonth = true;
}
return date;
};
/**
* Parse passed data
*/
Timesheet.prototype.parse = function(data) {
for (var n = 0, m = data.length; n this.year.max) {
this.year.max = end.getFullYear();
} else if (beg.getFullYear() > this.year.max) {
this.year.max = beg.getFullYear();
}
this.data.push({start: beg, end: end, label: lbl, type: cat});
}
};
/**
* Wrapper for adding bubbles
*/
Timesheet.prototype.createBubble = function(wMonth, min, start, end) {
return new Bubble(wMonth, min, start, end);
};
/**
* Timesheet Bubble
*/
var Bubble = function(wMonth, min, start, end) {
this.min = min;
this.start = start;
this.end = end;
this.widthMonth = wMonth;
};
/**
* Format month number
*/
Bubble.prototype.formatMonth = function(num) {
num = parseInt(num, 10);
return num >= 10 ? num : '0' + num;
};
/**
* Calculate starting offset for bubble
*/
Bubble.prototype.getStartOffset = function() {
return (this.widthMonth/12) * (12 * (this.start.getFullYear() - this.min) + this.start.getMonth());
};
/**
* Get count of full years from start to end
*/
Bubble.prototype.getFullYears = function() {
return ((this.end && this.end.getFullYear()) || this.start.getFullYear()) - this.start.getFullYear();
};
/**
* Get count of all months in Timesheet Bubble
*/
Bubble.prototype.getMonths = function() {
var fullYears = this.getFullYears();
var months = 0;
if (!this.end) {
months += !this.start.hasMonth ? 12 : 1;
} else {
if (!this.end.hasMonth) {
months += 12 - (this.start.hasMonth ? this.start.getMonth() : 0);
months += 12 * (fullYears-1 > 0 ? fullYears-1 : 0);
} else {
months += this.end.getMonth() + 1;
months += 12 - (this.start.hasMonth ? this.start.getMonth() : 0);
months += 12 * (fullYears-1);
}
}
return months;
};
/**
* Get bubble's width in pixel
*/
Bubble.prototype.getWidth = function() {
return (this.widthMonth/12) * this.getMonths();
};
/**
* Get the bubble's label
*/
Bubble.prototype.getDateLabel = function() {
return [
(this.start.hasMonth ? this.formatMonth(this.start.getMonth() + 1) + '/' : '' ) + this.start.getFullYear(),
(this.end ? '-' + ((this.end.hasMonth ? this.formatMonth(this.end.getMonth() + 1) + '/' : '' ) + this.end.getFullYear()) : '')
].join('');
};
window.Timesheet = Timesheet;
})();
================================================
FILE: source/snippets/example-date.js
================================================
new Timesheet('timesheet-default', 2002, 2013, [
['2002', '09/2002', 'A freaking awesome time', 'lorem'],
['06/2002', '09/2003', 'Some great memories', 'ipsum'],
['2003', 'Had very bad luck'],
['10/2003', '2006', 'At least had fun', 'dolor'],
['02/2005', '05/2006', 'Enjoyed those times as well', 'ipsum'],
['07/2005', '09/2005', 'Bad luck again', 'default'],
['10/2005', '2008', 'For a long time nothing happened', 'dolor'],
['01/2008', '05/2009', 'LOST Season #4', 'lorem'],
['01/2009', '05/2009', 'LOST Season #4', 'lorem'],
['02/2010', '05/2010', 'LOST Season #5', 'lorem'],
['09/2008', '06/2010', 'FRINGE #1 & #2', 'ipsum']
]);
================================================
FILE: source/stylesheets/_normalize.sass
================================================
article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary
display: block
audio, canvas, video
display: inline-block
audio:not([controls])
display: none
height: 0
[hidden]
display: none
html
font-family: sans-serif
-webkit-text-size-adjust: 100%
-ms-text-size-adjust: 100%
html, body, p, ul, li, h1, h2, h3, h4, h5, img, fieldset, input, textarea, select
margin: 0
padding: 0
border: 0
a
&:focus
outline: 0
&:active, &:hover
outline: 0
h1
font-size: 2em
h2
font-size: 1em
strong
font-weight: bold
dfn
font-style: italic
code, kbd, pre, samp
font-family: monospace, serif
font-size: 1em
pre
white-space: pre
white-space: pre-wrap
word-wrap: break-word
q
quotes: "\201C" "\201D" "\2018" "\2019"
small
font-size: 80%
sub
font-size: 75%
line-height: 0
position: relative
vertical-align: baseline
bottom: -0.25em
sup
font-size: 75%
line-height: 0
position: relative
vertical-align: baseline
top: -0.5em
img
border: 0
legend
border: 0
padding: 0
button, input, select, textarea
font-size: 100%
textarea, input
outline: none
input
line-height: normal
ul, ul li
list-style-type: none
margin: 0
padding: 0
button::-moz-focus-inner, input::-moz-focus-inner
border: 0
padding: 0
textarea
overflow: auto
vertical-align: top
table
border-collapse: collapse
border-spacing: 0
================================================
FILE: source/stylesheets/style.sass
================================================
@import 'normalize'
html, body
margin: 0
padding: 0
width: 100%
height: 100%
*
transition: all 0.5s ease
body.black
background-color: rgba(61, 61, 61, 1)
body.white
background-color: rgba(230, 230, 230, 1)
#box
width: 100%
height: 100%
#box-inner
height: 100%
text-align: center
vertical-align: middle
h1
font-family: 'Open Sans'
font-size: 60pt
font-weight: 800
line-height: 240px
p
width: 680px
text-align: left
font-family: 'Open Sans'
font-weight: 400
margin: 20px auto
line-height: 24px
code
pre
margin: 0 auto
width: 670px
padding: 10px 8px
font-family: 'Oxygen Mono'
font-size: 11px
font-weight: 600
code, pre
text-align: left
.footer
margin-top: 65px
text-align: center
font-size: 12px
font-weight: 300
a
font-weight: 300
a, a:hover, a:active, a:visited
font-weight: 300
a, a:hover, a:visited, a:active
font-weight: 600
text-decoration: none
.center
text-align: center
.white
h1
color: RGBA(29, 175, 234, 1)
p
color: rgba(100, 100, 100, 1)
p span
color: RGBA(29, 175, 234, 1)
font-weight: 600
code
pre
color: rgba(40, 40, 40, 1)
background-color: rgba(250, 250, 250, 1)
.footer
color: rgba(100, 100, 100, 1)
a
color: rgba(100, 100, 100, 1)
span
a
color: RGBA(29, 175, 234, 1)
.black
h1
color: rgba(255, 145, 18, 1)
p
color: rgba(220, 220, 220, 1)
code
pre
background-color: rgba(100, 100, 100, 1)
color: rgba(190, 190, 190, 1)
a, a:hover, a:visited, a:active, p span
color: rgba(255, 145, 18, 1)
.footer
color: rgba(100, 100, 100, 1)
a
color: rgba(100, 100, 100, 1)
span
a
color: rgba(255, 145, 18, 1)
#example-data
margin: 0 auto
width: 680px
height: 300px
background-color: rgba(100, 100, 100, 1)
p
text-align: right
font-size: 12px
a
color: rgba(255, 145, 18, 1)
text-decoration: none
.version
font-size: 12px
line-height: 17px
margin: 80px auto
a, a:visited, a:hover, a:active
font-family: 'Open Sans'
color: rgba(255, 145, 18, 1)
text-decoration: none
span
font-weight: 600
color: white
span
color: rgba(255, 145, 18, 1)
font-weight: 600
================================================
FILE: source/stylesheets/timesheet-white.sass
================================================
.white
.timesheet
width: 720px
height: 292px
margin: 0 auto
.timesheet
border-top: 1px solid rgba(60, 60, 60, 0.3)
background-color: rgba(251, 251, 251, 1)
position: relative
&.color-scheme-default
.bubble-default
background-color: RGBA(252, 70, 74, 1) // red
.bubble-lorem
background-color: RGBA(154, 202, 39, 1) // green
.bubble-ipsum
background-color: RGBA(60, 182, 227, 1) // blue
.bubble-dolor
background-color: RGBA(244, 207, 48, 1) // yellow
.bubble-sit
background-color: RGBA(169, 105, 202, 1) // cyan
&.color-scheme-alternative
.bubble-default
background-color: rgba(243, 85, 46, 1)
.bubble-lorem
background-color: rgba(136, 195, 58, 1)
.bubble-ipsum
background-color: rgba(67, 106, 224, 1)
.bubble-dolor
background-color: rgba(244, 210, 52, 1)
.bubble-sit
background-color: rgba(112, 125, 134, 1)
.scale
height: 100%
position: absolute
top: 0
left: 0
float: left
section
float: left
width: 59px
color: rgba(50, 50, 50, 0.8)
font-family: 'Signika Negative'
font-size: 13px
line-height: 24px
font-weight: 300
border-left: 1px dashed rgba(50, 50, 50, 0.1)
height: 100%
.data
margin: 28px 0 0 0
padding: 0
text-align: left
list-style-type: none
color: rgba(250, 250, 250, 0.8)
font-family: 'Signika Negative'
font-size: 13px
overflow: hidden
li
margin: 0 0 3px 0
line-height: 22px
height: 21px
display: block
cursor: pointer
clear: both
position: relative
white-space: nowrap
&:hover
.bubble
opacity: 1
.date
color: rgba(121, 121, 121, 1)
font-size: 14px
.label
font-weight: lighter
font-size: 14px
padding-left: 5px
line-height: 21px
color: rgba(51, 51, 50, 1)
white-space: nowrap
.bubble
width: 24px
height: 7px
display: block
float: left
position: relative
top: 7px
border-radius: 4px
margin: 0 10px 0 0
opacity: 0.7
================================================
FILE: source/stylesheets/timesheet.sass
================================================
.timesheet
width: 720px
height: 292px
margin: 0 auto
.timesheet
border-top: 1px solid rgba(250, 250, 250, 0.5)
background-color: rgba(51, 51, 51, 1)
position: relative
&.color-scheme-default
.bubble-default
background-color: RGBA(252, 70, 74, 1) // red
.bubble-lorem
background-color: RGBA(154, 202, 39, 1) // green
.bubble-ipsum
background-color: RGBA(60, 182, 227, 1) // blue
.bubble-dolor
background-color: RGBA(244, 207, 48, 1) // yellow
.bubble-sit
background-color: RGBA(169, 105, 202, 1) // cyan
&.color-scheme-alternative
.bubble-default
background-color: rgba(243, 85, 46, 1)
.bubble-lorem
background-color: rgba(136, 195, 58, 1)
.bubble-ipsum
background-color: rgba(67, 106, 224, 1)
.bubble-dolor
background-color: rgba(244, 210, 52, 1)
.bubble-sit
background-color: rgba(112, 125, 134, 1)
.scale
height: 100%
position: absolute
top: 0
left: 0
float: left
section
float: left
width: 59px
text-align: center
color: rgba(250, 250, 250, 0.8)
font-family: 'Signika Negative'
font-size: 13px
line-height: 24px
font-weight: lighter
border-left: 1px dashed rgba(250, 250, 250, 0.2)
height: 100%
.data
margin: 28px 0 0 0
padding: 0
text-align: left
list-style-type: none
color: rgba(250, 250, 250, 0.8)
font-family: 'Signika Negative'
font-size: 13px
overflow: hidden
li
margin: 0 0 3px 0
line-height: 22px
height: 21px
display: block
clear: both
position: relative
white-space: nowrap
&:hover
.bubble
opacity: 1
.date
color: rgba(181, 181, 181, 1)
font-size: 14px
.label
font-weight: lighter
font-size: 14px
padding-left: 5px
line-height: 21px
color: rgba(151, 151, 150, 1)
white-space: nowrap
.bubble
width: 24px
height: 7px
display: block
float: left
position: relative
top: 7px
border-radius: 4px
margin: 0 10px 0 0
opacity: 0.7
#timesheet-alternative
background-color: RGBA(247, 247, 247, 1)
border-radius: 5px
section
color: RGBA(63, 68, 72, 1)
border-left: 1px dashed RGBA(63, 68, 72, 0.2)
&:first-child
border-left: 1px dashed transparent
.date
display: none
.bubble
margin-right: 7px
.label
padding-left: 0px
color: RGBA(48, 48, 48, 1)
================================================
FILE: test/timesheet.js
================================================
/**
* Load Timesheet lib and fake a window object …
*/
window = {};
require(__dirname + '/../source/javascripts/timesheet.js');
var assert = require('assert');
suite('Timesheet', function() {
test('Calculation', function(done) {
var TS = new window.Timesheet();
assert.equal(12, (TS.createBubble(60, 2012, TS.parseDate('2002'), TS.parseDate('2002'))).getMonths());
assert.equal(12, (TS.createBubble(60, 2012, TS.parseDate('2002'), TS.parseDate('2003'))).getMonths());
assert.equal(24, (TS.createBubble(60, 2012, TS.parseDate('2002'), TS.parseDate('2004'))).getMonths());
assert.equal(9, (TS.createBubble(60, 2012, TS.parseDate('04/2002'), TS.parseDate('2002'))).getMonths());
assert.equal(9, (TS.createBubble(60, 2012, TS.parseDate('04/2002'), TS.parseDate('2003'))).getMonths());
assert.equal(21, (TS.createBubble(60, 2012, TS.parseDate('04/2002'), TS.parseDate('2004'))).getMonths());
assert.equal(13, (TS.createBubble(60, 2012, TS.parseDate('04/2002'), TS.parseDate('04/2003'))).getMonths());
assert.equal(25, (TS.createBubble(60, 2012, TS.parseDate('04/2002'), TS.parseDate('04/2004'))).getMonths());
assert.equal(1, (TS.createBubble(60, 2012, TS.parseDate('04/2002'))).getMonths());
assert.equal(12, (TS.createBubble(60, 2012, TS.parseDate('2002'))).getMonths());
done();
});
});