Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15398825
D15088.id36429.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Referenced Files
None
Subscribers
None
D15088.id36429.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D15088: Allow project colors to be relabeled
Attached
Detach File
Event Timeline
Log In to Comment