colors for visual grouping of customer, projects and activities (#751)
This commit is contained in:
@@ -6,34 +6,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@import "~bootstrap-sass/assets/stylesheets/bootstrap/variables";
|
@import "~bootstrap-sass/assets/stylesheets/bootstrap/variables";
|
||||||
|
@import 'variables';
|
||||||
.error-page {
|
@import 'error-page';
|
||||||
margin-bottom: 50px;
|
@import 'print';
|
||||||
}
|
|
||||||
|
|
||||||
@media print{
|
|
||||||
.sf-toolbar, .control-sidebar {display: none !important;}
|
|
||||||
}
|
|
||||||
|
|
||||||
@import 'content';
|
@import 'content';
|
||||||
@import 'toolbar';
|
@import 'toolbar';
|
||||||
|
@import 'sidebar';
|
||||||
/* ================================ SIDEBAR ================================ */
|
@import 'footer';
|
||||||
|
|
||||||
/* Used for the Sidebar UserPanel (which is deactivated right now) */
|
|
||||||
.user-panel>.info {
|
|
||||||
left: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ================================ FOOTER ================================ */
|
|
||||||
|
|
||||||
footer.main-footer {
|
|
||||||
padding: 5px;
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@import 'invoice';
|
@import 'invoice';
|
||||||
@import 'datatable';
|
@import 'datatable';
|
||||||
|
@import 'datatable-extensions';
|
||||||
@import 'calendar';
|
@import 'calendar';
|
||||||
@import 'dashboard';
|
@import 'dashboard';
|
||||||
@import 'navbar';
|
@import 'navbar';
|
||||||
|
|||||||
63
assets/sass/datatable-extensions.scss
Normal file
63
assets/sass/datatable-extensions.scss
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
table.dataTable {
|
||||||
|
/* action column */
|
||||||
|
.actions {
|
||||||
|
width: 90px;
|
||||||
|
li.delete a {
|
||||||
|
color: #dd4b39;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tr {
|
||||||
|
/* summary row - provided in the users own timesheet table */
|
||||||
|
&.summary td {
|
||||||
|
font-weight: bold;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
&.open-edit {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
/*
|
||||||
|
Make sure that the action buttons do not line-break if another column takes all available space
|
||||||
|
See https://github.com/twbs/bootstrap/issues/9939#issuecomment-37682952
|
||||||
|
*/
|
||||||
|
.btn-group {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
font-size: 85%;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: .3em .6em .3em;
|
||||||
|
}
|
||||||
|
span.label-activity,
|
||||||
|
span.label-project,
|
||||||
|
span.label-customer {
|
||||||
|
display: inline-block;
|
||||||
|
.dot {
|
||||||
|
height: 10px;
|
||||||
|
width: 10px;
|
||||||
|
background-color: $gray-lte;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: unset;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
border-bottom: 1px dotted $gray-lte;
|
||||||
|
&:hover {
|
||||||
|
border-bottom: 1px dotted darken($gray-lte, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
span.label-invisible {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ section.content .overlay,
|
|||||||
.overlay-wrapper .overlay {
|
.overlay-wrapper .overlay {
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
background: rgba(255, 255, 255, 0.7);
|
background: rgba(255, 255, 255, 0.7);
|
||||||
border-radius: 3px;
|
border-radius: $box-border-radius;
|
||||||
}
|
}
|
||||||
.box .overlay.dark,
|
.box .overlay.dark,
|
||||||
section.content .overlay.dark,
|
section.content .overlay.dark,
|
||||||
@@ -264,37 +264,3 @@ div.dataTables_scrollHead table.table-bordered {
|
|||||||
.table-striped.dataTable tbody tr.active:nth-child(odd) th {
|
.table-striped.dataTable tbody tr.active:nth-child(odd) th {
|
||||||
background-color: #017ebc;
|
background-color: #017ebc;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable {
|
|
||||||
/* action column */
|
|
||||||
.actions {
|
|
||||||
width: 90px;
|
|
||||||
li.delete a {
|
|
||||||
color: #dd4b39;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* summary row, like the timesheet table provides */
|
|
||||||
tr {
|
|
||||||
&.summary td {
|
|
||||||
font-weight: bold;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
&.open-edit {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
td {
|
|
||||||
/*
|
|
||||||
Make sure that the action buttons do not line-break if another column takes all available space
|
|
||||||
See https://github.com/twbs/bootstrap/issues/9939#issuecomment-37682952
|
|
||||||
*/
|
|
||||||
.btn-group {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.label {
|
|
||||||
font-size: 85%;
|
|
||||||
font-weight: 500;
|
|
||||||
padding: .3em .6em .3em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
10
assets/sass/error-page.scss
Normal file
10
assets/sass/error-page.scss
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.error-page {
|
||||||
|
margin-bottom: 50px;
|
||||||
|
}
|
||||||
11
assets/sass/footer.scss
Normal file
11
assets/sass/footer.scss
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
footer.main-footer {
|
||||||
|
padding: 5px;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
@@ -76,16 +76,3 @@ li.open .ticktac i.running{
|
|||||||
padding-top: 0px;
|
padding-top: 0px;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@media (min-width: $screen-sm-min) {
|
|
||||||
.sidebar-mini.sidebar-collapse .sidebar-menu li.header {
|
|
||||||
border-top-width: 1px;
|
|
||||||
border-top-style: solid;
|
|
||||||
display: block !important;
|
|
||||||
margin-top: 16px;
|
|
||||||
opacity: 0.4;
|
|
||||||
span {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
10
assets/sass/print.scss
Normal file
10
assets/sass/print.scss
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media print{
|
||||||
|
.sf-toolbar, .control-sidebar {display: none !important;}
|
||||||
|
}
|
||||||
41
assets/sass/sidebar.scss
Normal file
41
assets/sass/sidebar.scss
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* UserPanel is deactivated right now */
|
||||||
|
/*
|
||||||
|
.user-panel>.info {
|
||||||
|
left: 80px;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Right sidebar with additional tabs for personal settings and "About Kimai" section */
|
||||||
|
/*
|
||||||
|
.control-sidebar {
|
||||||
|
select {
|
||||||
|
color: $input-color;
|
||||||
|
background-color: $input-bg;
|
||||||
|
}
|
||||||
|
div.image {
|
||||||
|
img.img-circle {
|
||||||
|
max-width: 34px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
@media (min-width: $screen-sm-min) {
|
||||||
|
.sidebar-mini.sidebar-collapse .sidebar-menu li.header {
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-top-style: solid;
|
||||||
|
display: block !important;
|
||||||
|
margin-top: 16px;
|
||||||
|
opacity: 0.4;
|
||||||
|
span {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,19 +12,6 @@
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Right sidebar with additional tabs for personal settings and "About Kimai" section */
|
|
||||||
.control-sidebar {
|
|
||||||
select {
|
|
||||||
color: $input-color;
|
|
||||||
background-color: $input-bg;
|
|
||||||
}
|
|
||||||
div.image {
|
|
||||||
img.img-circle {
|
|
||||||
max-width: 34px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-pad {
|
.toolbar-pad {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
126
assets/sass/variables.scss
Normal file
126
assets/sass/variables.scss
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple one to one clone of /node_modules/admin-lte/build/less/variables.less
|
||||||
|
*/
|
||||||
|
|
||||||
|
// COLORS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
// Primary
|
||||||
|
//$light-blue: #3c8dbc;
|
||||||
|
// Danger
|
||||||
|
//$red: #dd4b39;
|
||||||
|
// Success
|
||||||
|
//$green: #00a65a;
|
||||||
|
// Info
|
||||||
|
//$aqua: #00c0ef;
|
||||||
|
// Warning
|
||||||
|
//$yellow: #f39c12;
|
||||||
|
//$blue: #0073b7;
|
||||||
|
//$navy: #001F3F;
|
||||||
|
//$teal: #39CCCC;
|
||||||
|
//$olive: #3D9970;
|
||||||
|
//$lime: #01FF70;
|
||||||
|
//$orange: #FF851B;
|
||||||
|
//$fuchsia: #F012BE;
|
||||||
|
//$purple: #605ca8;
|
||||||
|
//$maroon: #D81B60;
|
||||||
|
//$black: #111;
|
||||||
|
$gray-lte: #d2d6de;
|
||||||
|
|
||||||
|
// LAYOUT
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Side bar and logo width
|
||||||
|
//$sidebar-width: 230px;
|
||||||
|
//
|
||||||
|
// Link colors (Aka: <a> tags)
|
||||||
|
//$link-color: $light-blue;
|
||||||
|
//$link-hover-color: lighten($link-color, 15%);
|
||||||
|
//
|
||||||
|
// Body background (Affects main content background only)
|
||||||
|
//$body-bg: #ecf0f5; // DEPRECATED
|
||||||
|
//$content-bg: #ecf0f5;
|
||||||
|
//
|
||||||
|
// SIDEBAR SKINS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Dark sidebar
|
||||||
|
//$sidebar-dark-bg: #222d32;
|
||||||
|
//$sidebar-dark-hover-bg: darken($sidebar-dark-bg, 2%);
|
||||||
|
//$sidebar-dark-color: lighten($sidebar-dark-bg, 60%);
|
||||||
|
//$sidebar-dark-hover-color: #fff;
|
||||||
|
//$sidebar-dark-submenu-bg: lighten($sidebar-dark-bg, 5%);
|
||||||
|
//$sidebar-dark-submenu-color: lighten($sidebar-dark-submenu-bg, 40%);
|
||||||
|
//$sidebar-dark-submenu-hover-color: #fff;
|
||||||
|
//
|
||||||
|
// Light sidebar
|
||||||
|
//$sidebar-ligh//t-bg: #f9fafc;
|
||||||
|
//$sidebar-light-hover-bg: lighten(#f0f0f1, 1.5%);
|
||||||
|
//$sidebar-light-color: #444;
|
||||||
|
//$sidebar-light-hover-color: #000;
|
||||||
|
//$sidebar-light-submenu-bg: $sidebar-light-hover-bg;
|
||||||
|
//$sidebar-light-submenu-color: #777;
|
||||||
|
//$sidebar-light-submenu-hover-color: #000;
|
||||||
|
//
|
||||||
|
// sidebar-expanded-on-hover
|
||||||
|
//$sidebar-expanded-shadow: 3px 0 8px rgba(0,0,0,.125);
|
||||||
|
//
|
||||||
|
// CONTROL SIDEBAR
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$control-sidebar-width: $sidebar-width;
|
||||||
|
//
|
||||||
|
// BOXES
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$box-border-color: #f4f4f4;
|
||||||
|
$box-border-radius: 3px;
|
||||||
|
//$box-footer-bg: #fff;
|
||||||
|
//$box-boxshadow: 0 1px 1px rgba(0, 0, 0, .1);
|
||||||
|
//$box-padding: 10px;
|
||||||
|
//
|
||||||
|
// Box variants
|
||||||
|
//$box-default-border-top-color: #d2d6de;
|
||||||
|
//
|
||||||
|
// BUTTONS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$btn-boxshadow: none;
|
||||||
|
//
|
||||||
|
// PROGRESS BARS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$progress-bar-border-radius: 1px;
|
||||||
|
//$progress-bar-sm-border-radius: 1px;
|
||||||
|
//$progress-bar-xs-border-radius: 1px;
|
||||||
|
//
|
||||||
|
// FORMS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$input-radius: 0;
|
||||||
|
//
|
||||||
|
// BUTTONS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Border radius for non flat buttons
|
||||||
|
//$btn-border-radius: 3px;
|
||||||
|
//
|
||||||
|
// DIRECT CHAT
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$direct-chat-height: 250px;
|
||||||
|
//$direct-chat-default-msg-bg: $gray-lte;
|
||||||
|
//$direct-chat-default-font-color: #444;
|
||||||
|
//$direct-chat-default-msg-border-color: $gray-lte;
|
||||||
|
//
|
||||||
|
// CHAT WIDGET
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//$attachment-border-radius: 3px;
|
||||||
|
//
|
||||||
|
// TRANSITIONS SETTINGS
|
||||||
|
// --------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Transition global options
|
||||||
|
//$transition-speed: .3s;
|
||||||
|
//$transition-fn: ease-in-out;
|
||||||
|
//
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
App\Entity\Activity:
|
App\Entity\Activity:
|
||||||
exclusion_policy: All
|
exclusion_policy: All
|
||||||
custom_accessor_order: [id, name, comment, visible, project, fixedRate, hourlyRate]
|
custom_accessor_order: [id, name, comment, visible, project, fixedRate, hourlyRate, color]
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
include: true
|
include: true
|
||||||
@@ -24,6 +24,9 @@ App\Entity\Activity:
|
|||||||
include: false
|
include: false
|
||||||
exclude: true
|
exclude: true
|
||||||
groups: [Default]
|
groups: [Default]
|
||||||
|
color:
|
||||||
|
include: true
|
||||||
|
groups: [Entity]
|
||||||
virtual_properties:
|
virtual_properties:
|
||||||
getProject:
|
getProject:
|
||||||
serialized_name: project
|
serialized_name: project
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
App\Entity\Customer:
|
App\Entity\Customer:
|
||||||
exclusion_policy: All
|
exclusion_policy: All
|
||||||
custom_accessor_order: [id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, email, homepage, timezone, fixedRate, hourlyRate]
|
custom_accessor_order: [id, name, number, comment, visible, company, contact, address, country, currency, phone, fax, mobile, email, homepage, timezone, fixedRate, hourlyRate, color]
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
include: true
|
include: true
|
||||||
@@ -56,3 +56,6 @@ App\Entity\Customer:
|
|||||||
hourlyRate:
|
hourlyRate:
|
||||||
include: true
|
include: true
|
||||||
groups: [Default]
|
groups: [Default]
|
||||||
|
color:
|
||||||
|
include: true
|
||||||
|
groups: [Entity]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
App\Entity\Project:
|
App\Entity\Project:
|
||||||
exclusion_policy: All
|
exclusion_policy: All
|
||||||
custom_accessor_order: [id, name, comment, visible, budget, orderNumber, customer, fixedRate, hourlyRate]
|
custom_accessor_order: [id, name, comment, visible, budget, orderNumber, customer, fixedRate, hourlyRate, color]
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
include: true
|
include: true
|
||||||
@@ -30,6 +30,9 @@ App\Entity\Project:
|
|||||||
include: false
|
include: false
|
||||||
exclude: true
|
exclude: true
|
||||||
groups: [Default]
|
groups: [Default]
|
||||||
|
color:
|
||||||
|
include: true
|
||||||
|
groups: [Entity]
|
||||||
virtual_properties:
|
virtual_properties:
|
||||||
getCustomer:
|
getCustomer:
|
||||||
serialized_name: customer
|
serialized_name: customer
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"build/app.js": "./app.js?[contenthash]",
|
"build/app.js": "./app.js?[contenthash]",
|
||||||
"build/app.css": "./app.css?03894379d3cc9cde71d1ce7c0fe24573",
|
"build/app.css": "./app.css?361d4520765f893b9b0fb94bc9f761c1",
|
||||||
"build/fonts/fa-solid-900.woff2": "./fonts/fa-solid-900.woff2?e8a92a29",
|
"build/fonts/fa-solid-900.woff2": "./fonts/fa-solid-900.woff2?e8a92a29",
|
||||||
"build/images/fa-solid-900.svg": "./images/fa-solid-900.svg?666a82cb",
|
"build/images/fa-solid-900.svg": "./images/fa-solid-900.svg?666a82cb",
|
||||||
"build/images/glyphicons-halflings-regular.svg": "./images/glyphicons-halflings-regular.svg?89889688",
|
"build/images/glyphicons-halflings-regular.svg": "./images/glyphicons-halflings-regular.svg?89889688",
|
||||||
|
|||||||
@@ -67,11 +67,18 @@ class TimesheetEntity
|
|||||||
$this->project = $entry->getProject()->getName();
|
$this->project = $entry->getProject()->getName();
|
||||||
$this->activity = $entry->getActivity()->getName();
|
$this->activity = $entry->getActivity()->getName();
|
||||||
|
|
||||||
if (null === $entry->getEnd()) {
|
$color = $entry->getActivity()->getColor();
|
||||||
// TODO move these colors to the controller
|
if (empty($color)) {
|
||||||
$this->borderColor = '367fa9'; //'#f39c12';
|
$color = $entry->getProject()->getColor();
|
||||||
$this->backgroundColor = '#3c8dbc'; //'#f39c12';
|
if (empty($color)) {
|
||||||
} else {
|
$color = $entry->getProject()->getCustomer()->getColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->borderColor = $color;
|
||||||
|
$this->backgroundColor = $color;
|
||||||
|
|
||||||
|
if (null !== $entry->getEnd()) {
|
||||||
$this->end = $entry->getEnd();
|
$this->end = $entry->getEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ class Activity
|
|||||||
|
|
||||||
// keep the trait include exactly here, for placing the column at the correct position
|
// keep the trait include exactly here, for placing the column at the correct position
|
||||||
use RatesTrait;
|
use RatesTrait;
|
||||||
|
use ColorTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
|
|||||||
41
src/Entity/ColorTrait.php
Normal file
41
src/Entity/ColorTrait.php
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
trait ColorTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="color", type="string", length=7, nullable=true)
|
||||||
|
*/
|
||||||
|
private $color = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getColor(): ?string
|
||||||
|
{
|
||||||
|
return $this->color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $color
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setColor(?string $color = null)
|
||||||
|
{
|
||||||
|
$this->color = $color;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -149,6 +149,7 @@ class Customer
|
|||||||
|
|
||||||
// keep the trait include exactly here, for placing the column at the correct position
|
// keep the trait include exactly here, for placing the column at the correct position
|
||||||
use RatesTrait;
|
use RatesTrait;
|
||||||
|
use ColorTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ class Project
|
|||||||
|
|
||||||
// keep the trait include exactly here, for placing the column at the correct position
|
// keep the trait include exactly here, for placing the column at the correct position
|
||||||
use RatesTrait;
|
use RatesTrait;
|
||||||
|
use ColorTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Timesheet[]
|
* @var Timesheet[]
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
use App\Entity\Activity;
|
use App\Entity\Activity;
|
||||||
|
use App\Form\Type\ColorPickerType;
|
||||||
use App\Form\Type\CustomerType;
|
use App\Form\Type\CustomerType;
|
||||||
use App\Form\Type\FixedRateType;
|
use App\Form\Type\FixedRateType;
|
||||||
use App\Form\Type\HourlyRateType;
|
use App\Form\Type\HourlyRateType;
|
||||||
@@ -109,6 +110,7 @@ class ActivityEditForm extends AbstractType
|
|||||||
);
|
);
|
||||||
|
|
||||||
$builder
|
$builder
|
||||||
|
->add('color', ColorPickerType::class)
|
||||||
->add('fixedRate', FixedRateType::class, [
|
->add('fixedRate', FixedRateType::class, [
|
||||||
'currency' => $currency,
|
'currency' => $currency,
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
|
use App\Form\Type\ColorPickerType;
|
||||||
use App\Form\Type\FixedRateType;
|
use App\Form\Type\FixedRateType;
|
||||||
use App\Form\Type\HourlyRateType;
|
use App\Form\Type\HourlyRateType;
|
||||||
use App\Form\Type\YesNoType;
|
use App\Form\Type\YesNoType;
|
||||||
@@ -101,6 +102,7 @@ class CustomerEditForm extends AbstractType
|
|||||||
->add('timezone', TimezoneType::class, [
|
->add('timezone', TimezoneType::class, [
|
||||||
'label' => 'label.timezone',
|
'label' => 'label.timezone',
|
||||||
])
|
])
|
||||||
|
->add('color', ColorPickerType::class)
|
||||||
->add('fixedRate', FixedRateType::class, [
|
->add('fixedRate', FixedRateType::class, [
|
||||||
'currency' => $currency ?? false,
|
'currency' => $currency ?? false,
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace App\Form;
|
|||||||
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
use App\Entity\Project;
|
use App\Entity\Project;
|
||||||
|
use App\Form\Type\ColorPickerType;
|
||||||
use App\Form\Type\CustomerType;
|
use App\Form\Type\CustomerType;
|
||||||
use App\Form\Type\FixedRateType;
|
use App\Form\Type\FixedRateType;
|
||||||
use App\Form\Type\HourlyRateType;
|
use App\Form\Type\HourlyRateType;
|
||||||
@@ -69,6 +70,7 @@ class ProjectEditForm extends AbstractType
|
|||||||
return $repo->builderForEntityType($customer);
|
return $repo->builderForEntityType($customer);
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
->add('color', ColorPickerType::class)
|
||||||
->add('fixedRate', FixedRateType::class, [
|
->add('fixedRate', FixedRateType::class, [
|
||||||
'currency' => $currency,
|
'currency' => $currency,
|
||||||
])
|
])
|
||||||
|
|||||||
67
src/Form/Type/ColorPickerType.php
Normal file
67
src/Form/Type/ColorPickerType.php
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\ColorType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
|
class ColorPickerType extends AbstractType implements DataTransformerInterface
|
||||||
|
{
|
||||||
|
public const DEFAULT_COLOR = '#d2d6de';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->addViewTransformer($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults([
|
||||||
|
'label' => 'label.color',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function transform($data)
|
||||||
|
{
|
||||||
|
if (empty($data)) {
|
||||||
|
return self::DEFAULT_COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function reverseTransform($data)
|
||||||
|
{
|
||||||
|
return null === $data ? self::DEFAULT_COLOR : $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return ColorType::class;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
src/Migrations/Version20190502161758.php
Normal file
52
src/Migrations/Version20190502161758.php
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use App\Doctrine\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the color columns on: customer, project, activity.
|
||||||
|
*
|
||||||
|
* @version 0.9
|
||||||
|
*/
|
||||||
|
final class Version20190502161758 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Creates the color columns on: customer, project, activity';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$customers = $schema->getTable('kimai2_customers');
|
||||||
|
$customers->addColumn('color', 'string', ['length' => 7, 'notnull' => false, 'default' => null]);
|
||||||
|
|
||||||
|
$projects = $schema->getTable('kimai2_projects');
|
||||||
|
$projects->addColumn('color', 'string', ['length' => 7, 'notnull' => false, 'default' => null]);
|
||||||
|
|
||||||
|
$activities = $schema->getTable('kimai2_activities');
|
||||||
|
$activities->addColumn('color', 'string', ['length' => 7, 'notnull' => false, 'default' => null]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$customers = $schema->getTable('kimai2_customers');
|
||||||
|
$customers->dropColumn('color');
|
||||||
|
|
||||||
|
$projects = $schema->getTable('kimai2_projects');
|
||||||
|
$projects->dropColumn('color');
|
||||||
|
|
||||||
|
$activities = $schema->getTable('kimai2_activities');
|
||||||
|
$activities->dropColumn('color');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ class BaseQuery
|
|||||||
public const ORDER_ASC = 'ASC';
|
public const ORDER_ASC = 'ASC';
|
||||||
public const ORDER_DESC = 'DESC';
|
public const ORDER_DESC = 'DESC';
|
||||||
|
|
||||||
public const DEFAULT_PAGESIZE = 100;
|
public const DEFAULT_PAGESIZE = 50;
|
||||||
public const DEFAULT_PAGE = 1;
|
public const DEFAULT_PAGE = 1;
|
||||||
|
|
||||||
public const RESULT_TYPE_OBJECTS = 'Objects';
|
public const RESULT_TYPE_OBJECTS = 'Objects';
|
||||||
|
|||||||
@@ -34,19 +34,17 @@
|
|||||||
|
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_activity_edit', {'id': entry.id}) }}"{% endif %}>
|
<tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_activity_edit', {'id': entry.id}) }}"{% endif %}>
|
||||||
<td>{{ entry.name }}</td>
|
<td>{{ widgets.label_color_dot('activity', true, entry.name, null, entry.color) }}</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">
|
||||||
{% if entry.project and entry.project.customer %}
|
{% if entry.project and entry.project.customer %}
|
||||||
<a href="{{ path('admin_customer_edit', {'id' : entry.project.customer.id}) }}">{{ widgets.label_customer(entry.project.customer) }}</a>
|
{# only none-global activities have a project and customer assigned #}
|
||||||
{% else %}
|
{{ widgets.label_customer(entry.project.customer, path('admin_customer_edit', {'id' : entry.project.customer.id})) }}
|
||||||
{# GLOBAL ACTIVTITY DOES NOT HAVE A CUSTOMER #}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'project') }}">
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'project') }}">
|
||||||
{% if entry.project %}
|
{% if entry.project %}
|
||||||
<a href="{{ path('admin_project_edit', {'id' : entry.project.id}) }}">{{ widgets.label_project(entry.project) }}</a>
|
{# only none-global activities have a project and customer assigned #}
|
||||||
{% else %}
|
{{ widgets.label_project(entry.project, path('admin_project_edit', {'id' : entry.project.id})) }}
|
||||||
{# GLOBAL ACTIVTITY DOES NOT HAVE A PROJECT #}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_customer_edit', {'id': entry.id}) }}"{% endif %}>
|
<tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_customer_edit', {'id': entry.id}) }}"{% endif %}>
|
||||||
<td>{{ entry.name }} {% if entry.company is not empty %}({{ entry.company }}){% endif %}</td>
|
<td>{{ widgets.label_color_dot('customer', true, entry.name, null, entry.color) }} {% if entry.company is not empty %}({{ entry.company }}){% endif %}</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'country') }}">{{ entry.country|country }}</td>
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'country') }}">{{ entry.country|country }}</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'number') }}">{{ entry.number }}</td>
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'number') }}">{{ entry.number }}</td>
|
||||||
|
|||||||
@@ -42,35 +42,48 @@
|
|||||||
{{ macro.label(macro.username(user), 'primary') }}
|
{{ macro.label(macro.username(user), 'primary') }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro label_activity(activity) %}
|
{% macro label_activity(activity, url) %}
|
||||||
{% import _self as macro %}
|
{% import _self as macro %}
|
||||||
{% set isVisible = activity.visible %}
|
{% set isVisible = activity.visible %}
|
||||||
|
{% set color = activity.color %}
|
||||||
|
{% if color is empty and activity.project is not null %}
|
||||||
|
{% set color = activity.project.color ?? activity.project.customer.color %}
|
||||||
|
{% endif %}
|
||||||
{% if isVisible and not activity.project is null %}
|
{% if isVisible and not activity.project is null %}
|
||||||
{% set isVisible = activity.project.visible %}
|
{% set isVisible = activity.project.visible %}
|
||||||
{% if isVisible and not activity.project.customer is null %}
|
{% if isVisible and not activity.project.customer is null %}
|
||||||
{% set isVisible = activity.project.customer.visible %}
|
{% set isVisible = activity.project.customer.visible %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% set type = (isVisible ? 'primary' : 'default') %}
|
{{ macro.label_color_dot('activity', isVisible, activity.name, url, color) }}
|
||||||
<span class="label label-{{ type }}">{{ activity.name }}</span>
|
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro label_project(project) %}
|
{% macro label_project(project, url) %}
|
||||||
{% import _self as macro %}
|
{% import _self as macro %}
|
||||||
{% set type = 'default' %}
|
{% set isVisible = false %}
|
||||||
{% if project.visible and project.customer.visible %}
|
{% if project.visible and project.customer.visible %}
|
||||||
{% set type = 'primary' %}
|
{% set isVisible = true %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="label label-{{ type }}">{{ project.name }}</span>
|
{{ macro.label_color_dot('project', isVisible, project.name, url, (project.color ?? project.customer.color)) }}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro label_customer(customer) %}
|
{% macro label_customer(customer, url) %}
|
||||||
{% import _self as macro %}
|
{% import _self as macro %}
|
||||||
{% set type = 'default' %}
|
{% set isVisible = customer.visible %}
|
||||||
{% if customer.visible %}
|
{{ macro.label_color_dot('customer', isVisible, customer.name, url, customer.color) }}
|
||||||
{% set type = 'primary' %}
|
{% endmacro %}
|
||||||
{% endif %}
|
|
||||||
<span class="label label-{{ type }}">{{ customer.name }}</span>
|
{% macro label_color_dot(type, isVisible, name, url, color) %}
|
||||||
|
<span class="label-{{ type }}{{ isVisible ? '' : ' label-invisible' }}">
|
||||||
|
<span class="dot"{% if color is not empty %} style="background-color:{{ color }}"{% endif %}></span>
|
||||||
|
<span class="name">
|
||||||
|
{% if url is not empty %}
|
||||||
|
<a href="{{ url }}">{{ name }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ name }}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro badge_counter(count, url) %}
|
{% macro badge_counter(count, url) %}
|
||||||
|
|||||||
@@ -33,9 +33,9 @@
|
|||||||
|
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_project_edit', {'id': entry.id}) }}"{% endif %}>
|
<tr{% if is_granted('edit', entry) %} class="modal-ajax-form open-edit" data-href="{{ path('admin_project_edit', {'id': entry.id}) }}"{% endif %}>
|
||||||
<td>{{ entry.name }}</td>
|
<td>{{ widgets.label_color_dot('project', true, entry.name, null, entry.color) }}</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'customer') }}">
|
||||||
<a href="{{ path('admin_customer_edit', {'id' : entry.customer.id}) }}">{{ widgets.label_customer(entry.customer) }}</a>
|
{{ widgets.label_customer(entry.customer, path('admin_customer_edit', {'id' : entry.customer.id})) }}
|
||||||
</td>
|
</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'comment') }}">{{ entry.comment }}</td>
|
||||||
<td class="{{ tables.data_table_column_class(tableName, columns, 'budget') }}">{{ entry.budget|money(entry.customer.currency) }}</td>
|
<td class="{{ tables.data_table_column_class(tableName, columns, 'budget') }}">{{ entry.budget|money(entry.customer.currency) }}</td>
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ class ActivityControllerTest extends APIControllerBaseTest
|
|||||||
$expectedKeys = ['id', 'name', 'visible', 'project', 'hourlyRate', 'fixedRate'];
|
$expectedKeys = ['id', 'name', 'visible', 'project', 'hourlyRate', 'fixedRate'];
|
||||||
|
|
||||||
if ($full) {
|
if ($full) {
|
||||||
$expectedKeys = array_merge($expectedKeys, ['comment']);
|
$expectedKeys = array_merge($expectedKeys, ['comment', 'color']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$actual = array_keys($result);
|
$actual = array_keys($result);
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class CustomerControllerTest extends APIControllerBaseTest
|
|||||||
|
|
||||||
if ($full) {
|
if ($full) {
|
||||||
$expectedKeys = array_merge($expectedKeys, [
|
$expectedKeys = array_merge($expectedKeys, [
|
||||||
'homepage', 'number', 'comment', 'company', 'contact', 'address', 'country', 'currency', 'phone', 'fax', 'mobile', 'email', 'timezone'
|
'homepage', 'number', 'comment', 'company', 'contact', 'address', 'country', 'currency', 'phone', 'fax', 'mobile', 'email', 'timezone', 'color'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ class ProjectControllerTest extends APIControllerBaseTest
|
|||||||
if ($full) {
|
if ($full) {
|
||||||
$expectedKeys = array_merge(
|
$expectedKeys = array_merge(
|
||||||
$expectedKeys,
|
$expectedKeys,
|
||||||
['comment', 'budget', 'orderNumber']
|
['comment', 'budget', 'orderNumber', 'color']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,11 +66,11 @@ class TimesheetEntityTest extends TestCase
|
|||||||
$sut->setActivity('cccccccc');
|
$sut->setActivity('cccccccc');
|
||||||
$this->assertEquals('cccccccc', $sut->getActivity());
|
$this->assertEquals('cccccccc', $sut->getActivity());
|
||||||
|
|
||||||
$this->assertEquals('367fa9', $sut->getBorderColor());
|
$this->assertNull($sut->getBorderColor());
|
||||||
$sut->setBorderColor('#cccccc');
|
$sut->setBorderColor('#cccccc');
|
||||||
$this->assertEquals('#cccccc', $sut->getBorderColor());
|
$this->assertEquals('#cccccc', $sut->getBorderColor());
|
||||||
|
|
||||||
$this->assertEquals('#3c8dbc', $sut->getBackgroundColor());
|
$this->assertNull($sut->getBackgroundColor());
|
||||||
$sut->setBackgroundColor('#ffffff');
|
$sut->setBackgroundColor('#ffffff');
|
||||||
$this->assertEquals('#ffffff', $sut->getBackgroundColor());
|
$this->assertEquals('#ffffff', $sut->getBackgroundColor());
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class ActivityTest extends AbstractEntityTest
|
|||||||
// timesheets
|
// timesheets
|
||||||
$this->assertNull($sut->getFixedRate());
|
$this->assertNull($sut->getFixedRate());
|
||||||
$this->assertNull($sut->getHourlyRate());
|
$this->assertNull($sut->getHourlyRate());
|
||||||
|
$this->assertNull($sut->getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetterAndGetter()
|
public function testSetterAndGetter()
|
||||||
@@ -42,6 +43,9 @@ class ActivityTest extends AbstractEntityTest
|
|||||||
$this->assertInstanceOf(Activity::class, $sut->setComment('hello world'));
|
$this->assertInstanceOf(Activity::class, $sut->setComment('hello world'));
|
||||||
$this->assertEquals('hello world', $sut->getComment());
|
$this->assertEquals('hello world', $sut->getComment());
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Activity::class, $sut->setColor('#fffccc'));
|
||||||
|
$this->assertEquals('#fffccc', $sut->getColor());
|
||||||
|
|
||||||
$this->assertInstanceOf(Activity::class, $sut->setFixedRate(13.47));
|
$this->assertInstanceOf(Activity::class, $sut->setFixedRate(13.47));
|
||||||
$this->assertEquals(13.47, $sut->getFixedRate());
|
$this->assertEquals(13.47, $sut->getFixedRate());
|
||||||
$this->assertInstanceOf(Activity::class, $sut->setHourlyRate(99));
|
$this->assertInstanceOf(Activity::class, $sut->setHourlyRate(99));
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class CustomerTest extends AbstractEntityTest
|
|||||||
|
|
||||||
$this->assertNull($sut->getFixedRate());
|
$this->assertNull($sut->getFixedRate());
|
||||||
$this->assertNull($sut->getHourlyRate());
|
$this->assertNull($sut->getHourlyRate());
|
||||||
|
$this->assertNull($sut->getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetterAndGetter()
|
public function testSetterAndGetter()
|
||||||
@@ -57,6 +58,9 @@ class CustomerTest extends AbstractEntityTest
|
|||||||
$this->assertInstanceOf(Customer::class, $sut->setComment('hello world'));
|
$this->assertInstanceOf(Customer::class, $sut->setComment('hello world'));
|
||||||
$this->assertEquals('hello world', $sut->getComment());
|
$this->assertEquals('hello world', $sut->getComment());
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Customer::class, $sut->setColor('#fffccc'));
|
||||||
|
$this->assertEquals('#fffccc', $sut->getColor());
|
||||||
|
|
||||||
$projects = [(new Project())->setName('Test')];
|
$projects = [(new Project())->setName('Test')];
|
||||||
$this->assertInstanceOf(Customer::class, $sut->setProjects($projects));
|
$this->assertInstanceOf(Customer::class, $sut->setProjects($projects));
|
||||||
$this->assertSame($projects, $sut->getProjects());
|
$this->assertSame($projects, $sut->getProjects());
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class ProjectTest extends AbstractEntityTest
|
|||||||
$this->assertNull($sut->getFixedRate());
|
$this->assertNull($sut->getFixedRate());
|
||||||
$this->assertNull($sut->getHourlyRate());
|
$this->assertNull($sut->getHourlyRate());
|
||||||
$this->assertNull($sut->getTimesheets());
|
$this->assertNull($sut->getTimesheets());
|
||||||
|
$this->assertNull($sut->getColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetterAndGetter()
|
public function testSetterAndGetter()
|
||||||
@@ -52,6 +53,9 @@ class ProjectTest extends AbstractEntityTest
|
|||||||
$this->assertInstanceOf(Project::class, $sut->setComment('a comment'));
|
$this->assertInstanceOf(Project::class, $sut->setComment('a comment'));
|
||||||
$this->assertEquals('a comment', $sut->getComment());
|
$this->assertEquals('a comment', $sut->getComment());
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Project::class, $sut->setColor('#fffccc'));
|
||||||
|
$this->assertEquals('#fffccc', $sut->getColor());
|
||||||
|
|
||||||
$this->assertInstanceOf(Project::class, $sut->setVisible(false));
|
$this->assertInstanceOf(Project::class, $sut->setVisible(false));
|
||||||
$this->assertFalse($sut->getVisible());
|
$this->assertFalse($sut->getVisible());
|
||||||
|
|
||||||
|
|||||||
@@ -337,6 +337,10 @@
|
|||||||
<source>label.fixedRate</source>
|
<source>label.fixedRate</source>
|
||||||
<target>Festbetrag</target>
|
<target>Festbetrag</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="label.color">
|
||||||
|
<source>label.color</source>
|
||||||
|
<target>Farbe</target>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
User profile
|
User profile
|
||||||
|
|||||||
@@ -337,6 +337,10 @@
|
|||||||
<source>label.fixedRate</source>
|
<source>label.fixedRate</source>
|
||||||
<target>Fixed rate</target>
|
<target>Fixed rate</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="label.color">
|
||||||
|
<source>label.color</source>
|
||||||
|
<target>Color</target>
|
||||||
|
</trans-unit>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
User profile
|
User profile
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user