mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Allow projects to be quickly added from the Maniphest task creation interface
Summary: Provide a quick workflow for adding a new project. This ended up being sort of complicated because we don't currently put forms in dialogs. I separated the actual <form /> tag out of the display/layout of AphrontFormView to enable this (the dialog is itself a form). Limitations: if you create a new project and then remove it, it won't appear in the tokenizer until you reload the page. We need to add the ability for the datasource to drop its cache to enable this, which is super complicated. Test Plan: Used "Create new project" to add a new project when creating a task. Reviewed By: aran Reviewers: jungejason, tuomaspelkonen, aran CC: anjali, aran, epriestley Differential Revision: 422
This commit is contained in:
parent
d710fc097f
commit
eab768f705
18 changed files with 366 additions and 68 deletions
|
@ -36,7 +36,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'aphront-dialog-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/79613f9b/rsrc/css/aphront/dialog-view.css',
|
||||
'uri' => '/res/61a58113/rsrc/css/aphront/dialog-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -45,7 +45,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'aphront-error-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/98c5fc69/rsrc/css/aphront/error-view.css',
|
||||
'uri' => '/res/e4c5e4ed/rsrc/css/aphront/error-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -54,7 +54,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'aphront-form-view-css' =>
|
||||
array(
|
||||
'uri' => '/res/38a347da/rsrc/css/aphront/form-view.css',
|
||||
'uri' => '/res/8ee16aba/rsrc/css/aphront/form-view.css',
|
||||
'type' => 'css',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -161,16 +161,6 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/css/application/differential/core.css',
|
||||
),
|
||||
0 =>
|
||||
array(
|
||||
'uri' => '/res/39de799e/rsrc/js/javelin/docs/Base.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
),
|
||||
'disk' => '/rsrc/js/javelin/docs/Base.js',
|
||||
),
|
||||
'differential-inline-comment-editor' =>
|
||||
array(
|
||||
'uri' => '/res/5e4f0aa4/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
|
||||
|
@ -305,7 +295,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-aphront-basic-tokenizer' =>
|
||||
array(
|
||||
'uri' => '/res/bce3961b/rsrc/js/application/core/behavior-tokenizer.js',
|
||||
'uri' => '/res/5e183bd5/rsrc/js/application/core/behavior-tokenizer.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -314,6 +304,7 @@ celerity_register_resource_map(array(
|
|||
2 => 'javelin-tokenizer',
|
||||
3 => 'javelin-typeahead-preloaded-source',
|
||||
4 => 'javelin-dom',
|
||||
5 => 'javelin-stratcom',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/core/behavior-tokenizer.js',
|
||||
),
|
||||
|
@ -344,7 +335,7 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'javelin-behavior-countdown-timer' =>
|
||||
array(
|
||||
'uri' => '/res/48477cc8/rsrc/js/application/countdown/timer.js',
|
||||
'uri' => '/res/9eef8193/rsrc/js/application/countdown/timer.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
|
@ -535,6 +526,19 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/herald/herald-rule-editor.js',
|
||||
),
|
||||
'javelin-behavior-maniphest-project-create' =>
|
||||
array(
|
||||
'uri' => '/res/85a0eaf9/rsrc/js/application/maniphest/behavior-project-create.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-dom',
|
||||
2 => 'javelin-stratcom',
|
||||
3 => 'javelin-workflow',
|
||||
),
|
||||
'disk' => '/rsrc/js/application/maniphest/behavior-project-create.js',
|
||||
),
|
||||
'javelin-behavior-maniphest-transaction-controls' =>
|
||||
array(
|
||||
'uri' => '/res/94a2a395/rsrc/js/application/maniphest/behavior-transaction-controls.js',
|
||||
|
@ -586,6 +590,16 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
|
||||
),
|
||||
0 =>
|
||||
array(
|
||||
'uri' => '/res/39de799e/rsrc/js/javelin/docs/Base.js',
|
||||
'type' => 'js',
|
||||
'requires' =>
|
||||
array(
|
||||
0 => 'javelin-install',
|
||||
),
|
||||
'disk' => '/rsrc/js/javelin/docs/Base.js',
|
||||
),
|
||||
'javelin-behavior-phabricator-keyboard-shortcuts' =>
|
||||
array(
|
||||
'uri' => '/res/5a23bcc8/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
|
||||
|
@ -1081,6 +1095,30 @@ celerity_register_resource_map(array(
|
|||
), array (
|
||||
'packages' =>
|
||||
array (
|
||||
'01052905' =>
|
||||
array (
|
||||
'name' => 'core.pkg.css',
|
||||
'symbols' =>
|
||||
array (
|
||||
0 => 'phabricator-core-css',
|
||||
1 => 'phabricator-core-buttons-css',
|
||||
2 => 'phabricator-standard-page-view',
|
||||
3 => 'aphront-dialog-view-css',
|
||||
4 => 'aphront-form-view-css',
|
||||
5 => 'aphront-panel-view-css',
|
||||
6 => 'aphront-side-nav-view-css',
|
||||
7 => 'aphront-table-view-css',
|
||||
8 => 'aphront-crumbs-view-css',
|
||||
9 => 'aphront-tokenizer-control-css',
|
||||
10 => 'aphront-typeahead-control-css',
|
||||
11 => 'aphront-list-filter-view-css',
|
||||
12 => 'phabricator-directory-css',
|
||||
13 => 'phabricator-remarkup-css',
|
||||
14 => 'syntax-highlighting-css',
|
||||
),
|
||||
'uri' => '/res/pkg/01052905/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'03ef179e' =>
|
||||
array (
|
||||
'name' => 'diffusion.pkg.css',
|
||||
|
@ -1108,7 +1146,7 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/0e6e36aa/differential.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'33f413ef' =>
|
||||
'2892314d' =>
|
||||
array (
|
||||
'name' => 'typeahead.pkg.js',
|
||||
'symbols' =>
|
||||
|
@ -1121,7 +1159,7 @@ celerity_register_resource_map(array(
|
|||
5 => 'javelin-tokenizer',
|
||||
6 => 'javelin-behavior-aphront-basic-tokenizer',
|
||||
),
|
||||
'uri' => '/res/pkg/33f413ef/typeahead.pkg.js',
|
||||
'uri' => '/res/pkg/2892314d/typeahead.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'c8f4dac5' =>
|
||||
|
@ -1140,30 +1178,6 @@ celerity_register_resource_map(array(
|
|||
'uri' => '/res/pkg/c8f4dac5/workflow.pkg.js',
|
||||
'type' => 'js',
|
||||
),
|
||||
'ca51195b' =>
|
||||
array (
|
||||
'name' => 'core.pkg.css',
|
||||
'symbols' =>
|
||||
array (
|
||||
0 => 'phabricator-core-css',
|
||||
1 => 'phabricator-core-buttons-css',
|
||||
2 => 'phabricator-standard-page-view',
|
||||
3 => 'aphront-dialog-view-css',
|
||||
4 => 'aphront-form-view-css',
|
||||
5 => 'aphront-panel-view-css',
|
||||
6 => 'aphront-side-nav-view-css',
|
||||
7 => 'aphront-table-view-css',
|
||||
8 => 'aphront-crumbs-view-css',
|
||||
9 => 'aphront-tokenizer-control-css',
|
||||
10 => 'aphront-typeahead-control-css',
|
||||
11 => 'aphront-list-filter-view-css',
|
||||
12 => 'phabricator-directory-css',
|
||||
13 => 'phabricator-remarkup-css',
|
||||
14 => 'syntax-highlighting-css',
|
||||
),
|
||||
'uri' => '/res/pkg/ca51195b/core.pkg.css',
|
||||
'type' => 'css',
|
||||
),
|
||||
'da416e1c' =>
|
||||
array (
|
||||
'name' => 'differential.pkg.js',
|
||||
|
@ -1200,15 +1214,15 @@ celerity_register_resource_map(array(
|
|||
),
|
||||
'reverse' =>
|
||||
array (
|
||||
'aphront-crumbs-view-css' => 'ca51195b',
|
||||
'aphront-dialog-view-css' => 'ca51195b',
|
||||
'aphront-form-view-css' => 'ca51195b',
|
||||
'aphront-list-filter-view-css' => 'ca51195b',
|
||||
'aphront-panel-view-css' => 'ca51195b',
|
||||
'aphront-side-nav-view-css' => 'ca51195b',
|
||||
'aphront-table-view-css' => 'ca51195b',
|
||||
'aphront-tokenizer-control-css' => 'ca51195b',
|
||||
'aphront-typeahead-control-css' => 'ca51195b',
|
||||
'aphront-crumbs-view-css' => '01052905',
|
||||
'aphront-dialog-view-css' => '01052905',
|
||||
'aphront-form-view-css' => '01052905',
|
||||
'aphront-list-filter-view-css' => '01052905',
|
||||
'aphront-panel-view-css' => '01052905',
|
||||
'aphront-side-nav-view-css' => '01052905',
|
||||
'aphront-table-view-css' => '01052905',
|
||||
'aphront-tokenizer-control-css' => '01052905',
|
||||
'aphront-typeahead-control-css' => '01052905',
|
||||
'differential-changeset-view-css' => '0e6e36aa',
|
||||
'differential-core-view-css' => '0e6e36aa',
|
||||
'differential-revision-add-comment-css' => '0e6e36aa',
|
||||
|
@ -1219,7 +1233,7 @@ celerity_register_resource_map(array(
|
|||
'differential-table-of-contents-css' => '0e6e36aa',
|
||||
'diffusion-commit-view-css' => '03ef179e',
|
||||
'javelin-behavior' => 'db95a6d0',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '33f413ef',
|
||||
'javelin-behavior-aphront-basic-tokenizer' => '2892314d',
|
||||
'javelin-behavior-aphront-form-disable-on-submit' => 'c8f4dac5',
|
||||
'javelin-behavior-differential-diff-radios' => 'da416e1c',
|
||||
'javelin-behavior-differential-edit-inline-comments' => 'da416e1c',
|
||||
|
@ -1235,23 +1249,23 @@ celerity_register_resource_map(array(
|
|||
'javelin-mask' => 'c8f4dac5',
|
||||
'javelin-request' => 'db95a6d0',
|
||||
'javelin-stratcom' => 'db95a6d0',
|
||||
'javelin-tokenizer' => '33f413ef',
|
||||
'javelin-typeahead' => '33f413ef',
|
||||
'javelin-typeahead-normalizer' => '33f413ef',
|
||||
'javelin-typeahead-ondemand-source' => '33f413ef',
|
||||
'javelin-typeahead-preloaded-source' => '33f413ef',
|
||||
'javelin-typeahead-source' => '33f413ef',
|
||||
'javelin-tokenizer' => '2892314d',
|
||||
'javelin-typeahead' => '2892314d',
|
||||
'javelin-typeahead-normalizer' => '2892314d',
|
||||
'javelin-typeahead-ondemand-source' => '2892314d',
|
||||
'javelin-typeahead-preloaded-source' => '2892314d',
|
||||
'javelin-typeahead-source' => '2892314d',
|
||||
'javelin-uri' => 'db95a6d0',
|
||||
'javelin-util' => 'db95a6d0',
|
||||
'javelin-vector' => 'db95a6d0',
|
||||
'javelin-workflow' => 'c8f4dac5',
|
||||
'phabricator-core-buttons-css' => 'ca51195b',
|
||||
'phabricator-core-css' => 'ca51195b',
|
||||
'phabricator-directory-css' => 'ca51195b',
|
||||
'phabricator-core-buttons-css' => '01052905',
|
||||
'phabricator-core-css' => '01052905',
|
||||
'phabricator-directory-css' => '01052905',
|
||||
'phabricator-keyboard-shortcut' => 'c8f4dac5',
|
||||
'phabricator-keyboard-shortcut-manager' => 'c8f4dac5',
|
||||
'phabricator-remarkup-css' => 'ca51195b',
|
||||
'phabricator-standard-page-view' => 'ca51195b',
|
||||
'syntax-highlighting-css' => 'ca51195b',
|
||||
'phabricator-remarkup-css' => '01052905',
|
||||
'phabricator-standard-page-view' => '01052905',
|
||||
'syntax-highlighting-css' => '01052905',
|
||||
),
|
||||
));
|
||||
|
|
|
@ -30,6 +30,7 @@ phutil_register_library_map(array(
|
|||
'AphrontFormDividerControl' => 'view/form/control/divider',
|
||||
'AphrontFormDragAndDropUploadControl' => 'view/form/control/draganddropupload',
|
||||
'AphrontFormFileControl' => 'view/form/control/file',
|
||||
'AphrontFormLayoutView' => 'view/form/layout',
|
||||
'AphrontFormMarkupControl' => 'view/form/control/markup',
|
||||
'AphrontFormPasswordControl' => 'view/form/control/password',
|
||||
'AphrontFormRecaptchaControl' => 'view/form/control/recaptcha',
|
||||
|
@ -426,6 +427,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectListController' => 'applications/project/controller/list',
|
||||
'PhabricatorProjectProfile' => 'applications/project/storage/profile',
|
||||
'PhabricatorProjectProfileController' => 'applications/project/controller/profile',
|
||||
'PhabricatorProjectQuickCreateController' => 'applications/project/controller/quickcreate',
|
||||
'PhabricatorRedirectController' => 'applications/base/controller/redirect',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'infrastructure/markup/remarkup/markuprule/differential',
|
||||
'PhabricatorRemarkupRuleDiffusion' => 'infrastructure/markup/remarkup/markuprule/diffusion',
|
||||
|
@ -570,6 +572,7 @@ phutil_register_library_map(array(
|
|||
'AphrontFormDividerControl' => 'AphrontFormControl',
|
||||
'AphrontFormDragAndDropUploadControl' => 'AphrontFormControl',
|
||||
'AphrontFormFileControl' => 'AphrontFormControl',
|
||||
'AphrontFormLayoutView' => 'AphrontView',
|
||||
'AphrontFormMarkupControl' => 'AphrontFormControl',
|
||||
'AphrontFormPasswordControl' => 'AphrontFormControl',
|
||||
'AphrontFormRecaptchaControl' => 'AphrontFormControl',
|
||||
|
@ -881,6 +884,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectListController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
|
||||
'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
|
||||
'PhabricatorProjectQuickCreateController' => 'PhabricatorProjectController',
|
||||
'PhabricatorRedirectController' => 'PhabricatorController',
|
||||
'PhabricatorRemarkupRuleDifferential' => 'PhabricatorRemarkupRuleObjectName',
|
||||
'PhabricatorRemarkupRuleDiffusion' => 'PhutilRemarkupRule',
|
||||
|
|
|
@ -200,6 +200,7 @@ class AphrontDefaultApplicationConfiguration
|
|||
'view/(?P<id>\d+)/$' => 'PhabricatorProjectProfileController',
|
||||
'affiliation/(?P<id>\d+)/$'
|
||||
=> 'PhabricatorProjectAffiliationEditController',
|
||||
'quickcreate/$' => 'PhabricatorProjectQuickCreateController',
|
||||
),
|
||||
|
||||
'/r(?P<callsign>[A-Z]+)(?P<commit>[a-z0-9]+)$'
|
||||
|
|
|
@ -210,6 +210,8 @@ class ManiphestTaskEditController extends ManiphestController {
|
|||
$header_name = 'Create New Task';
|
||||
}
|
||||
|
||||
$project_tokenizer_id = celerity_generate_unique_node_id();
|
||||
|
||||
$form = new AphrontFormView();
|
||||
$form
|
||||
->setUser($user)
|
||||
|
@ -245,8 +247,22 @@ class ManiphestTaskEditController extends ManiphestController {
|
|||
->setLabel('Projects')
|
||||
->setName('projects')
|
||||
->setValue($projects_value)
|
||||
->setID($project_tokenizer_id)
|
||||
->setCaption(
|
||||
javelin_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => '/project/quickcreate/',
|
||||
'mustcapture' => true,
|
||||
'sigil' => 'project-create',
|
||||
),
|
||||
'Create New Project'))
|
||||
->setDatasource('/typeahead/common/projects/'));
|
||||
|
||||
Javelin::initBehavior('maniphest-project-create', array(
|
||||
'tokenizerID' => $project_tokenizer_id,
|
||||
));
|
||||
|
||||
if ($files) {
|
||||
$file_display = array();
|
||||
foreach ($files as $file) {
|
||||
|
|
|
@ -18,6 +18,9 @@ phutil_require_module('phabricator', 'applications/maniphest/storage/task');
|
|||
phutil_require_module('phabricator', 'applications/maniphest/storage/transaction');
|
||||
phutil_require_module('phabricator', 'applications/phid/constants');
|
||||
phutil_require_module('phabricator', 'applications/phid/handle/data');
|
||||
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/markup');
|
||||
phutil_require_module('phabricator', 'view/form/control/select');
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
class PhabricatorProjectQuickCreateController
|
||||
extends PhabricatorProjectController {
|
||||
|
||||
|
||||
public function processRequest() {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$project = new PhabricatorProject();
|
||||
$project->setAuthorPHID($user->getPHID());
|
||||
$profile = new PhabricatorProjectProfile();
|
||||
|
||||
$e_name = true;
|
||||
$errors = array();
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
|
||||
$project->setName($request->getStr('name'));
|
||||
$profile->setBlurb($request->getStr('blurb'));
|
||||
|
||||
if (!strlen($project->getName())) {
|
||||
$e_name = 'Required';
|
||||
$errors[] = 'Project name is required.';
|
||||
} else {
|
||||
$e_name = null;
|
||||
}
|
||||
|
||||
if (!$errors) {
|
||||
$project->save();
|
||||
|
||||
$profile->setProjectPHID($project->getPHID());
|
||||
$profile->save();
|
||||
|
||||
return id(new AphrontAjaxResponse())
|
||||
->setContent(array(
|
||||
'phid' => $project->getPHID(),
|
||||
'name' => $project->getName(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
$error_view = null;
|
||||
if ($errors) {
|
||||
$error_view = new AphrontErrorView();
|
||||
$error_view->setTitle('Form Errors');
|
||||
$error_view->setWidth(AphrontErrorView::WIDTH_DIALOG);
|
||||
$error_view->setErrors($errors);
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormLayoutView())
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
->setName('name')
|
||||
->setValue($project->getName())
|
||||
->setError($e_name))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextAreaControl())
|
||||
->setLabel('Blurb')
|
||||
->setName('blurb')
|
||||
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
|
||||
->setValue($profile->getBlurb()));
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setTitle('Create a New Project')
|
||||
->appendChild($error_view)
|
||||
->appendChild($form)
|
||||
->addSubmitButton('Create Project')
|
||||
->addCancelButton('/project/');
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
}
|
23
src/applications/project/controller/quickcreate/__init__.php
Normal file
23
src/applications/project/controller/quickcreate/__init__.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/ajax');
|
||||
phutil_require_module('phabricator', 'aphront/response/dialog');
|
||||
phutil_require_module('phabricator', 'applications/project/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/profile');
|
||||
phutil_require_module('phabricator', 'applications/project/storage/project');
|
||||
phutil_require_module('phabricator', 'view/dialog');
|
||||
phutil_require_module('phabricator', 'view/form/control/text');
|
||||
phutil_require_module('phabricator', 'view/form/control/textarea');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/form/layout');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorProjectQuickCreateController.php');
|
|
@ -29,6 +29,10 @@ class AphrontDialogView extends AphrontView {
|
|||
private $renderAsForm = true;
|
||||
private $formID;
|
||||
|
||||
private $width = 'default';
|
||||
const WIDTH_DEFAULT = 'default';
|
||||
const WIDTH_FORM = 'form';
|
||||
|
||||
public function setUser(PhabricatorUser $user) {
|
||||
$this->user = $user;
|
||||
return $this;
|
||||
|
@ -80,6 +84,11 @@ class AphrontDialogView extends AphrontView {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function setWidth($width) {
|
||||
$this->width = $width;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function render() {
|
||||
require_celerity_resource('aphront-dialog-view-css');
|
||||
|
||||
|
@ -114,6 +123,16 @@ class AphrontDialogView extends AphrontView {
|
|||
|
||||
$more = $this->class;
|
||||
|
||||
switch ($this->width) {
|
||||
case self::WIDTH_FORM:
|
||||
$more .= ' aphront-dialog-view-width-'.$this->width;
|
||||
break;
|
||||
case self::WIDTH_DEFAULT:
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unknown dialog width '{$this->width}'!");
|
||||
}
|
||||
|
||||
$attributes = array(
|
||||
'class' => 'aphront-dialog-view '.$more,
|
||||
'sigil' => 'jx-dialog',
|
||||
|
|
|
@ -67,18 +67,22 @@ final class AphrontFormView extends AphrontView {
|
|||
|
||||
Javelin::initBehavior('aphront-form-disable-on-submit');
|
||||
|
||||
$layout = id(new AphrontFormLayoutView())
|
||||
->setBackgroundShading(true)
|
||||
->setPadded(true)
|
||||
->appendChild($this->renderDataInputs())
|
||||
->appendChild($this->renderChildren());
|
||||
|
||||
return javelin_render_tag(
|
||||
'form',
|
||||
array(
|
||||
'action' => $this->action,
|
||||
'method' => $this->method,
|
||||
'class' => 'aphront-form-view',
|
||||
'enctype' => $this->encType,
|
||||
'sigil' => $this->workflow ? 'workflow' : null,
|
||||
'id' => $this->id,
|
||||
),
|
||||
$this->renderDataInputs().
|
||||
$this->renderChildren());
|
||||
$layout->render());
|
||||
}
|
||||
|
||||
private function renderDataInputs() {
|
||||
|
|
|
@ -10,8 +10,10 @@ phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
|||
phutil_require_module('phabricator', 'infrastructure/javelin/api');
|
||||
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
|
||||
phutil_require_module('phabricator', 'view/base');
|
||||
phutil_require_module('phabricator', 'view/form/layout');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('AphrontFormView.php');
|
||||
|
|
|
@ -24,6 +24,7 @@ final class AphrontErrorView extends AphrontView {
|
|||
|
||||
const WIDTH_DEFAULT = 'default';
|
||||
const WIDTH_WIDE = 'wide';
|
||||
const WIDTH_DIALOG = 'dialog';
|
||||
|
||||
private $title;
|
||||
private $errors;
|
||||
|
|
59
src/view/form/layout/AphrontFormLayoutView.php
Normal file
59
src/view/form/layout/AphrontFormLayoutView.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2011 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This provides the layout of an AphrontFormView without actually providing
|
||||
* the <form /> tag. Useful on its own for creating forms in other forms (like
|
||||
* dialogs) or forms which aren't submittable.
|
||||
*/
|
||||
final class AphrontFormLayoutView extends AphrontView {
|
||||
|
||||
private $backgroundShading;
|
||||
private $padded;
|
||||
|
||||
public function setBackgroundShading($shading) {
|
||||
$this->backgroundShading = $shading;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPadded($padded) {
|
||||
$this->padded = $padded;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$classes = array('aphront-form-view');
|
||||
|
||||
if ($this->backgroundShading) {
|
||||
$classes[] = 'aphront-form-view-shaded';
|
||||
}
|
||||
|
||||
if ($this->padded) {
|
||||
$classes[] = 'aphront-form-view-padded';
|
||||
}
|
||||
|
||||
$classes = implode(' ', $classes);
|
||||
|
||||
return phutil_render_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => $classes,
|
||||
),
|
||||
$this->renderChildren());
|
||||
}
|
||||
}
|
14
src/view/form/layout/__init__.php
Normal file
14
src/view/form/layout/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'view/base');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('AphrontFormLayoutView.php');
|
|
@ -17,6 +17,9 @@
|
|||
color: #ffffff;
|
||||
}
|
||||
|
||||
.aphront-dialog-view-width-form {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.aphront-dialog-body {
|
||||
background: #ffffff;
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
width: 720px;
|
||||
}
|
||||
|
||||
.aphront-error-width-dialog {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.aphront-error-width-wide {
|
||||
width: 95%;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,19 @@
|
|||
* @provides aphront-form-view-css
|
||||
*/
|
||||
|
||||
.aphront-form-view {
|
||||
background: #e7e7e7;
|
||||
/**
|
||||
* These styles are overrides for .aphront-form-view
|
||||
*/
|
||||
.aphront-form-view-shaded {
|
||||
border: 1px solid #c4c4c4;
|
||||
background: #e7e7e7;
|
||||
}
|
||||
|
||||
.aphront-form-view-padded {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
|
||||
.aphront-form-view label.aphront-form-label {
|
||||
padding-top: 4px;
|
||||
width: 19%;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* javelin-tokenizer
|
||||
* javelin-typeahead-preloaded-source
|
||||
* javelin-dom
|
||||
* javelin-stratcom
|
||||
*/
|
||||
|
||||
JX.behavior('aphront-basic-tokenizer', function(config) {
|
||||
|
@ -28,5 +29,7 @@ JX.behavior('aphront-basic-tokenizer', function(config) {
|
|||
tokenizer.setInitialValue(config.value);
|
||||
}
|
||||
|
||||
JX.Stratcom.addData(root, {'tokenizer' : tokenizer});
|
||||
|
||||
tokenizer.start();
|
||||
});
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* @provides javelin-behavior-maniphest-project-create
|
||||
* @requires javelin-behavior
|
||||
* javelin-dom
|
||||
* javelin-stratcom
|
||||
* javelin-workflow
|
||||
*/
|
||||
|
||||
JX.behavior('maniphest-project-create', function(config) {
|
||||
|
||||
JX.Stratcom.listen(
|
||||
'click',
|
||||
'project-create',
|
||||
function(e) {
|
||||
JX.Workflow.newFromLink(e.getTarget())
|
||||
.setHandler(function(r) {
|
||||
var node = JX.$(config.tokenizerID);
|
||||
var tokenizer = JX.Stratcom.getData(node).tokenizer;
|
||||
tokenizer.addToken(r.phid, r.name);
|
||||
})
|
||||
.start();
|
||||
|
||||
e.kill();
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in a new issue