Page MenuHomePhabricator

D15088.id36429.diff
No OneTemporary

D15088.id36429.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2858,6 +2858,7 @@
'PhabricatorProjectBoardImportController' => 'applications/project/controller/PhabricatorProjectBoardImportController.php',
'PhabricatorProjectBoardReorderController' => 'applications/project/controller/PhabricatorProjectBoardReorderController.php',
'PhabricatorProjectBoardViewController' => 'applications/project/controller/PhabricatorProjectBoardViewController.php',
+ 'PhabricatorProjectColorsConfigOptionType' => 'applications/project/config/PhabricatorProjectColorsConfigOptionType.php',
'PhabricatorProjectColumn' => 'applications/project/storage/PhabricatorProjectColumn.php',
'PhabricatorProjectColumnDetailController' => 'applications/project/controller/PhabricatorProjectColumnDetailController.php',
'PhabricatorProjectColumnEditController' => 'applications/project/controller/PhabricatorProjectColumnEditController.php',
@@ -2890,6 +2891,7 @@
'PhabricatorProjectHeraldFieldGroup' => 'applications/project/herald/PhabricatorProjectHeraldFieldGroup.php',
'PhabricatorProjectHistoryController' => 'applications/project/controller/PhabricatorProjectHistoryController.php',
'PhabricatorProjectIconSet' => 'applications/project/icon/PhabricatorProjectIconSet.php',
+ 'PhabricatorProjectIconsConfigOptionType' => 'applications/project/config/PhabricatorProjectIconsConfigOptionType.php',
'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php',
'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
'PhabricatorProjectListView' => 'applications/project/view/PhabricatorProjectListView.php',
@@ -2937,7 +2939,6 @@
'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php',
'PhabricatorProjectTransactionEditor' => 'applications/project/editor/PhabricatorProjectTransactionEditor.php',
'PhabricatorProjectTransactionQuery' => 'applications/project/query/PhabricatorProjectTransactionQuery.php',
- 'PhabricatorProjectTypeConfigOptionType' => 'applications/project/config/PhabricatorProjectTypeConfigOptionType.php',
'PhabricatorProjectUIEventListener' => 'applications/project/events/PhabricatorProjectUIEventListener.php',
'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
'PhabricatorProjectUserFunctionDatasource' => 'applications/project/typeahead/PhabricatorProjectUserFunctionDatasource.php',
@@ -7255,6 +7256,7 @@
'PhabricatorProjectBoardImportController' => 'PhabricatorProjectBoardController',
'PhabricatorProjectBoardReorderController' => 'PhabricatorProjectBoardController',
'PhabricatorProjectBoardViewController' => 'PhabricatorProjectBoardController',
+ 'PhabricatorProjectColorsConfigOptionType' => 'PhabricatorConfigJSONOptionType',
'PhabricatorProjectColumn' => array(
'PhabricatorProjectDAO',
'PhabricatorApplicationTransactionInterface',
@@ -7298,6 +7300,7 @@
'PhabricatorProjectHeraldFieldGroup' => 'HeraldFieldGroup',
'PhabricatorProjectHistoryController' => 'PhabricatorProjectController',
'PhabricatorProjectIconSet' => 'PhabricatorIconSet',
+ 'PhabricatorProjectIconsConfigOptionType' => 'PhabricatorConfigJSONOptionType',
'PhabricatorProjectListController' => 'PhabricatorProjectController',
'PhabricatorProjectListView' => 'AphrontView',
'PhabricatorProjectLockController' => 'PhabricatorProjectController',
@@ -7347,7 +7350,6 @@
'PhabricatorProjectTransaction' => 'PhabricatorApplicationTransaction',
'PhabricatorProjectTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorProjectTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
- 'PhabricatorProjectTypeConfigOptionType' => 'PhabricatorConfigJSONOptionType',
'PhabricatorProjectUIEventListener' => 'PhabricatorEventListener',
'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
'PhabricatorProjectUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
diff --git a/src/applications/project/config/PhabricatorProjectTypeConfigOptionType.php b/src/applications/project/config/PhabricatorProjectColorsConfigOptionType.php
rename from src/applications/project/config/PhabricatorProjectTypeConfigOptionType.php
rename to src/applications/project/config/PhabricatorProjectColorsConfigOptionType.php
--- a/src/applications/project/config/PhabricatorProjectTypeConfigOptionType.php
+++ b/src/applications/project/config/PhabricatorProjectColorsConfigOptionType.php
@@ -1,10 +1,10 @@
<?php
-final class PhabricatorProjectTypeConfigOptionType
+final class PhabricatorProjectColorsConfigOptionType
extends PhabricatorConfigJSONOptionType {
public function validateOption(PhabricatorConfigOption $option, $value) {
- PhabricatorProjectIconSet::validateConfiguration($value);
+ PhabricatorProjectIconSet::validateColorConfiguration($value);
}
}
diff --git a/src/applications/project/config/PhabricatorProjectConfigOptions.php b/src/applications/project/config/PhabricatorProjectConfigOptions.php
--- a/src/applications/project/config/PhabricatorProjectConfigOptions.php
+++ b/src/applications/project/config/PhabricatorProjectConfigOptions.php
@@ -21,7 +21,7 @@
public function getOptions() {
$default_icons = PhabricatorProjectIconSet::getDefaultConfiguration();
- $icons_type = 'custom:PhabricatorProjectTypeConfigOptionType';
+ $icons_type = 'custom:PhabricatorProjectIconsConfigOptionType';
$icons_description = $this->deformat(pht(<<<EOTEXT
Allows you to change and customize the available project icons.
@@ -47,6 +47,27 @@
EOTEXT
));
+ $default_colors = PhabricatorProjectIconSet::getDefaultColorMap();
+ $colors_type = 'custom:PhabricatorProjectColorsConfigOptionType';
+
+ $colors_description = $this->deformat(pht(<<<EOTEXT
+Allows you to relabel project colors.
+
+The list of available colors can not be expanded, but the existing colors may
+be given labels.
+
+Configure a list of color specifications. Each color specification should be a
+dictionary, which may contain these keys:
+
+ - `key` //Required string.// The internal key identifying the color.
+ - `name` //Required string.// Human-readable label for the color.
+ - `default` //Optional bool.// Selects the default color used when creating
+ new projects. Exactly one color must be selected as the default.
+
+You can look at the default configuration below for an example of a valid
+configuration.
+EOTEXT
+ ));
$default_fields = array(
'std:project:internal:description' => true,
@@ -76,6 +97,9 @@
$this->newOption('projects.icons', $icons_type, $default_icons)
->setSummary(pht('Adjust project icons.'))
->setDescription($icons_description),
+ $this->newOption('projects.colors', $colors_type, $default_colors)
+ ->setSummary(pht('Adjust project colors.'))
+ ->setDescription($colors_description),
);
}
diff --git a/src/applications/project/config/PhabricatorProjectTypeConfigOptionType.php b/src/applications/project/config/PhabricatorProjectIconsConfigOptionType.php
rename from src/applications/project/config/PhabricatorProjectTypeConfigOptionType.php
rename to src/applications/project/config/PhabricatorProjectIconsConfigOptionType.php
--- a/src/applications/project/config/PhabricatorProjectTypeConfigOptionType.php
+++ b/src/applications/project/config/PhabricatorProjectIconsConfigOptionType.php
@@ -1,6 +1,6 @@
<?php
-final class PhabricatorProjectTypeConfigOptionType
+final class PhabricatorProjectIconsConfigOptionType
extends PhabricatorConfigJSONOptionType {
public function validateOption(PhabricatorConfigOption $option, $value) {
diff --git a/src/applications/project/icon/PhabricatorProjectIconSet.php b/src/applications/project/icon/PhabricatorProjectIconSet.php
--- a/src/applications/project/icon/PhabricatorProjectIconSet.php
+++ b/src/applications/project/icon/PhabricatorProjectIconSet.php
@@ -125,16 +125,6 @@
return $icons;
}
- public static function getColorMap() {
- $shades = PHUITagView::getShadeMap();
- $shades = array_select_keys(
- $shades,
- array(PhabricatorProject::DEFAULT_COLOR)) + $shades;
- unset($shades[PHUITagView::COLOR_DISABLED]);
-
- return $shades;
- }
-
private static function getIconSpecifications() {
return PhabricatorEnv::getEnvConfig('projects.icons');
}
@@ -314,4 +304,157 @@
}
+ private static function getColorSpecifications() {
+ return PhabricatorEnv::getEnvConfig('projects.colors');
+ }
+
+ public static function getColorMap() {
+ $specifications = self::getColorSpecifications();
+ return ipull($specifications, 'name', 'key');
+ }
+
+ public static function getDefaultColorKey() {
+ $specifications = self::getColorSpecifications();
+
+ foreach ($specifications as $specification) {
+ if (idx($specification, 'default')) {
+ return $specification['key'];
+ }
+ }
+
+ return null;
+ }
+
+ private static function getAvailableColorKeys() {
+ $list = array();
+
+ $specifications = self::getDefaultColorMap();
+ foreach ($specifications as $specification) {
+ $list[] = $specification['key'];
+ }
+
+ return $list;
+ }
+
+ public static function getDefaultColorMap() {
+ return array(
+ array(
+ 'key' => PHUITagView::COLOR_RED,
+ 'name' => pht('Red'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_ORANGE,
+ 'name' => pht('Orange'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_YELLOW,
+ 'name' => pht('Yellow'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_GREEN,
+ 'name' => pht('Green'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_BLUE,
+ 'name' => pht('Blue'),
+ 'default' => true,
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_INDIGO,
+ 'name' => pht('Indigo'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_VIOLET,
+ 'name' => pht('Violet'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_PINK,
+ 'name' => pht('Pink'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_GREY,
+ 'name' => pht('Grey'),
+ ),
+ array(
+ 'key' => PHUITagView::COLOR_CHECKERED,
+ 'name' => pht('Checkered'),
+ ),
+ );
+ }
+
+ public static function validateColorConfiguration($config) {
+ if (!is_array($config)) {
+ throw new Exception(
+ pht('Configuration must be a list of project color specifications.'));
+ }
+
+ $available_keys = self::getAvailableColorKeys();
+ $available_keys = array_fuse($available_keys);
+
+ foreach ($config as $idx => $value) {
+ if (!is_array($value)) {
+ throw new Exception(
+ pht(
+ 'Value for index "%s" should be a dictionary.',
+ $idx));
+ }
+
+ PhutilTypeSpec::checkMap(
+ $value,
+ array(
+ 'key' => 'string',
+ 'name' => 'string',
+ 'default' => 'optional bool',
+ ));
+
+ $key = $value['key'];
+ if (!isset($available_keys[$key])) {
+ throw new Exception(
+ pht(
+ 'Color key "%s" is not a valid color key. The supported color '.
+ 'keys are: %s.',
+ $key,
+ implode(', ', $available_keys)));
+ }
+ }
+
+ $default = null;
+ $keys = array();
+ foreach ($config as $idx => $value) {
+ $key = $value['key'];
+ if (isset($keys[$key])) {
+ throw new Exception(
+ pht(
+ 'Project colors must have unique keys, but two icons share the '.
+ 'same key ("%s").',
+ $key));
+ } else {
+ $keys[$key] = true;
+ }
+
+ if (idx($value, 'default')) {
+ if ($default === null) {
+ $default = $value;
+ } else {
+ $original_key = $default['key'];
+ throw new Exception(
+ pht(
+ 'Two different colors ("%s", "%s") are marked as the default '.
+ 'color. Only one color may be marked as the default.',
+ $key,
+ $original_key));
+ }
+ }
+ }
+
+ if ($default === null) {
+ throw new Exception(
+ pht(
+ 'Project colors must include one color marked as the "%s" color, '.
+ 'but no such color exists.',
+ 'default'));
+ }
+
+ }
+
}
diff --git a/src/applications/project/query/PhabricatorProjectSearchEngine.php b/src/applications/project/query/PhabricatorProjectSearchEngine.php
--- a/src/applications/project/query/PhabricatorProjectSearchEngine.php
+++ b/src/applications/project/query/PhabricatorProjectSearchEngine.php
@@ -42,7 +42,7 @@
}
-protected function buildQueryFromParameters(array $map) {
+ protected function buildQueryFromParameters(array $map) {
$query = $this->newQuery();
if (strlen($map['name'])) {
@@ -155,8 +155,6 @@
->setType(PHUITagView::TYPE_SHADE)
->setShade($color)
->setName($name),
- ' ',
- $name,
);
}
diff --git a/src/applications/project/storage/PhabricatorProject.php b/src/applications/project/storage/PhabricatorProject.php
--- a/src/applications/project/storage/PhabricatorProject.php
+++ b/src/applications/project/storage/PhabricatorProject.php
@@ -44,8 +44,6 @@
private $slugs = self::ATTACHABLE;
private $parentProject = self::ATTACHABLE;
- const DEFAULT_COLOR = 'blue';
-
const TABLE_DATASOURCE_TOKEN = 'project_datasourcetoken';
const PANEL_PROFILE = 'project.profile';
@@ -68,11 +66,12 @@
ProjectDefaultJoinCapability::CAPABILITY);
$default_icon = PhabricatorProjectIconSet::getDefaultIconKey();
+ $default_color = PhabricatorProjectIconSet::getDefaultColorKey();
return id(new PhabricatorProject())
->setAuthorPHID($actor->getPHID())
->setIcon($default_icon)
- ->setColor(self::DEFAULT_COLOR)
+ ->setColor($default_color)
->setViewPolicy($view_policy)
->setEditPolicy($edit_policy)
->setJoinPolicy($join_policy)
@@ -511,7 +510,7 @@
public function getDisplayColor() {
if ($this->isMilestone()) {
- return self::DEFAULT_COLOR;
+ return PhabricatorProjectIconSet::getDefaultColorKey();
}
return $this->getColor();

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 18, 1:49 AM (4 w, 17 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7389296
Default Alt Text
D15088.id36429.diff (14 KB)

Event Timeline