Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms
This commit is contained in:
@@ -25,3 +25,6 @@ ALTER table `zt_reviewcl` ADD `type` varchar(255) NOT NULL DEFAULT '' AFTER `cat
|
||||
UPDATE `zt_reviewcl` SET `type` = 'waterfall' WHERE `type` = '';
|
||||
|
||||
UPDATE `zt_activity` SET `order` = `id` * 5 WHERE `order` = '0';
|
||||
|
||||
ALTER table `zt_cmcl` ADD `projectType` varchar(255) NOT NULL DEFAULT '' AFTER `type`;
|
||||
UPDATE `zt_cmcl` SET `projectType` = 'waterfall' WHERE `projectType` = '';
|
||||
|
||||
@@ -9780,6 +9780,7 @@ CREATE TABLE IF NOT EXISTS `zt_reviewlist` (
|
||||
CREATE TABLE IF NOT EXISTS `zt_cmcl` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`type` char(30) NOT NULL,
|
||||
`projectType` varchar(255) NOT NULL,
|
||||
`title` int(11) NOT NULL,
|
||||
`contents` text NOT NULL,
|
||||
`assignedTo` varchar(30) NOT NULL,
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<th><?php echo $lang->project->name;?></th>
|
||||
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->code;?></th>
|
||||
<td><?php echo html::input('code', '', "class='form-control' required");?></td>
|
||||
|
||||
@@ -339,12 +339,12 @@ class helper extends baseHelper
|
||||
$dateInterval->hour = $interval->format('%H');
|
||||
$dateInterval->minute = $interval->format('%i');
|
||||
$dateInterval->secound = $interval->format('%s');
|
||||
$dateInterval->year = ltrim($dateInterval->year, '0');
|
||||
$dateInterval->month = ltrim($dateInterval->month, '0');
|
||||
$dateInterval->day = ltrim($dateInterval->day, '0');
|
||||
$dateInterval->hour = ltrim($dateInterval->hour, '0');
|
||||
$dateInterval->minute = ltrim($dateInterval->minute, '0');
|
||||
$dateInterval->secound = ltrim($dateInterval->secound, '0');
|
||||
$dateInterval->year = $dateInterval->year == '00' ? 0 : ltrim($dateInterval->year, '0');
|
||||
$dateInterval->month = $dateInterval->month == '00' ? 0 : ltrim($dateInterval->month, '0');
|
||||
$dateInterval->day = $dateInterval->day == '00' ? 0 : ltrim($dateInterval->day, '0');
|
||||
$dateInterval->hour = $dateInterval->hour == '00' ? 0 : ltrim($dateInterval->hour, '0');
|
||||
$dateInterval->minute = $dateInterval->minute == '00' ? 0 : ltrim($dateInterval->minute, '0');
|
||||
$dateInterval->secound = $dateInterval->secound == '00' ? 0 : ltrim($dateInterval->secound, '0');
|
||||
}
|
||||
return $dateInterval;
|
||||
}
|
||||
|
||||
Vendored
+53
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* The cache library of zentaopms.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Lu Fei <lufei@easycorp.ltd>
|
||||
* @package cache
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
helper::import(dirname(__FILE__) . DS . 'simple-cache' . DS . 'CacheInterface.php');
|
||||
helper::import(dirname(__FILE__) . DS . 'simple-cache' . DS . 'CacheException.php');
|
||||
helper::import(dirname(__FILE__) . DS . 'simple-cache' . DS . 'InvalidArgumentException.php');
|
||||
helper::import(dirname(__FILE__) . DS . 'driver' . DS . 'ApcuDriver.php');
|
||||
helper::import(dirname(__FILE__) . DS . 'driver' . DS . 'YacDriver.php');
|
||||
|
||||
use ZenTao\Cache\SimpleCache\InvalidArgumentException;
|
||||
|
||||
class cache
|
||||
{
|
||||
/**
|
||||
* @var ZenTao\Cache\SimpleCache\CacheInterface
|
||||
*/
|
||||
protected $client;
|
||||
|
||||
public function __construct($driver = 'Apcu', $namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$driver = ucfirst(strtolower($driver));
|
||||
switch($driver)
|
||||
{
|
||||
case 'Apcu':
|
||||
$className = 'ZenTao\Cache\Driver\ApcuDriver';
|
||||
break;
|
||||
case 'Yac':
|
||||
$className = 'ZenTao\Cache\Driver\YacDriver';
|
||||
break;
|
||||
default:
|
||||
throw new InvalidArgumentException("Driver {$driver} is not supported.");
|
||||
}
|
||||
|
||||
if(!extension_loaded($driver)) throw new InvalidArgumentException("Driver ext-{$driver} is not loaded.");
|
||||
|
||||
$this->client = new $className($namespace, $defaultLifetime);
|
||||
}
|
||||
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if(!method_exists($this->client, $name)) throw new InvalidArgumentException("Method {$name} does not exist.");
|
||||
|
||||
return call_user_func_array(array($this->client, $name), $arguments);
|
||||
}
|
||||
}
|
||||
Vendored
+173
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* The cache library of zentaopms.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Lu Fei <lufei@easycorp.ltd>
|
||||
* @package cache
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
namespace ZenTao\Cache\Driver;
|
||||
|
||||
use ZenTao\Cache\SimpleCache\CacheInterface;
|
||||
use ZenTao\Cache\SimpleCache\InvalidArgumentException;
|
||||
|
||||
class ApcuDriver implements CacheInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $namespace;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $defaultLifetime;
|
||||
|
||||
public function __construct($namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->defaultLifetime = $defaultLifetime;
|
||||
}
|
||||
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
$value = apcu_fetch($key, $success);
|
||||
|
||||
return $success === false ? $default : $value;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
|
||||
|
||||
return apcu_store($key, $value, (int) $ttl);
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
return apcu_delete($key);
|
||||
}
|
||||
|
||||
public function clear()
|
||||
{
|
||||
return apcu_clear_cache();
|
||||
}
|
||||
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
$this->assertKeyNames($keys);
|
||||
$keys = $this->buildKeyNames($keys);
|
||||
|
||||
$result = apcu_fetch($keys);
|
||||
|
||||
if(!is_null($default) && is_array($result) && count($keys) > count($result))
|
||||
{
|
||||
$notFoundKeys = array_diff($keys, array_keys($result));
|
||||
$result = array_merge($result, array_fill_keys($notFoundKeys, $default));
|
||||
}
|
||||
|
||||
$mappedResult = array();
|
||||
|
||||
foreach($result as $key => $value)
|
||||
{
|
||||
$key = preg_replace("/^$this->namespace/", '', $key);
|
||||
|
||||
$mappedResult[$key] = $value;
|
||||
}
|
||||
|
||||
return $mappedResult;
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
$this->assertKeyNames(array_keys($values));
|
||||
|
||||
$mappedByNamespaceValues = array();
|
||||
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
$mappedByNamespaceValues[$this->buildKeyName($key)] = $value;
|
||||
}
|
||||
|
||||
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
|
||||
|
||||
$result = apcu_store($mappedByNamespaceValues, (int) $ttl);
|
||||
|
||||
return $result === true ? true : (is_array($result) && count($result) == 0 ? true : false);
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
$this->assertKeyNames($keys);
|
||||
$keys = $this->buildKeyNames($keys);
|
||||
|
||||
$result = apcu_delete($keys);
|
||||
|
||||
return count($result) === count($keys) ? false : true;
|
||||
}
|
||||
|
||||
public function has($key)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
return (bool) apcu_exists($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildKeyName($key)
|
||||
{
|
||||
return $this->namespace . $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $keys
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function buildKeyNames(array $keys)
|
||||
{
|
||||
return array_map(function($key) {
|
||||
return $this->buildKeyName($key);
|
||||
}, $keys);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function assertKeyName($key)
|
||||
{
|
||||
if(!is_scalar($key) || is_bool($key)) throw new InvalidArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $keys
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function assertKeyNames(array $keys)
|
||||
{
|
||||
array_map(function ($value) {
|
||||
$this->assertKeyName($value);
|
||||
}, $keys);
|
||||
}
|
||||
}
|
||||
Vendored
+197
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* The cache library of zentaopms.
|
||||
*
|
||||
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
|
||||
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
|
||||
* @author Lu Fei <lufei@easycorp.ltd>
|
||||
* @package cache
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
|
||||
namespace ZenTao\Cache\Driver;
|
||||
|
||||
use ZenTao\Cache\SimpleCache\CacheInterface;
|
||||
use ZenTao\Cache\SimpleCache\InvalidArgumentException;
|
||||
|
||||
class YacDriver implements CacheInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $namespace;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $defaultLifetime;
|
||||
|
||||
/**
|
||||
* yac client
|
||||
*
|
||||
* @var \Yac
|
||||
*/
|
||||
protected $yac;
|
||||
|
||||
/**
|
||||
* if your key is longer than this, maybe you can use md5 result as the key
|
||||
*/
|
||||
const KEY_MAX_LEN = 48;
|
||||
|
||||
public function __construct($namespace = '', $defaultLifetime = 0)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
$this->defaultLifetime = $defaultLifetime;
|
||||
$this->yac = new \Yac($namespace);
|
||||
}
|
||||
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
return $this->yac->get($key) ?: $default;
|
||||
}
|
||||
|
||||
public function set($key, $value, $ttl = null)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
|
||||
|
||||
return $this->yac->set($key, $value, (int)$ttl);
|
||||
}
|
||||
|
||||
public function delete($key)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
$key = $this->buildKeyName($key);
|
||||
|
||||
return $this->yac->delete($key);
|
||||
}
|
||||
|
||||
public function clear()
|
||||
{
|
||||
return $this->yac->flush();
|
||||
}
|
||||
|
||||
public function getMultiple($keys, $default = null)
|
||||
{
|
||||
if(!is_array($keys)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$hashKeyMap = array();
|
||||
foreach($keys as $index => $key)
|
||||
{
|
||||
$this->assertKeyName($key);
|
||||
if(strlen($key) > self::KEY_MAX_LEN)
|
||||
{
|
||||
$keys[$index] = $this->buildKeyName($key);
|
||||
$hashKeyMap[$keys[$index]] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
$results = $this->yac->get($keys);
|
||||
if($results !== false)
|
||||
{
|
||||
foreach($results as $key => $value)
|
||||
{
|
||||
if(isset($hashKeyMap[$key]))
|
||||
{
|
||||
$results[$hashKeyMap[$key]] = $value;
|
||||
unset($results[$key]);
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
$results = array();
|
||||
foreach($keys as $key)
|
||||
{
|
||||
$results[$key] = $default;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function setMultiple($values, $ttl = null)
|
||||
{
|
||||
if(!is_array($values)) return false;
|
||||
|
||||
foreach($values as $key => $value)
|
||||
{
|
||||
if(strlen($key) > self::KEY_MAX_LEN)
|
||||
{
|
||||
$values[$this->buildKeyName($key)] = $value;
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$ttl = is_null($ttl) ? $this->defaultLifetime : $ttl;
|
||||
|
||||
return $this->yac->set($values, $ttl);
|
||||
}
|
||||
|
||||
public function deleteMultiple($keys)
|
||||
{
|
||||
foreach($keys as $index => $key)
|
||||
{
|
||||
$keys[$index] = $this->buildKeyName($key);
|
||||
}
|
||||
return $this->yac->delete($keys);
|
||||
}
|
||||
|
||||
public function has($key)
|
||||
{
|
||||
return $this->get($key) !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildKeyName($key)
|
||||
{
|
||||
if(strlen($key) > self::KEY_MAX_LEN)
|
||||
{
|
||||
$key = md5($key);
|
||||
}
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $keys
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function buildKeyNames(array $keys)
|
||||
{
|
||||
return array_map(function ($key) {
|
||||
return $this->buildKeyName($key);
|
||||
}, $keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $key
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function assertKeyName($key)
|
||||
{
|
||||
if(!is_scalar($key) || is_bool($key)) throw new InvalidArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $keys
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
private function assertKeyNames(array $keys)
|
||||
{
|
||||
array_map(function ($value) {
|
||||
$this->assertKeyName($value);
|
||||
}, $keys);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ZenTao\Cache\SimpleCache;
|
||||
|
||||
class CacheException extends \RuntimeException
|
||||
{
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace ZenTao\Cache\SimpleCache;
|
||||
|
||||
interface CacheInterface
|
||||
{
|
||||
/**
|
||||
* Fetches a value from the cache.
|
||||
*
|
||||
* @param string $key The unique key of this item in the cache.
|
||||
* @param mixed $default Default value to return if the key does not exist.
|
||||
*
|
||||
* @return mixed The value of the item from the cache, or $default in case of cache miss.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if the $key string is not a legal value.
|
||||
*/
|
||||
public function get($key, $default = null);
|
||||
|
||||
/**
|
||||
* Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time.
|
||||
*
|
||||
* @param string $key The key of the item to store.
|
||||
* @param mixed $value The value of the item to store, must be serializable.
|
||||
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
|
||||
* the driver supports TTL then the library may set a default value
|
||||
* for it or let the driver take care of that.
|
||||
*
|
||||
* @return bool True on success and false on failure.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if the $key string is not a legal value.
|
||||
*/
|
||||
public function set($key, $value, $ttl = null);
|
||||
|
||||
/**
|
||||
* Delete an item from the cache by its unique key.
|
||||
*
|
||||
* @param string $key The unique cache key of the item to delete.
|
||||
*
|
||||
* @return bool True if the item was successfully removed. False if there was an error.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if the $key string is not a legal value.
|
||||
*/
|
||||
public function delete($key);
|
||||
|
||||
/**
|
||||
* Wipes clean the entire cache's keys.
|
||||
*
|
||||
* @return bool True on success and false on failure.
|
||||
*/
|
||||
public function clear();
|
||||
|
||||
/**
|
||||
* Obtains multiple cache items by their unique keys.
|
||||
*
|
||||
* @param iterable<string> $keys A list of keys that can be obtained in a single operation.
|
||||
* @param mixed $default Default value to return for keys that do not exist.
|
||||
*
|
||||
* @return iterable<string, mixed> A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if $keys is neither an array nor a Traversable,
|
||||
* or if any of the $keys are not a legal value.
|
||||
*/
|
||||
public function getMultiple($keys, $default = null);
|
||||
|
||||
/**
|
||||
* Persists a set of key => value pairs in the cache, with an optional TTL.
|
||||
*
|
||||
* @param iterable $values A list of key => value pairs for a multiple-set operation.
|
||||
* @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
|
||||
* the driver supports TTL then the library may set a default value
|
||||
* for it or let the driver take care of that.
|
||||
*
|
||||
* @return bool True on success and false on failure.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if $values is neither an array nor a Traversable,
|
||||
* or if any of the $values are not a legal value.
|
||||
*/
|
||||
public function setMultiple($values, $ttl = null);
|
||||
|
||||
/**
|
||||
* Deletes multiple cache items in a single operation.
|
||||
*
|
||||
* @param iterable<string> $keys A list of string-based keys to be deleted.
|
||||
*
|
||||
* @return bool True if the items were successfully removed. False if there was an error.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if $keys is neither an array nor a Traversable,
|
||||
* or if any of the $keys are not a legal value.
|
||||
*/
|
||||
public function deleteMultiple($keys);
|
||||
|
||||
/**
|
||||
* Determines whether an item is present in the cache.
|
||||
*
|
||||
* NOTE: It is recommended that has() is only to be used for cache warming type purposes
|
||||
* and not to be used within your live applications operations for get/set, as this method
|
||||
* is subject to a race condition where your has() will return true and immediately after,
|
||||
* another script can remove it making the state of your app out of date.
|
||||
*
|
||||
* @param string $key The cache item key.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
* MUST be thrown if the $key string is not a legal value.
|
||||
*/
|
||||
public function has($key);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace ZenTao\Cache\SimpleCache;
|
||||
|
||||
class InvalidArgumentException extends CacheException
|
||||
{
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
.font-20 {font-size: 20px;}
|
||||
.font-24 {font-size: 24px;}
|
||||
.radius-4 {border-radius: 4px;}
|
||||
.white-nowrap {white-space: nowrap;}
|
||||
.w-full {width: 100%;}
|
||||
|
||||
#notice {margin: -20px -20px 20px; padding: 20px;}
|
||||
#zentaoLinks {margin-top: 20px;}
|
||||
@@ -40,8 +42,10 @@
|
||||
.settings-list > .setting-box > .btn:hover {background: unset;}
|
||||
.settings-list > .setting-box > .btn[disabled] {cursor: not-allowed; pointer-events: unset;}
|
||||
.settings-list > .setting-box > .btn[disabled] > a {pointer-events: none;}
|
||||
.settings-list > .setting-box > .btn > h4 {padding-right: 5px;}
|
||||
.settings-list > .setting-box > .btn > h4 > div {gap: 3px;}
|
||||
.settings-list > .setting-box > .btn > h4 > img {padding-right: 8px; padding-bottom: 3px; width: 32px; height: 27px;}
|
||||
.settings-list > .setting-box > .btn > .setting-desc {padding-bottom: 16px; color: #5E626D; line-height: 25px; height: 50px;}
|
||||
.settings-list > .setting-box > .btn > .setting-desc {padding-bottom: 16px; color: #5E626D; line-height: 25px; height: 50px; overflow: hidden;}
|
||||
.settings-list.lite-setting > .setting-box {flex: 1 1 30%;}
|
||||
|
||||
.plugin-list {display: flex; flex-wrap: wrap; padding: 12px 4px 4px 4px;}
|
||||
@@ -71,7 +75,7 @@
|
||||
.panel.publicClass {padding: 0 10px;}
|
||||
.icon.follow-us {font-size: 20px; padding-left: 10px;}
|
||||
|
||||
.setting-help {width: 45px; color: #9EA3B0; padding-top: 15px;}
|
||||
.setting-help {color: #9EA3B0;}
|
||||
[lang^='zh'] .setting-help {padding-top: 0;}
|
||||
.pointer-none {pointer-events: none;}
|
||||
|
||||
@@ -86,7 +90,7 @@
|
||||
.time-block {background: #EDEEF2; padding:2px 4px; border-radius: 4px; color: #0B0F18; font-size: 15px; margin: 0 4px;}
|
||||
.dynamic-block {height: 74px; padding: 12px 16px; display: flex; justify-content: space-between; position: relative; line-height: 20px; border-top: 1px solid #E3E4E9;}
|
||||
.dynamic-content {height: 50px; line-height: 25px; overflow: hidden;}
|
||||
.dynamic-time {white-space: nowrap; position: absolute; right: 12px; bottom: 10px; padding-right: 12px; background: white; color: #5E626D;}
|
||||
.dynamic-time {white-space: nowrap; position: absolute; right: 12px; bottom: 12px; padding-left: 5px; padding-right: 12px; background: white; color: #5E626D;}
|
||||
.time-count {letter-spacing: 1px;}
|
||||
|
||||
.patch-block {padding: 10px 16px 12px; line-height: 20px; border-top: 1px solid #E3E4E9;}
|
||||
|
||||
@@ -11,6 +11,7 @@ $lang->admin->menuList->user['order'] = 2;
|
||||
|
||||
$lang->admin->menuList->switch['name'] = $lang->admin->menuSetting['switch']['name'];
|
||||
$lang->admin->menuList->switch['desc'] = $lang->admin->menuSetting['switch']['desc'];
|
||||
$lang->admin->menuList->switch['link'] = 'admin|setmodule';
|
||||
$lang->admin->menuList->switch['order'] = 3;
|
||||
|
||||
$lang->admin->menuList->model['name'] = $lang->admin->menuSetting['model']['name'];
|
||||
@@ -71,10 +72,6 @@ $lang->admin->menuList->user['menuOrder']['5'] = 'dept';
|
||||
$lang->admin->menuList->user['menuOrder']['10'] = 'user';
|
||||
$lang->admin->menuList->user['menuOrder']['15'] = 'group';
|
||||
|
||||
$lang->admin->menuList->switch['subMenu']['setmodule'] = array('link' => "{$lang->admin->module}|admin|setmodule|");
|
||||
|
||||
$lang->admin->menuList->switch['menuOrder']['5'] = 'setmodule';
|
||||
|
||||
$lang->admin->menuList->model['subMenu']['common'] = array('link' => "{$lang->globalSetting}|custom|required|module=project", 'subModule' => 'custom,subject,holiday,stage', 'exclude' => 'stage-browse,stage-plusbrowse,stage-create,stage-edit,stage-batchcreate');
|
||||
$lang->admin->menuList->model['subMenu']['scrum'] = array('link' => "{$lang->scrumModel}|auditcl|scrumbrowse|", 'subModule' => 'auditcl');
|
||||
$lang->admin->menuList->model['subMenu']['waterfall'] = array('link' => "{$lang->waterfallModel}|stage|browse|", 'subModule' => 'stage', 'exclude' => 'stage-settype,stage-plusbrowse');
|
||||
@@ -165,7 +162,7 @@ $lang->admin->menuList->message['menuOrder']['10'] = 'webhook';
|
||||
$lang->admin->menuList->message['menuOrder']['20'] = 'browser';
|
||||
$lang->admin->menuList->message['menuOrder']['25'] = 'setting';
|
||||
|
||||
$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "API|dev|api|module=index");
|
||||
$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "{$lang->api}|dev|api|module=index");
|
||||
$lang->admin->menuList->dev['subMenu']['db'] = array('link' => "{$lang->database}|dev|db|table=" . trim(TABLE_EFFORT, '`'));
|
||||
$lang->admin->menuList->dev['subMenu']['editor'] = array('link' => "{$lang->editor}|dev|editor|");
|
||||
$lang->admin->menuList->dev['subMenu']['entry'] = array('link' => "{$lang->admin->entry}|entry|browse|", 'subModule' => 'entry');
|
||||
|
||||
@@ -21,9 +21,14 @@
|
||||
<?php if($config->vision == 'lite' and !in_array($menuKey, $config->admin->liteMenuList)) continue;?>
|
||||
<div class="setting-box">
|
||||
<button class="btn shadow-primary-hover" <?php if($menu['disabled']) echo 'disabled';?> data-link='<?php echo $menu['link'];?>'>
|
||||
<h4><img src="/static/svg/admin-<?php echo $menuKey;?>.svg"/><?php echo $menu['name'];?></h4>
|
||||
<h4 class="flex align-center justify-between w-full">
|
||||
<div class="flex align-center">
|
||||
<img src="/static/svg/admin-<?php echo $menuKey;?>.svg"/>
|
||||
<?php echo $menu['name'];?>
|
||||
</div>
|
||||
<?php echo html::a($config->admin->helpURL[$menuKey], "<i class='icon icon-help'></i> ", '_blank', 'class="text-muted setting-help"');?>
|
||||
</h4>
|
||||
<p class="text-muted setting-desc" title="<?php echo $menu['desc'];?>"><?php echo $menu['desc'];?></p>
|
||||
<?php echo html::a($config->admin->helpURL[$menuKey], "<i class='icon icon-help'></i> {$lang->help}", '_blank', 'class="text-muted setting-help"');?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -253,7 +253,8 @@ $lang->indexPage = 'Index';
|
||||
$lang->model = 'Model';
|
||||
$lang->redev = 'Develop';
|
||||
$lang->browser = 'Browser';
|
||||
$lang->database = 'Database';
|
||||
$lang->api = 'API Document';
|
||||
$lang->database = 'Data Dictionary';
|
||||
$lang->editor = 'Editor';
|
||||
$lang->timezone = 'Timezone';
|
||||
$lang->security = 'Security';
|
||||
@@ -303,7 +304,7 @@ $lang->devops->set = 'Set';
|
||||
|
||||
$lang->admin->module = 'Module';
|
||||
$lang->admin->system = 'System';
|
||||
$lang->admin->entry = 'Application';
|
||||
$lang->admin->entry = 'Access ZenTao';
|
||||
$lang->admin->data = 'Data';
|
||||
$lang->admin->cron = 'Cron';
|
||||
$lang->admin->buildIndex = 'Full Text Search';
|
||||
|
||||
@@ -253,7 +253,8 @@ $lang->indexPage = 'Index';
|
||||
$lang->model = 'Model';
|
||||
$lang->redev = 'Develop';
|
||||
$lang->browser = 'Browser';
|
||||
$lang->database = 'Database';
|
||||
$lang->api = 'API Document';
|
||||
$lang->database = 'Data Dictionary';
|
||||
$lang->editor = 'Editor';
|
||||
$lang->timezone = 'Timezone';
|
||||
$lang->security = 'Security';
|
||||
@@ -303,7 +304,7 @@ $lang->devops->set = 'Set';
|
||||
|
||||
$lang->admin->module = 'Module';
|
||||
$lang->admin->system = 'System';
|
||||
$lang->admin->entry = 'Application';
|
||||
$lang->admin->entry = 'Access ZenTao';
|
||||
$lang->admin->data = 'Data';
|
||||
$lang->admin->cron = 'Cron';
|
||||
$lang->admin->buildIndex = 'Full Text Search';
|
||||
|
||||
@@ -253,7 +253,8 @@ $lang->indexPage = 'Index';
|
||||
$lang->model = 'Model';
|
||||
$lang->redev = 'Develop';
|
||||
$lang->browser = 'Browser';
|
||||
$lang->database = 'Database';
|
||||
$lang->api = 'API Document';
|
||||
$lang->database = 'Data Dictionary';
|
||||
$lang->editor = 'Editor';
|
||||
$lang->timezone = 'Timezone';
|
||||
$lang->security = 'Security';
|
||||
@@ -303,7 +304,7 @@ $lang->devops->set = 'Set';
|
||||
|
||||
$lang->admin->module = 'Module';
|
||||
$lang->admin->system = 'System';
|
||||
$lang->admin->entry = 'Application';
|
||||
$lang->admin->entry = 'Access ZenTao';
|
||||
$lang->admin->data = 'Data';
|
||||
$lang->admin->cron = 'Cron';
|
||||
$lang->admin->buildIndex = 'Full Text Search';
|
||||
|
||||
@@ -253,7 +253,8 @@ $lang->indexPage = '首页';
|
||||
$lang->model = '模型';
|
||||
$lang->redev = '二次开发';
|
||||
$lang->browser = '浏览器';
|
||||
$lang->database = '数据库';
|
||||
$lang->api = '接口文档';
|
||||
$lang->database = '数据字典';
|
||||
$lang->editor = '编辑器';
|
||||
$lang->timezone = '时区';
|
||||
$lang->security = '安全';
|
||||
@@ -303,7 +304,7 @@ $lang->devops->set = '设置';
|
||||
|
||||
$lang->admin->module = '功能配置';
|
||||
$lang->admin->system = '系统';
|
||||
$lang->admin->entry = '应用';
|
||||
$lang->admin->entry = '接入禅道';
|
||||
$lang->admin->data = '数据';
|
||||
$lang->admin->cron = '定时';
|
||||
$lang->admin->buildIndex = '重建索引';
|
||||
|
||||
+10
-5
@@ -204,6 +204,9 @@ class customModel extends model
|
||||
ksort($menuOrder);
|
||||
foreach($menuOrder as $name)
|
||||
{
|
||||
/* If menu is removed, delete the menuOrder. */
|
||||
if(!isset($allMenu->$name)) continue;
|
||||
|
||||
$item = new stdclass();
|
||||
$item->name = $name;
|
||||
$item->hidden = false;
|
||||
@@ -1134,13 +1137,15 @@ class customModel extends model
|
||||
$disabledFeatures = $this->setting->getItem('owner=system&module=common§ion=&key=disabledFeatures');
|
||||
$disabledFeatures = $disabledFeatures . ',' . $closedFeatures;
|
||||
|
||||
$hasWaterfall = strpos(",{$disabledFeatures},", ',waterfall,') === false;
|
||||
$hasWaterfallPlus = strpos(",{$disabledFeatures},", ',waterfallplus,') === false;
|
||||
$hasScrumMeasrecord = strpos(",{$disabledFeatures},", ',scrumMeasrecord,') === false;
|
||||
$hasWaterfallMeasrecord = (strpos(",{$disabledFeatures},", ',waterfallMeasrecord,') === false and ($hasWaterfall or $hasWaterfallPlus));
|
||||
$hasWaterfall = strpos(",{$disabledFeatures},", ',waterfall,') === false;
|
||||
$hasWaterfallPlus = strpos(",{$disabledFeatures},", ',waterfallplus,') === false;
|
||||
$hasScrumMeasrecord = strpos(",{$disabledFeatures},", ',scrumMeasrecord,') === false;
|
||||
$hasAgilePlusMeasrecord = strpos(",{$disabledFeatures},", ',agileMeasrecord,') === false;
|
||||
$hasWaterfallMeasrecord = (strpos(",{$disabledFeatures},", ',waterfallMeasrecord,') === false and $hasWaterfall);
|
||||
$hasWaterfallPlusMeasrecord = (strpos(",{$disabledFeatures},", ',waterfallplusMeasrecord,') === false and $hasWaterfallPlus);
|
||||
|
||||
$cronStatus = 'normal';
|
||||
if(!$hasScrumMeasrecord and !$hasWaterfallMeasrecord) $cronStatus = 'stop';
|
||||
if(!$hasScrumMeasrecord and !$hasAgilePlusMeasrecord and !$hasWaterfallMeasrecord and $hasWaterfallPlusMeasrecord) $cronStatus = 'stop';
|
||||
|
||||
$this->loadModel('cron');
|
||||
$cron = $this->dao->select('id,status')->from(TABLE_CRON)->where('command')->like('%methodName=initCrontabQueue')->fetch();
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<tr>
|
||||
<th class='c-setCode'><?php echo $lang->custom->setCode;?></th>
|
||||
<td class='c-code text-left'>
|
||||
<?php $checkedKey = isset($config->setCode) ? $config->setCode : 1;?>
|
||||
<?php $checkedKey = isset($config->setCode) ? $config->setCode : 0;?>
|
||||
<?php foreach($lang->custom->conceptOptions->URAndSR as $key => $value):?>
|
||||
<label class="radio-inline"><input type="radio" name="code" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="code<?php echo $key;?>"><?php echo $value;?></label>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<?php if(is_array($feature) and empty($disabledScrumFeatures)) continue;?>
|
||||
<tr class='text-center'>
|
||||
<td class='text-left'><?php echo (is_array($feature) and !empty($disabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
|
||||
<td><i class='icon text-red icon-close'></i></td>
|
||||
<td><i class='icon text-red icon-ban-circle'></i></td>
|
||||
<td><i class='icon text-success icon-check'></i></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -176,7 +176,7 @@ $config->execution->gantt->linkType['end']['end'] = 2;
|
||||
$config->execution->gantt->linkType['begin']['end'] = 3;
|
||||
|
||||
$config->execution->datatable = new stdclass();
|
||||
if(!isset($config->setCode) or $config->setCode == 1)
|
||||
if(isset($config->setCode) and $config->setCode == 1)
|
||||
{
|
||||
$config->execution->datatable->defaultField = array('id', 'name', 'code', 'project', 'PM', 'status', 'progress', 'openedDate', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
|
||||
}
|
||||
@@ -201,7 +201,7 @@ $config->execution->datatable->fieldList['name']['nestedToggle'] = true;
|
||||
$config->execution->datatable->fieldList['name']['iconRender'] = true;
|
||||
$config->execution->datatable->fieldList['name']['required'] = 'yes';
|
||||
|
||||
if(!isset($config->setCode) or $config->setCode == 1)
|
||||
if(isset($config->setCode) and $config->setCode == 1)
|
||||
{
|
||||
$config->execution->datatable->fieldList['code']['title'] = 'execCode';
|
||||
$config->execution->datatable->fieldList['code']['width'] = '180';
|
||||
|
||||
@@ -2732,12 +2732,17 @@ class execution extends control
|
||||
|
||||
if($groupBy == 'story' and $browseType == 'task' and !isset($this->lang->kanban->orderList[$orderBy])) $orderBy = 'id_asc';
|
||||
$kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, '', $orderBy);
|
||||
|
||||
if(empty($kanbanGroup))
|
||||
{
|
||||
$this->kanban->createExecutionLane($executionID, $browseType);
|
||||
$kanbanGroup = $this->kanban->getExecutionKanban($executionID, $browseType, $groupBy, '', $orderBy);
|
||||
}
|
||||
|
||||
/* Show lanes of the attribute: no story&bug in request, no bug in design. */
|
||||
if(!isset($this->lang->execution->menu->story)) unset($kanbanGroup['story']);
|
||||
if(!isset($this->lang->execution->menu->qa)) unset($kanbanGroup['bug']);
|
||||
|
||||
/* Determines whether an object is editable. */
|
||||
$canBeChanged = common::canModify('execution', $execution);
|
||||
|
||||
|
||||
@@ -2,3 +2,5 @@
|
||||
.c-team-name {width: 120px;}
|
||||
.c-project, .c-user, .c-code, .c-desc, .c-days {width: 150px;}
|
||||
.c-method {width: 45px;}
|
||||
.c-type > .icon-help {vertical-align: text-top;}
|
||||
.c-type > .popover .popover-content {font-weight: 400;}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
.c-user {width: 150px !important;}
|
||||
.c-date {width: 125px;}
|
||||
.c-method {width: 60px;}
|
||||
.c-type {width: 130px;}
|
||||
|
||||
@@ -39,3 +39,4 @@
|
||||
.productsBox .required + .text-danger.help-text {position: relative; left: 10px;}
|
||||
.productsBox > #productNameLabel {padding-top: 8px;}
|
||||
.productsBox div[id^='branch'].chosen-disabled {pointer-events: none;}
|
||||
.methodTip icon:before {margin-bottom: 5px;}
|
||||
|
||||
@@ -27,3 +27,8 @@ $('#executionForm').on('change input mousedown', '.has-error', function()
|
||||
$(this).parent().find('.text-danger').remove();
|
||||
$(this).removeClass('has-error');
|
||||
})
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('[data-toggle="popover"]').popover();
|
||||
})
|
||||
|
||||
@@ -153,6 +153,8 @@ $(function()
|
||||
{
|
||||
$('.disabledBranch div[id^="branch"]').addClass('chosen-disabled');
|
||||
}
|
||||
|
||||
$('[data-toggle="popover"]').popover();
|
||||
});
|
||||
|
||||
function showLifeTimeTips()
|
||||
|
||||
@@ -112,6 +112,8 @@ $(function()
|
||||
{
|
||||
$('.disabledBranch div[id^="branch"]').addClass('chosen-disabled');
|
||||
}
|
||||
|
||||
$('[data-toggle="popover"]').popover();
|
||||
})
|
||||
var lastProjectID = $("#project").val();
|
||||
|
||||
|
||||
@@ -151,6 +151,8 @@ $lang->execution->left = 'Left';
|
||||
$lang->execution->copyTeamTip = "copy Project/project team members";
|
||||
$lang->execution->daysGreaterProject = 'Days cannot be greater than days of execution 『%s』';
|
||||
$lang->execution->errorHours = 'Hours/Day cannot be greater than『24』';
|
||||
$lang->execution->agileplusMethodTip = 'When creating executions in an Agile Plus project, both Iteration and Kanban management methods are supported.';
|
||||
$lang->execution->typeTip = "The sub-stages of other types can be created under the parent stage of the 'mix' type, while the type of other parent-child levels is consistent.";
|
||||
|
||||
$lang->execution->start = 'Start';
|
||||
$lang->execution->activate = 'Aktivieren';
|
||||
|
||||
@@ -151,6 +151,8 @@ $lang->execution->left = 'Left';
|
||||
$lang->execution->copyTeamTip = "copy Project/project team members";
|
||||
$lang->execution->daysGreaterProject = 'Days cannot be greater than days of execution 『%s』';
|
||||
$lang->execution->errorHours = 'Hours/Day cannot be greater than『24』';
|
||||
$lang->execution->agileplusMethodTip = 'When creating executions in an Agile Plus project, both Iteration and Kanban management methods are supported.';
|
||||
$lang->execution->typeTip = "The sub-stages of other types can be created under the parent stage of the 'mix' type, while the type of other parent-child levels is consistent.";
|
||||
|
||||
$lang->execution->start = 'Start';
|
||||
$lang->execution->activate = 'Activate';
|
||||
|
||||
@@ -151,6 +151,8 @@ $lang->execution->left = 'Left';
|
||||
$lang->execution->copyTeamTip = "copy Project/project team members";
|
||||
$lang->execution->daysGreaterProject = 'Days cannot be greater than days of execution 『%s』';
|
||||
$lang->execution->errorHours = 'Hours/Day cannot be greater than『24』';
|
||||
$lang->execution->agileplusMethodTip = 'When creating executions in an Agile Plus project, both Iteration and Kanban management methods are supported.';
|
||||
$lang->execution->typeTip = "The sub-stages of other types can be created under the parent stage of the 'mix' type, while the type of other parent-child levels is consistent.";
|
||||
|
||||
$lang->execution->start = 'Démarrer';
|
||||
$lang->execution->activate = 'Activer';
|
||||
|
||||
@@ -151,6 +151,8 @@ $lang->execution->left = '剩余';
|
||||
$lang->execution->copyTeamTip = "可以选择复制项目或{$lang->execution->common}团队的成员";
|
||||
$lang->execution->daysGreaterProject = '可用工日不能大于执行的可用工日『%s』';
|
||||
$lang->execution->errorHours = '可用工时/天不能大于『24』';
|
||||
$lang->execution->agileplusMethodTip = '融合敏捷项目创建执行时,支持迭代和看板两种管理方法。';
|
||||
$lang->execution->typeTip = '“综合”类型的父阶段可以创建其它类型的子级,其它父子层级的类型均一致。';
|
||||
|
||||
$lang->execution->start = "开始";
|
||||
$lang->execution->activate = "激活";
|
||||
|
||||
@@ -533,7 +533,7 @@ class executionModel extends model
|
||||
$oldExecution = $this->dao->findById($executionID)->from(TABLE_EXECUTION)->fetch();
|
||||
|
||||
/* Judgment of required items. */
|
||||
if($oldExecution->type != 'stage' and $this->post->code == '' and (!isset($this->config->setCode) or $this->config->setCode == 1))
|
||||
if($oldExecution->type != 'stage' and $this->post->code == '' and isset($this->config->setCode) and $this->config->setCode == 1)
|
||||
{
|
||||
dao::$errors['code'] = sprintf($this->lang->error->notempty, $this->lang->execution->code);
|
||||
return false;
|
||||
@@ -5789,7 +5789,7 @@ class executionModel extends model
|
||||
$_POST['status'] = $project->status;
|
||||
$_POST['acl'] = 'open';
|
||||
|
||||
if(!isset($this->config->setCode) or $this->config->setCode == 1) $_POST['code'] = $project->code;
|
||||
if(isset($this->config->setCode) and $this->config->setCode == 1) $_POST['code'] = $project->code;
|
||||
|
||||
$projectProducts = $this->dao->select('*')->from(TABLE_PROJECTPRODUCT)->where('project')->eq($projectID)->fetchAll();
|
||||
foreach($projectProducts as $projectProduct)
|
||||
|
||||
@@ -55,14 +55,17 @@
|
||||
<th class='c-method'><?php echo $lang->execution->method;?></th>
|
||||
<?php endif;?>
|
||||
<th class='required <?php echo $minWidth?>' style="width:100%"><?php echo $lang->execution->$name;?></th>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<th class='c-code required'><?php echo $lang->execution->$code;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-user<?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>'><?php echo $lang->execution->$PM;?></th>
|
||||
<th class='c-user<?php echo zget($visibleFields, 'PO', ' hidden') . zget($requiredFields, 'PO', '', ' required');?>'><?php echo $lang->execution->PO;?></th>
|
||||
<th class='c-user<?php echo zget($visibleFields, 'QD', ' hidden') . zget($requiredFields, 'QD', '', ' required');?>'><?php echo $lang->execution->QD;?></th>
|
||||
<th class='c-user<?php echo zget($visibleFields, 'RD', ' hidden') . zget($requiredFields, 'RD', '', ' required');?>'><?php echo $lang->execution->RD;?></th>
|
||||
<th class='c-type<?php echo zget($visibleFields, 'type', ' hidden') . zget($requiredFields, 'type', '', ' required');?>'><?php echo $lang->execution->$type;?></th>
|
||||
<th class='c-type<?php echo zget($visibleFields, 'type', ' hidden') . zget($requiredFields, 'type', '', ' required');?>'>
|
||||
<?php echo $lang->execution->$type;?>
|
||||
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->execution->typeTip;?>"></icon>
|
||||
</th>
|
||||
<th class='c-date required'><?php echo $lang->execution->begin;?></th>
|
||||
<th class='c-date required'><?php echo $lang->execution->end;?></th>
|
||||
<th class='c-desc <?php echo zget($visibleFields, 'desc', ' hidden') . zget($requiredFields, 'desc', '', ' required');?>'><?php echo $lang->execution->$desc;?></th>
|
||||
@@ -91,7 +94,7 @@
|
||||
<td title='<?php echo zget($lang->execution->typeList, $executions[$executionID]->type);?>'><?php echo zget($lang->execution->typeList, $executions[$executionID]->type);?></td>
|
||||
<?php endif;?>
|
||||
<td title='<?php echo $executions[$executionID]->name?>'><?php echo html::input("names[$executionID]", $executions[$executionID]->name, "class='form-control' id='names{$executionID}'");?></td>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<td><?php echo html::input("codes[$executionID]", $executions[$executionID]->code, "id='codes{$executionID}' class='form-control'");?></td>
|
||||
<?php endif;?>
|
||||
<td class='text-left<?php echo zget($visibleFields, 'PM', ' hidden')?>' style='overflow:visible'><?php echo html::select("PMs[$executionID]", $pmUsers, $executions[$executionID]->PM, "class='form-control picker-select'");?></td>
|
||||
|
||||
@@ -66,7 +66,10 @@
|
||||
<tr>
|
||||
<th><?php echo $lang->execution->method;?></th>
|
||||
<td class="col-main"><?php echo html::select("type", $lang->execution->typeList, $type, "class='form-control chosen' required onchange='setType(this.value)'");?></td>
|
||||
<td colspan='2'></td>
|
||||
<td class='methodTip'>
|
||||
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->execution->agileplusMethodTip;?>"></icon>
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
@@ -74,7 +77,7 @@
|
||||
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
|
||||
<td colspan='2'></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $showExecutionExec ? $lang->execution->execCode : $lang->execution->code;?></th>
|
||||
<td><?php echo html::input('code', $code, "class='form-control' required");?></td><td></td><td></td>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
<th class='w-120px'><?php echo $lang->execution->name;?></th>
|
||||
<td><?php echo html::input('name', $execution->name, "class='form-control' required");?></td><td></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->execution->code;?></th>
|
||||
<td><?php echo html::input('code', $execution->code, "class='form-control' required");?></td>
|
||||
@@ -98,6 +98,9 @@
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->execution->typeTip;?>"></icon>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
|
||||
@@ -63,10 +63,13 @@
|
||||
$link = common::hasPriv('execution', 'importTask') ? $this->createLink('execution', 'importTask', "execution=$execution->id") : '#';
|
||||
echo "<li $class>" . html::a($link, $lang->execution->importTask, '', $misc) . "</li>";
|
||||
|
||||
$class = common::hasPriv('execution', 'importBug') ? '' : "class=disabled";
|
||||
$misc = common::hasPriv('execution', 'importBug') ? "class='import'" : "class=disabled";
|
||||
$link = common::hasPriv('execution', 'importBug') ? $this->createLink('execution', 'importBug', "execution=$execution->id") : '#';
|
||||
echo "<li $class id='importBug'>" . html::a($link, $lang->execution->importBug, '', $misc) . "</li>";
|
||||
if(isset($this->lang->execution->menu->qa))
|
||||
{
|
||||
$class = common::hasPriv('execution', 'importBug') ? '' : "class=disabled";
|
||||
$misc = common::hasPriv('execution', 'importBug') ? "class='import'" : "class=disabled";
|
||||
$link = common::hasPriv('execution', 'importBug') ? $this->createLink('execution', 'importBug', "execution=$execution->id") : '#';
|
||||
echo "<li $class id='importBug'>" . html::a($link, $lang->execution->importBug, '', $misc) . "</li>";
|
||||
}
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<?php endif;?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?>
|
||||
<?php if(isset($lang->execution->menu->qa)):?>
|
||||
<div class="input-control space c-type">
|
||||
<?php echo html::select('type', $lang->kanban->type, $browseType, 'class="form-control chosen" data-max_drop_width="215"');?>
|
||||
</div>
|
||||
@@ -62,7 +62,7 @@
|
||||
$link = common::hasPriv('execution', 'importTask') ? $this->createLink('execution', 'importTask', "execution=$execution->id") : '#';
|
||||
echo "<li $misc>" . html::a($link, $lang->execution->importTask, '', $misc) . "</li>";
|
||||
|
||||
if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review')))
|
||||
if(isset($lang->execution->menu->qa))
|
||||
{
|
||||
$misc = common::hasPriv('execution', 'importBug') ? '' : "class=disabled";
|
||||
$link = common::hasPriv('execution', 'importBug') ? $this->createLink('execution', 'importBug', "execution=$execution->id") : '#';
|
||||
@@ -102,12 +102,16 @@
|
||||
<div class='dropdown' id='createDropdown'>
|
||||
<button class='btn btn-primary' type='button' data-toggle='dropdown'><i class='icon icon-plus'></i> <?php echo $this->lang->create;?> <span class='caret'></span></button>
|
||||
<ul class='dropdown-menu pull-right'>
|
||||
<?php if($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))):?>
|
||||
<?php $showDivider = false;?>
|
||||
<?php if(isset($lang->execution->menu->story)):?>
|
||||
<?php if($canCreateStory) echo '<li>' . html::a(helper::createLink('story', 'create', "productID=$productID&branch=0&moduleID=0&story=0&execution=$execution->id", '', true), $lang->execution->createStory, '', "class='iframe' data-width='80%'") . '</li>';?>
|
||||
<?php if($canBatchCreateStory) echo '<li>' . html::a(helper::createLink('story', 'batchCreate', "productID=$productID&branch=0&moduleID=0&story=0&execution=$execution->id", '', true), $lang->execution->batchCreateStory, '', "class='iframe' data-width='90%'") . '</li>';?>
|
||||
<?php if($canLinkStory) echo '<li>' . html::a(helper::createLink('execution', 'linkStory', "execution=$execution->id", '', true), $lang->execution->linkStory, '', "class='iframe' data-width='90%'") . '</li>';?>
|
||||
<?php if($canLinkStoryByPlan) echo '<li>' . html::a('#linkStoryByPlan', $lang->execution->linkStoryByPlan, '', 'data-toggle="modal"') . '</li>';?>
|
||||
<?php if($hasStoryButton and $hasBugButton) echo '<li class="divider"></li>';?>
|
||||
<?php $showDivider = true;?>
|
||||
<?php endif;?>
|
||||
<?php if(isset($lang->execution->menu->qa)):?>
|
||||
<?php if($showDivider) echo '<li class="divider"></li>';?>
|
||||
<?php if($canCreateBug) echo '<li>' . html::a(helper::createLink('bug', 'create', "productID=$productID&branch=0&extra=executionID=$execution->id", '', true), $lang->bug->create, '', "class='iframe'") . '</li>';?>
|
||||
<?php if($canBatchCreateBug)
|
||||
{
|
||||
@@ -115,9 +119,9 @@
|
||||
if($productNum > 1) $batchCreateBugLink = '<li>' . html::a('#batchCreateBug', $lang->bug->batchCreate, '', "data-toggle='modal'") . '</li>';
|
||||
echo $batchCreateBugLink;
|
||||
}?>
|
||||
<?php if(($hasStoryButton or $hasBugButton) and $hasTaskButton) echo '<li class="divider"></li>';?>
|
||||
<?php if($canImportBug) echo '<li>' . html::a(helper::createLink('execution', 'importBug', "execution=$execution->id", '', true), $lang->execution->importBug, '', "class='iframe' data-width='90%'") . '</li>';?>
|
||||
<?php endif;?>
|
||||
<?php if($showDivider) echo '<li class="divider"></li>';?>
|
||||
<?php if($canCreateTask) echo '<li>' . html::a(helper::createLink('task', 'create', "execution=$execution->id", '', true), $lang->task->create, '', "class='iframe' data-width='80%'") . '</li>';?>
|
||||
<?php if($canBatchCreateTask) echo '<li>' . html::a(helper::createLink('task', 'batchCreate', "execution=$execution->id", '', true), $lang->execution->batchCreateTask, '', "class='iframe' data-width=90%") . '</li>';?>
|
||||
</ul>
|
||||
@@ -234,5 +238,6 @@ js::set('priv',
|
||||
<?php js::set('defaultMinColWidth', $this->config->minColWidth);?>
|
||||
<?php js::set('defaultMaxColWidth', $this->config->maxColWidth);?>
|
||||
<?php js::set('teamWords', $lang->execution->teamWords);?>
|
||||
<?php js::set('canImportBug', ($execution->lifetime != 'ops' and !in_array($execution->attribute, array('request', 'review'))))?>
|
||||
<?php js::set('canImportBug', isset($lang->execution->menu->qa));?>
|
||||
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
@@ -269,7 +269,7 @@
|
||||
<div class="col-sm-12">
|
||||
<div class="cell">
|
||||
<div class="detail">
|
||||
<?php $hiddenCode = (isset($config->setCode) and $config->setCode == 0) ? 'hidden' : '';?>
|
||||
<?php $hiddenCode = (!isset($config->setCode) or $config->setCode == 0) ? 'hidden' : '';?>
|
||||
<h2 class="detail-title"><span class="label-id"><?php echo $execution->id;?></span> <span class="label label-light label-outline <?php echo $hiddenCode;?>"><?php echo $execution->code;?></span> <?php echo $execution->name;?></h2>
|
||||
<div class="detail-content article-content">
|
||||
<div><span class="text-limit hidden" data-limit-size="40"><?php echo $execution->desc;?></span><a class="text-primary text-limit-toggle small" data-text-expand="<?php echo $lang->expand;?>" data-text-collapse="<?php echo $lang->collapse;?>"></a></div>
|
||||
|
||||
@@ -279,7 +279,7 @@ if($isCustomExport)
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->file->extension;?></th>
|
||||
<td><?php echo html::select('fileType', $lang->exportFileTypeList, '', 'onchange=switchEncode(this.value) class="form-control chosen"');?></td>
|
||||
<td><?php echo html::select('fileType', $lang->exportFileTypeList, '', 'onchange=switchEncode(this.value) class="form-control chosen" data-drop_direction="down"');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->file->encoding;?></th>
|
||||
|
||||
@@ -254,9 +254,9 @@ class group extends control
|
||||
foreach($this->lang->resource as $module => $moduleActions)
|
||||
{
|
||||
$modules[$module] = $this->lang->$module->common;
|
||||
foreach($moduleActions as $action)
|
||||
foreach($moduleActions as $key => $action)
|
||||
{
|
||||
$actions[$module][$action] = $this->lang->$module->$action;
|
||||
$actions[$module][$key] = $this->lang->$module->$action;
|
||||
}
|
||||
}
|
||||
$this->view->groups = $this->group->getPairs();
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<?php if(is_array($feature) && empty($disabledScrumFeatures)) continue;?>
|
||||
<tr class='text-center'>
|
||||
<td class='text-left'><?php echo (is_array($feature) && !empty($disabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
|
||||
<td><i class='icon text-red icon-close'></i></td>
|
||||
<td><i class='icon text-red icon-ban-circle'></i></td>
|
||||
<td><i class='icon text-success icon-check'></i></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
|
||||
@@ -198,6 +198,8 @@ class my extends control
|
||||
$meetingCount = $pager->recTotal;
|
||||
}
|
||||
|
||||
if($this->app->viewType != 'json')
|
||||
{
|
||||
echo <<<EOF
|
||||
<script>
|
||||
var taskCount = $taskCount;
|
||||
@@ -227,6 +229,7 @@ if(isMax !== 0)
|
||||
}
|
||||
</script>
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -96,7 +96,7 @@ $app->loadLang('product');
|
||||
$config->product->all = new stdclass();
|
||||
$config->product->all->search['module'] = 'product';
|
||||
$config->product->all->search['fields']['name'] = $lang->product->name;
|
||||
if(!isset($config->setCode) or $config->setCode == 1) $config->product->all->search['fields']['code'] = $lang->product->code;
|
||||
if(isset($config->setCode) and $config->setCode == 1) $config->product->all->search['fields']['code'] = $lang->product->code;
|
||||
$config->product->all->search['fields']['id'] = $lang->product->id;
|
||||
if($config->systemMode == 'ALM')
|
||||
{
|
||||
@@ -113,7 +113,7 @@ $config->product->all->search['fields']['createdDate'] = $lang->product->created
|
||||
$config->product->all->search['fields']['createdBy'] = $lang->product->createdBy;
|
||||
|
||||
$config->product->all->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
if(!isset($config->setCode) or $config->setCode == 1) $config->product->all->search['params']['code'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
if(isset($config->setCode) and $config->setCode == 1) $config->product->all->search['params']['code'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
|
||||
$config->product->all->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
|
||||
if($config->systemMode == 'ALM')
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<th><?php echo $lang->product->name;?></th>
|
||||
<td><?php echo html::input('name', '', "class='form-control input-product-title' required");?></td><td></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->code;?></th>
|
||||
<td><?php echo html::input('code', '', "class='form-control' required");?></td>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<th class='w-140px'><?php echo $lang->product->name;?></th>
|
||||
<td class='w-p40-f'><?php echo html::input('name', $product->name, "class='form-control' required");?></td><td></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->product->code;?></th>
|
||||
<td><?php echo html::input('code', $product->code, "class='form-control' required");?></td><td></td>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="col-sm-12">
|
||||
<div class="cell">
|
||||
<div class="detail">
|
||||
<?php $hiddenCode = (isset($config->setCode) and $config->setCode == 0) ? 'hidden' : '';?>
|
||||
<?php $hiddenCode = (!isset($config->setCode) or $config->setCode == 0) ? 'hidden' : '';?>
|
||||
<h2 class="detail-title"><span class="label-id"><?php echo $product->id;?></span> <span class="label label-light label-outline <?php echo $hiddenCode;?>"><?php echo $product->code;?></span> <?php echo $product->name;?></h2>
|
||||
<div class="detail-content article-content">
|
||||
<p><?php echo $product->desc;?></p>
|
||||
|
||||
Regular → Executable
+1
-1
@@ -20,4 +20,4 @@ div.checkbox-primary + span.table-nest-icon {margin-left: 0px !important;}
|
||||
#checkAll + label.hover:after {border-width: 0px;}
|
||||
.c-budget {width:100px; text-align: right; padding-right:16px !important;}
|
||||
.c-status {width: 65px !important;}
|
||||
.icon-scrum.table-nest-toggle:after, .icon-waterfall.table-nest-toggle:after, .icon-kanban.table-nest-toggle:after {content: ''; border: 0;}
|
||||
.icon-scrum.table-nest-toggle:after, .icon-waterfall.table-nest-toggle:after, .icon-kanban.table-nest-toggle:after, .icon-waterfallplus.table-nest-toggle:after, .icon-aglieplus.table-nest-toggle:after {content: ''; border: 0;}
|
||||
|
||||
Regular → Executable
+2
@@ -122,6 +122,8 @@ th.table-nest-title > .table-nest-toggle-global:before {width: 100%; left: 0 !im
|
||||
#programTableList .icon-scrum:before {content: '\e9a2';}
|
||||
#programTableList .icon-waterfall:before {content: '\e9a4';}
|
||||
#programTableList .icon-kanban:before {content: '\e983';}
|
||||
#programTableList .icon-waterfallplus:before {content: '\e9ed';}
|
||||
#programTableList .icon-agileplus:before {content: '\e9ee';}
|
||||
#programTableList > tr[data-type="program"] > .c-name > a {color: #0b0f18;}
|
||||
#programTableList > tr[data-nest-parent] {background: #f8f8f8;}
|
||||
</style>
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#planForm tr td {vertical-align: top;}
|
||||
#mainContent .methodTitle, #mainContent .methodTip {display: inline-block; vertical-align: middle;}
|
||||
|
||||
@@ -5,6 +5,8 @@ $(function()
|
||||
$(this).removeClass('has-error');
|
||||
$(this).closest('td').find('.text-danger.help-text').remove();
|
||||
});
|
||||
|
||||
$('[data-toggle="popover"]').popover();
|
||||
});
|
||||
/**
|
||||
* Add item to create view of programplan.
|
||||
|
||||
@@ -57,4 +57,6 @@ $(function()
|
||||
if(!result) return false;
|
||||
}
|
||||
})
|
||||
|
||||
$('[data-toggle="popover"]').popover();
|
||||
})
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->programplan->delete = 'Delete Stage';
|
||||
$lang->programplan->close = 'Close Stage';
|
||||
$lang->programplan->activate = 'Activate Stage';
|
||||
$lang->programplan->createSubPlan = 'Create Sub Plan';
|
||||
$lang->programplan->subPlanManage = 'Sub-stages management';
|
||||
|
||||
$lang->programplan->parent = 'Parent Stage';
|
||||
$lang->programplan->emptyParent = 'N/A';
|
||||
@@ -72,6 +73,7 @@ $lang->programplan->emptyBegin = '『Begin』should not be blank';
|
||||
$lang->programplan->emptyEnd = '『End』should not be blank';
|
||||
$lang->programplan->checkBegin = '『Begin』should be valid date';
|
||||
$lang->programplan->checkEnd = '『End』should be valid date';
|
||||
$lang->programplan->methodTip = 'When creating sub-stages in a Waterfall Plus project stage, you can choose to create them as stages or as Iterations/Kanban. If the sub-stage is created as an Iteration/Kanban, it does not support creating sub-levels further down.';
|
||||
|
||||
$lang->programplan->milestoneList[1] = 'Yes';
|
||||
$lang->programplan->milestoneList[0] = 'No';
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->programplan->delete = 'Delete Stage';
|
||||
$lang->programplan->close = 'Close Stage';
|
||||
$lang->programplan->activate = 'Activate Stage';
|
||||
$lang->programplan->createSubPlan = 'Create Sub Stage';
|
||||
$lang->programplan->subPlanManage = 'Sub-stages management';
|
||||
|
||||
$lang->programplan->parent = 'Parent Stage';
|
||||
$lang->programplan->emptyParent = 'N/A';
|
||||
@@ -72,6 +73,7 @@ $lang->programplan->emptyBegin = '『Begin』should not be blank';
|
||||
$lang->programplan->emptyEnd = '『End』should not be blank';
|
||||
$lang->programplan->checkBegin = '『Begin』should be valid date';
|
||||
$lang->programplan->checkEnd = '『End』should be valid date';
|
||||
$lang->programplan->methodTip = 'When creating sub-stages in a Waterfall Plus project stage, you can choose to create them as stages or as Iterations/Kanban. If the sub-stage is created as an Iteration/Kanban, it does not support creating sub-levels further down.';
|
||||
|
||||
$lang->programplan->milestoneList[1] = 'Yes';
|
||||
$lang->programplan->milestoneList[0] = 'No';
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->programplan->delete = 'Delete Stage';
|
||||
$lang->programplan->close = 'Close Stage';
|
||||
$lang->programplan->activate = 'Activate Stage';
|
||||
$lang->programplan->createSubPlan = 'Create Sub Plan';
|
||||
$lang->programplan->subPlanManage = 'Sub-stages management';
|
||||
|
||||
$lang->programplan->parent = 'Parent Stage';
|
||||
$lang->programplan->emptyParent = 'N/A';
|
||||
@@ -72,6 +73,7 @@ $lang->programplan->emptyBegin = '『Begin』should not be blank';
|
||||
$lang->programplan->emptyEnd = '『End』should not be blank';
|
||||
$lang->programplan->checkBegin = '『Begin』should be valid date';
|
||||
$lang->programplan->checkEnd = '『End』should be valid date';
|
||||
$lang->programplan->methodTip = 'When creating sub-stages in a Waterfall Plus project stage, you can choose to create them as stages or as Iterations/Kanban. If the sub-stage is created as an Iteration/Kanban, it does not support creating sub-levels further down.';
|
||||
|
||||
$lang->programplan->milestoneList[1] = 'Yes';
|
||||
$lang->programplan->milestoneList[0] = 'No';
|
||||
|
||||
@@ -20,6 +20,7 @@ $lang->programplan->delete = '删除阶段';
|
||||
$lang->programplan->close = '关闭阶段';
|
||||
$lang->programplan->activate = '激活阶段';
|
||||
$lang->programplan->createSubPlan = '创建子阶段';
|
||||
$lang->programplan->subPlanManage = '子阶段的管理方法';
|
||||
|
||||
$lang->programplan->parent = '父阶段';
|
||||
$lang->programplan->emptyParent = '无';
|
||||
@@ -72,6 +73,7 @@ $lang->programplan->emptyBegin = '『计划开始』日期不能为空';
|
||||
$lang->programplan->emptyEnd = '『计划完成』日期不能为空';
|
||||
$lang->programplan->checkBegin = '『计划开始』应当为合法的日期';
|
||||
$lang->programplan->checkEnd = '『计划完成』应当为合法的日期';
|
||||
$lang->programplan->methodTip = '融合瀑布项目阶段子阶段创建时,可以选择创建为阶段或创建为迭代/看板。子阶段为迭代/看板,不支持继续向下创建子级。';
|
||||
|
||||
$lang->programplan->milestoneList[1] = '是';
|
||||
$lang->programplan->milestoneList[0] = '否';
|
||||
|
||||
@@ -714,7 +714,7 @@ class programplanModel extends model
|
||||
$sameNames = array_diff_assoc($names, array_unique($names));
|
||||
|
||||
$project = $this->loadModel('project')->getByID($projectID);
|
||||
$setCode = (!isset($this->config->setCode) or $this->config->setCode == 1) ? true : false;
|
||||
$setCode = (isset($this->config->setCode) and $this->config->setCode == 1) ? true : false;
|
||||
$sameCodes = $this->checkCodeUnique($codes, isset($planIDList) ? $planIDList : '');
|
||||
|
||||
$datas = array();
|
||||
@@ -1075,7 +1075,7 @@ class programplanModel extends model
|
||||
if($projectID) $this->loadModel('execution')->checkBeginAndEndDate($projectID, $plan->begin, $plan->end);
|
||||
if(dao::isError()) return false;
|
||||
|
||||
$setCode = (!isset($this->config->setCode) or $this->config->setCode == 1) ? true : false;
|
||||
$setCode = (isset($this->config->setCode) and $this->config->setCode == 1) ? true : false;
|
||||
if($setCode and empty($plan->code))
|
||||
{
|
||||
dao::$errors['code'][] = sprintf($this->lang->error->notempty, $this->lang->execution->code);
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<div class='main-header'>
|
||||
<?php if(!empty($planID) and $project->model == 'waterfallplus'):?>
|
||||
<div class="pull-left">
|
||||
<div class='methodTitle'><strong><?php echo $lang->programplan->subPlanManage . ':'?></strong></div>
|
||||
<div class='btn-group'>
|
||||
<a href='javascript:;' class='btn btn-link btn-limit' data-toggle='dropdown'><span class='text' title='<?php echo zget($lang->programplan->typeList, $executionType);?>'><?php echo zget($lang->programplan->typeList, $executionType);?></span> <span class='caret'></span></a>
|
||||
<ul class='dropdown-menu' style='max-height:240px; max-width: 300px; overflow-y:auto'>
|
||||
@@ -57,6 +58,7 @@
|
||||
?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class='methodTip'><icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->programplan->methodTip;?>"></icon></div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="btn-toolbar pull-right">
|
||||
@@ -76,7 +78,7 @@
|
||||
<tr class='text-center'>
|
||||
<th class='c-type<?php echo $typeClass;?> required'><?php echo $lang->execution->method;?></th>
|
||||
<th class='c-name required'><?php echo $executionType == 'stage' ? $name : $lang->nameAB;?></th>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<th class='c-code required'><?php echo $executionType == 'stage' ? $lang->execution->code : $lang->code;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-pm <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>'><?php echo $executionType == 'stage' ? $lang->programplan->PM : $lang->programplan->PMAB;?></th>
|
||||
@@ -106,7 +108,7 @@
|
||||
<?php foreach($stages as $stage):?>
|
||||
<tr>
|
||||
<td><input type='text' name='names[<?php echo $i;?>]' id='names<?php echo $i;?>' value='<?php echo $stage->name;?>' class='form-control' /></td>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<td><?php echo html::input("codes[$i]", isset($stage->code) ? $stage->code : '', "class='form-control'");?></td>
|
||||
<?php endif;?>
|
||||
<td <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>><?php echo html::select("PM[$i]", $PMUsers, '', "class='form-control picker-select'");?></td>
|
||||
@@ -142,7 +144,7 @@
|
||||
<tr>
|
||||
<td class='<?php echo $typeClass . ' text-center ' .zget($lang->execution->typeList, $plan->type);?>'><?php echo zget($lang->execution->typeList, $plan->type);?></td>
|
||||
<td><input type='text' name="names[<?php echo $i;?>]" id='names<?php echo $i;?>' value='<?php echo $plan->name;?>' class='form-control' /></td>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<td><?php echo html::input("codes[$i]", $plan->code, "class='form-control'");?></td>
|
||||
<?php endif;?>
|
||||
<td <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>><?php echo html::select("PM[$i]", $PMUsers, $plan->PM, "class='form-control picker-select'");?></td>
|
||||
@@ -178,7 +180,7 @@
|
||||
<tr class='addedItem'>
|
||||
<td class='<?php echo $typeClass;?>'><?php echo html::select("type[$i]", $lang->execution->typeList, '', "class='form-control chosen'");?></td>
|
||||
<td><input type='text' name='names[<?php echo $i;?>]' id='names<?php echo $i;?>' value='' class='form-control' /></td>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<td><?php echo html::input("codes[$i]", '', "class='form-control'");?></td>
|
||||
<?php endif;?>
|
||||
<td <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>><?php echo html::select("PM[$i]", $PMUsers, '', "class='form-control picker-select'");?></td>
|
||||
@@ -225,7 +227,7 @@
|
||||
<tr id='addItem' class='hidden'>
|
||||
<td class='<?php echo $typeClass;?>'><?php echo html::select("type[$i]", $lang->execution->typeList, '', "class='form-control chosen'");?></td>
|
||||
<td><input type='text' name='<?php echo "names[$i]";?>' id='names<?php echo $i;?>' class='form-control' /></td>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<td><?php echo html::input("codes[$i]", '', "class='form-control'");?></td>
|
||||
<?php endif;?>
|
||||
<td <?php echo zget($visibleFields, 'PM', ' hidden') . zget($requiredFields, 'PM', '', ' required');?>><?php echo html::select("PM[$i]", $PMUsers, '', "class='form-control' id='PM$i'");?></td>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<th class='w-100px'><?php echo $lang->programplan->name;?> </th>
|
||||
<td colspan='2'><?php echo html::input('name', $plan->name, "class='form-control'");?></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th class='w-100px'><?php echo $lang->execution->code;?> </th>
|
||||
<td class='required' colspan='2'><?php echo html::input('code', $plan->code, "class='form-control'");?></td>
|
||||
@@ -60,6 +60,9 @@
|
||||
<td colspan='2'>
|
||||
<?php echo $enableOptionalAttr ? html::select('attribute', $lang->stage->typeList, $plan->attribute, "class='form-control'") : zget($lang->stage->typeList, $plan->attribute);?>
|
||||
</td>
|
||||
<td>
|
||||
<icon class='icon icon-help' data-toggle='popover' data-trigger='focus hover' data-placement='right' data-tip-class='text-muted popover-sm' data-content="<?php echo $lang->execution->typeTip;?>"></icon>
|
||||
</td>
|
||||
</tr>
|
||||
<?php if($plan->setMilestone):?>
|
||||
<tr>
|
||||
|
||||
@@ -136,7 +136,7 @@ $config->project->datatable->fieldList['actions']['width'] = '165';
|
||||
$config->project->datatable->fieldList['actions']['required'] = 'yes';
|
||||
$config->project->datatable->fieldList['actions']['pri'] = '1';
|
||||
|
||||
if(isset($config->setCode) and $config->setCode == 0) unset($config->project->datatable->fieldList['code']);
|
||||
if(!isset($config->setCode) or $config->setCode == 0) unset($config->project->datatable->fieldList['code']);
|
||||
|
||||
$config->project->checkList = new stdclass();
|
||||
$config->project->checkList->scrum = array('bug', 'execution', 'build', 'doc', 'release', 'testtask', 'case');
|
||||
|
||||
@@ -68,7 +68,7 @@ class project extends control
|
||||
$fields[$fieldName] = zget($projectLang, $fieldName);
|
||||
unset($fields[$key]);
|
||||
}
|
||||
if(isset($this->config->setCode) and empty($this->config->setCode)) unset($fields['code']);
|
||||
if(!isset($this->config->setCode) or empty($this->config->setCode)) unset($fields['code']);
|
||||
|
||||
if(isset($fields['hasProduct'])) $fields['hasProduct'] = $projectLang->type;
|
||||
|
||||
|
||||
@@ -1023,7 +1023,7 @@ class projectModel extends model
|
||||
$programPairs += $this->loadModel('program')->getPairs();
|
||||
$this->config->project->search['params']['parent']['values'] = $programPairs;
|
||||
|
||||
if(isset($this->config->setCode) and $this->config->setCode == 0) unset($this->config->project->search['fields']['code'], $this->config->project->search['params']['code']);
|
||||
if(!isset($this->config->setCode) or $this->config->setCode == 0) unset($this->config->project->search['fields']['code'], $this->config->project->search['params']['code']);
|
||||
if($this->config->systemMode == 'light') unset($this->config->project->search['fields']['parent'], $this->config->project->search['params']['parent']);
|
||||
|
||||
$this->loadModel('search')->setSearchParams($this->config->project->search);
|
||||
@@ -1250,7 +1250,7 @@ class projectModel extends model
|
||||
->stripTags($this->config->project->editor->create['id'], $this->config->allowedTags)
|
||||
->remove('products,branch,plans,delta,newProduct,productName,future,contactListMenu,teamMembers')
|
||||
->get();
|
||||
if(isset($this->config->setCode) and $this->config->setCode == 0) unset($project->code);
|
||||
if(!isset($this->config->setCode) or $this->config->setCode == 0) unset($project->code);
|
||||
|
||||
/* Lean mode relation defaultProgram. */
|
||||
if($this->config->systemMode == 'light') $project->parent = $this->config->global->defaultProgram;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<th class='c-parent'><?php echo $lang->project->parent;?></th>
|
||||
<?php endif;?>
|
||||
<th class='c-name required'><?php echo $lang->project->name;?></th>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<th class='c-name required'><?php echo $lang->project->code;?></th>
|
||||
<?php endif?>
|
||||
<th class="c-user-box <?php echo strpos($requiredFields, 'PM') !== false ? 'required' : '';?>"> <?php echo $lang->project->PM;?></th>
|
||||
@@ -63,7 +63,7 @@
|
||||
<?php endif;?>
|
||||
<?php endif;?>
|
||||
<td title='<?php echo $project->name;?>'><?php echo html::input("names[$projectID]", $project->name, "class='form-control'");?></td>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<td title='<?php echo $project->code;?>'><?php echo html::input("codes[$projectID]", $project->code, "class='form-control'");?></td>
|
||||
<?php endif;?>
|
||||
<td><?php echo html::select("PMs[$projectID]", $PMUsers, $project->PM, "class='form-control chosen'");?></td>
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
<h2><?php echo $createTitle;?></h2>
|
||||
<?php if(!commonModel::isTutorialMode()): ?>
|
||||
<div class="pull-right btn-toolbar">
|
||||
<?php if($config->edition != 'max' or $model == 'kanban'):?>
|
||||
<button type='button' class='btn btn-link' data-toggle='modal' data-target='#copyProjectModal'><?php echo html::icon($lang->icons['copy'], 'muted') . ' ' . $lang->project->copy;?></button>
|
||||
<?php else: ?>
|
||||
<button type='button' class='btn btn-link open-btn' data-toggle='modal' data-target='#maxCopyProjectModal'><?php echo html::icon($lang->icons['copy'], 'muted') . ' ' . $lang->project->copy;?></button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -69,7 +73,7 @@
|
||||
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->code;?></th>
|
||||
<td><?php echo html::input('code', $code, "class='form-control' required");?></td>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<td class="col-main"><?php echo html::input('name', $project->name, "class='form-control' required");?></td>
|
||||
<td colspan='2'></td>
|
||||
</tr>
|
||||
<?php if(!isset($config->setCode) or $config->setCode == 1):?>
|
||||
<?php if(isset($config->setCode) and $config->setCode == 1):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->project->code;?></th>
|
||||
<td><?php echo html::input('code', $project->code, "class='form-control' required");?></td>
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
<div class="col-sm-12">
|
||||
<div class="cell">
|
||||
<div class="detail">
|
||||
<?php $hiddenCode = (isset($config->setCode) and $config->setCode == 0) ? 'hidden' : '';?>
|
||||
<?php $hiddenCode = (!isset($config->setCode) or $config->setCode == 0) ? 'hidden' : '';?>
|
||||
<h2 class="detail-title"><span class="label-id"><?php echo $project->id;?></span> <span class="label label-light label-outline <?php echo $hiddenCode;?>"><?php echo $project->code;?></span> <?php echo $project->name;?></h2>
|
||||
<div class="detail-content article-content">
|
||||
<div><span class="text-limit hidden" data-limit-size="40"><?php echo $project->desc;?></span><a class="text-primary text-limit-toggle small" data-text-expand="<?php echo $lang->expand;?>" data-text-collapse="<?php echo $lang->collapse;?>"></a></div>
|
||||
|
||||
@@ -599,7 +599,7 @@ class repo extends control
|
||||
}
|
||||
|
||||
/* Refresh repo. */
|
||||
if($refresh) $this->repo->updateCommit($repoID, $originBranchID);
|
||||
if($refresh) $this->repo->updateCommit($repoID, $objectID, $originBranchID);
|
||||
|
||||
/* Get files info. */
|
||||
$infos = $this->repo->getFileCommits($repo, $branchID, $path);
|
||||
|
||||
@@ -2810,7 +2810,7 @@ class repoModel extends model
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function updateCommit($repoID, $branchID = 0)
|
||||
public function updateCommit($repoID, $objectID = 0, $branchID = 0)
|
||||
{
|
||||
$repo = $this->getRepoByID($repoID);
|
||||
/* Update code commit history. */
|
||||
|
||||
@@ -199,7 +199,7 @@ class stageModel extends model
|
||||
$moduleName = $this->app->rawModule;
|
||||
$methodName = $this->app->rawMethod;
|
||||
if(!isset($this->lang->admin->menuList->model['subMenu']['waterfall']['exclude'])) $this->lang->admin->menuList->model['subMenu']['waterfall']['exclude'] = '';
|
||||
if(!isset($this->lang->admin->menuList->model['subMenu']['waterfallplus']['exclude'])) $this->lang->admin->menuList->model['subMenu']['agileplus']['exclude'] = '';
|
||||
if(!isset($this->lang->admin->menuList->model['subMenu']['waterfallplus']['exclude'])) $this->lang->admin->menuList->model['subMenu']['waterfallplus']['exclude'] = '';
|
||||
if($type == 'waterfall')
|
||||
{
|
||||
$this->lang->admin->menuList->model['subMenu']['waterfallplus']['exclude'] .= ",{$moduleName}-{$methodName}";
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<?php if(is_array($feature) && empty($disabledScrumFeatures)) continue;?>
|
||||
<tr class='text-center'>
|
||||
<td class='text-left'><?php echo (is_array($feature) && !empty($disabledScrumFeatures)) ? sprintf($this->lang->custom->scrum->common, implode($lang->comma, $disabledScrumFeatures)) : $this->lang->custom->features[$feature];?></td>
|
||||
<td><i class='icon text-red icon-close'></i></td>
|
||||
<td><i class='icon text-red icon-ban-circle'></i></td>
|
||||
<td><i class='icon text-success icon-check'></i></td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
|
||||
Reference in New Issue
Block a user