diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 8192900..a7ab028 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1,125 +1,129 @@ 2, 'class' => array( 'SemiStructuredBaseController' => 'applications/semistruct/controller/SemiStructuredBaseController.php', 'SemiStructuredDAO' => 'applications/semistruct/storage/SemiStructuredDAO.php', 'SemiStructuredDataApplication' => 'applications/semistruct/application/SemiStructuredDataApplication.php', 'SemiStructuredInstanceConfiguredCustomField' => 'applications/semistruct/customfield/SemiStructuredConfiguredCustomField.php', 'SemiStructuredInstanceConfiguredCustomFieldStorage' => 'applications/semistruct/storage/SemiStructuredInstanceConfiguredCustomFieldStorage.php', 'SemiStructuredInstanceCustomField' => 'applications/semistruct/customfield/SemiStructuredInstanceCustomField.php', 'SemiStructuredInstanceCustomFieldNumericIndex' => 'applications/semistruct/storage/SemiStructuredInstanceCustomFieldNumericIndex.php', 'SemiStructuredInstanceCustomFieldStringIndex' => 'applications/semistruct/storage/SemiStructuredInstanceCustomFieldStringIndex.php', 'SemiStructuredObjectInstance' => 'applications/semistruct/storage/SemiStructuredObjectInstance.php', 'SemiStructuredObjectInstanceClassTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceClassTransaction.php', 'SemiStructuredObjectInstanceController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceController.php', 'SemiStructuredObjectInstanceDescriptionTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceDescriptionTransaction.php', 'SemiStructuredObjectInstanceEditController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceEditController.php', 'SemiStructuredObjectInstanceEditEngine' => 'applications/semistruct/editor/SemiStructuredObjectInstanceEditEngine.php', 'SemiStructuredObjectInstanceListController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceListController.php', 'SemiStructuredObjectInstanceNameTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceNameTransaction.php', 'SemiStructuredObjectInstancePHIDType' => 'applications/semistruct/phid/SemiStructuredObjectInstancePHIDType.php', 'SemiStructuredObjectInstanceQuery' => 'applications/semistruct/query/SemiStructuredObjectInstanceQuery.php', 'SemiStructuredObjectInstanceRawDataTransaction' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceRawDataTransaction.php', 'SemiStructuredObjectInstanceSearchEngine' => 'applications/semistruct/query/SemiStructuredObjectInstanceSearchEngine.php', 'SemiStructuredObjectInstanceTransaction' => 'applications/semistruct/storage/SemiStructuredObjectInstanceTransaction.php', 'SemiStructuredObjectInstanceTransactionComment' => 'applications/semistruct/storage/SemiStructuredObjectInstanceTransactionComment.php', 'SemiStructuredObjectInstanceTransactionEditor' => 'applications/semistruct/editor/SemiStructuredObjectInstanceTransactionEditor.php', 'SemiStructuredObjectInstanceTransactionQuery' => 'applications/semistruct/query/SemiStructuredObjectInstanceTransactionQuery.php', 'SemiStructuredObjectInstanceTransactionType' => 'applications/semistruct/xaction/instance/SemiStructuredObjectInstanceTransactionType.php', 'SemiStructuredObjectInstanceViewController' => 'applications/semistruct/controller/instance/SemiStructuredObjectInstanceViewController.php', 'SemiStructuredObjectNewInstanceController' => 'applications/semistruct/controller/class/SemiStructuredObjectNewInstanceController.php', 'SemiStructuredObjectType' => 'applications/semistruct/storage/SemiStructuredObjectType.php', + 'SemiStructuredObjectTypeArchiveController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeArchiveController.php', 'SemiStructuredObjectTypeController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeController.php', 'SemiStructuredObjectTypeCustomFieldsTransaction' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeCustomFieldsTransaction.php', 'SemiStructuredObjectTypeDescriptionTransaction' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeDescriptionTransaction.php', 'SemiStructuredObjectTypeEditController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeEditController.php', 'SemiStructuredObjectTypeEditEngine' => 'applications/semistruct/editor/SemiStructuredObjectTypeEditEngine.php', 'SemiStructuredObjectTypeFerretEngine' => 'applications/semistruct/engine/SemiStructuredObjectTypeFerretEngine.php', 'SemiStructuredObjectTypeListController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeListController.php', 'SemiStructuredObjectTypeNameTransaction' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeNameTransaction.php', 'SemiStructuredObjectTypePHIDType' => 'applications/semistruct/phid/SemiStructuredObjectTypePHIDType.php', 'SemiStructuredObjectTypeQuery' => 'applications/semistruct/query/SemiStructuredObjectTypeQuery.php', 'SemiStructuredObjectTypeSearchEngine' => 'applications/semistruct/query/SemiStructuredObjectTypeSearchEngine.php', + 'SemiStructuredObjectTypeStatusTransaction' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeStatusTransaction.php', 'SemiStructuredObjectTypeTransaction' => 'applications/semistruct/storage/SemiStructuredObjectTypeTransaction.php', 'SemiStructuredObjectTypeTransactionComment' => 'applications/semistruct/storage/SemiStructuredObjectTypeTransactionComment.php', 'SemiStructuredObjectTypeTransactionEditor' => 'applications/semistruct/editor/SemiStructuredObjectTypeTransactionEditor.php', 'SemiStructuredObjectTypeTransactionQuery' => 'applications/semistruct/query/SemiStructuredObjectTypeTransactionQuery.php', 'SemiStructuredObjectTypeTransactionType' => 'applications/semistruct/xaction/class/SemiStructuredObjectTypeTransactionType.php', 'SemiStructuredObjectTypeViewController' => 'applications/semistruct/controller/class/SemiStructuredObjectTypeViewController.php', 'SemiStructuredPatchList' => 'applications/semistruct/storage/SemiStructuredPatchList.php', ), 'function' => array(), 'xmap' => array( 'SemiStructuredBaseController' => 'PhabricatorController', 'SemiStructuredDAO' => 'PhabricatorLiskDAO', 'SemiStructuredDataApplication' => 'PhabricatorApplication', 'SemiStructuredInstanceConfiguredCustomField' => array( 'SemiStructuredInstanceCustomField', 'PhabricatorStandardCustomFieldInterface', ), 'SemiStructuredInstanceConfiguredCustomFieldStorage' => 'PhabricatorCustomFieldStorage', 'SemiStructuredInstanceCustomField' => 'PhabricatorCustomField', 'SemiStructuredInstanceCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage', 'SemiStructuredInstanceCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage', 'SemiStructuredObjectInstance' => array( 'SemiStructuredDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFlaggableInterface', 'PhabricatorCustomFieldInterface', 'PhabricatorDestructibleInterface', ), 'SemiStructuredObjectInstanceClassTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstanceController' => 'SemiStructuredBaseController', 'SemiStructuredObjectInstanceDescriptionTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstanceEditController' => 'SemiStructuredBaseController', 'SemiStructuredObjectInstanceEditEngine' => 'PhabricatorEditEngine', 'SemiStructuredObjectInstanceListController' => 'SemiStructuredObjectTypeController', 'SemiStructuredObjectInstanceNameTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstancePHIDType' => 'PhabricatorPHIDType', 'SemiStructuredObjectInstanceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'SemiStructuredObjectInstanceRawDataTransaction' => 'SemiStructuredObjectInstanceTransactionType', 'SemiStructuredObjectInstanceSearchEngine' => 'PhabricatorApplicationSearchEngine', 'SemiStructuredObjectInstanceTransaction' => 'PhabricatorModularTransaction', 'SemiStructuredObjectInstanceTransactionComment' => 'PhabricatorApplicationTransactionComment', 'SemiStructuredObjectInstanceTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'SemiStructuredObjectInstanceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'SemiStructuredObjectInstanceTransactionType' => 'PhabricatorModularTransactionType', 'SemiStructuredObjectInstanceViewController' => 'SemiStructuredObjectInstanceController', 'SemiStructuredObjectNewInstanceController' => 'SemiStructuredObjectTypeController', 'SemiStructuredObjectType' => array( 'SemiStructuredDAO', 'PhabricatorPolicyInterface', 'PhabricatorApplicationTransactionInterface', 'PhabricatorFlaggableInterface', 'PhabricatorDestructibleInterface', 'PhabricatorFerretInterface', ), + 'SemiStructuredObjectTypeArchiveController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeCustomFieldsTransaction' => 'SemiStructuredObjectTypeTransactionType', 'SemiStructuredObjectTypeDescriptionTransaction' => 'SemiStructuredObjectTypeTransactionType', 'SemiStructuredObjectTypeEditController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeEditEngine' => 'PhabricatorEditEngine', 'SemiStructuredObjectTypeFerretEngine' => 'PhabricatorFerretEngine', 'SemiStructuredObjectTypeListController' => 'SemiStructuredBaseController', 'SemiStructuredObjectTypeNameTransaction' => 'SemiStructuredObjectTypeTransactionType', 'SemiStructuredObjectTypePHIDType' => 'PhabricatorPHIDType', 'SemiStructuredObjectTypeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'SemiStructuredObjectTypeSearchEngine' => 'PhabricatorApplicationSearchEngine', + 'SemiStructuredObjectTypeStatusTransaction' => 'SemiStructuredObjectTypeTransactionType', 'SemiStructuredObjectTypeTransaction' => 'PhabricatorModularTransaction', 'SemiStructuredObjectTypeTransactionComment' => 'PhabricatorApplicationTransactionComment', 'SemiStructuredObjectTypeTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 'SemiStructuredObjectTypeTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'SemiStructuredObjectTypeTransactionType' => 'PhabricatorModularTransactionType', 'SemiStructuredObjectTypeViewController' => 'SemiStructuredObjectTypeController', 'SemiStructuredPatchList' => 'PhabricatorSQLPatchList', ), )); diff --git a/src/application/SemiStructuredDataApplication.php b/src/application/SemiStructuredDataApplication.php index 6e349d9..59d0e38 100644 --- a/src/application/SemiStructuredDataApplication.php +++ b/src/application/SemiStructuredDataApplication.php @@ -1,43 +1,44 @@ array( '(?:query/(?P[^/]+)/)?' => 'SemiStructuredObjectTypeListController', $this->getEditRoutePattern('editclass/') => 'SemiStructuredObjectTypeEditController', 'type/(?:(?P\d+)/)?' => array( '' => 'SemiStructuredObjectTypeViewController', 'new/' => 'SemiStructuredObjectNewInstanceController', 'items/' => 'SemiStructuredObjectInstanceListController', + 'archive/' => 'SemiStructuredObjectTypeArchiveController', ), $this->getEditRoutePattern('editinstance/') => 'SemiStructuredObjectInstanceEditController', 'instance/(?:(?P\d+)/)?' => 'SemiStructuredObjectInstanceViewController', ), ); } } diff --git a/src/controller/class/SemiStructuredObjectTypeArchiveController.php b/src/controller/class/SemiStructuredObjectTypeArchiveController.php new file mode 100644 index 0000000..77d4ef7 --- /dev/null +++ b/src/controller/class/SemiStructuredObjectTypeArchiveController.php @@ -0,0 +1,62 @@ +getViewer(); + $id = $request->getURIData('id'); + + $object_type = id(new SemiStructuredObjectTypeQuery()) + ->setViewer($viewer) + ->withIDs(array($id)) + ->executeOne(); + if (!$object_type) { + return new Aphront404Response(); + } + + + $view_uri = $object_type->getURI(); + + if ($request->isFormPost()) { + if ($object_type->isArchived()) { + $new_status = SemiStructuredObjectType::STATUS_ACTIVE; + } else { + $new_status = SemiStructuredObjectType::STATUS_ARCHIVED; + } + + $xactions = array(); + + $xactions[] = id(new SemiStructuredObjectTypeTransaction()) + ->setTransactionType( + SemiStructuredObjectTypeStatusTransaction::TRANSACTIONTYPE) + ->setNewValue($new_status); + + id(new SemiStructuredObjectTypeTransactionEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnNoEffect(true) + ->setContinueOnMissingFields(true) + ->applyTransactions($object_type, $xactions); + + return id(new AphrontRedirectResponse())->setURI($view_uri); + } + + if ($object_type->isArchived()) { + $title = pht('Activate Object Type'); + $body = pht('This Object Type will be usable again.'); + $button = pht('Activate Object Type'); + } else { + $title = pht('Archive Object Type'); + $body = pht('This Object Type will be grayed out and forgotten.'); + $button = pht('Archive Object Type'); + } + + return $this->newDialog() + ->setTitle($title) + ->appendChild($body) + ->addCancelButton($view_uri) + ->addSubmitButton($button); + } + +} diff --git a/src/controller/class/SemiStructuredObjectTypeViewController.php b/src/controller/class/SemiStructuredObjectTypeViewController.php index 3a83db1..105322b 100644 --- a/src/controller/class/SemiStructuredObjectTypeViewController.php +++ b/src/controller/class/SemiStructuredObjectTypeViewController.php @@ -1,174 +1,174 @@ getViewer(); $id = $request->getURIData('id'); $object_type = id(new SemiStructuredObjectTypeQuery()) ->setViewer($viewer) ->withIDs(array($id)) ->executeOne(); if (!$object_type) { return new Aphront404Response(); } $this->setObjectType($object_type); $crumbs = $this->buildApplicationCrumbs(); $title = $object_type->getName(); $header = $this->buildHeaderView(); $curtain = $this->buildCurtain(); $details = $this->buildDetailsView(); $timeline = $this->buildTransactionTimeline( $object_type, new SemiStructuredObjectTypeTransactionQuery()); $comment_view = id(new SemiStructuredObjectTypeEditEngine()) ->setViewer($viewer) ->buildEditEngineCommentView($object_type); $instances_view = $this->buildInstancesView(); $view = id(new PHUITwoColumnView()) ->setHeader($header) ->setCurtain($curtain) ->setMainColumn(array( $instances_view, $timeline, $comment_view, )) ->addPropertySection(pht('Description'), $details); $navigation = $this->buildSideNavView('view'); return $this->newPage() ->setTitle($title) ->setCrumbs($crumbs) ->setPageObjectPHIDs(array($object_type->getPHID())) ->setNavigation($navigation) ->appendChild($view); } private function buildDetailsView() { $viewer = $this->getViewer(); $object_type = $this->getObjectType(); $view = id(new PHUIPropertyListView()) ->setUser($viewer); $description = $object_type->getDescription(); if (strlen($description)) { $view->addTextContent( new PHUIRemarkupView($viewer, $description)); } $custom_fields_def = $object_type->getCustomFieldsConfig(); $custom_fields_def = id(new PhutilJSON()) ->encodeFormatted($custom_fields_def); $view->addProperty( pht('Custom Fields'), phutil_tag('pre', array(), $custom_fields_def)); return $view; } private function buildCurtain() { $viewer = $this->getViewer(); $object_type = $this->getObjectType(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, $object_type, PhabricatorPolicyCapability::CAN_EDIT); $can_create_instance = true; $id = $object_type->getID(); $edit_uri = $this->getApplicationURI("/editclass/{$id}/"); $create_uri = $this->getApplicationURI("/type/{$id}/new/"); - $archive_uri = $this->getApplicationURI("/archive/{$id}/"); + $archive_uri = $this->getApplicationURI("/type/{$id}/archive/"); $curtain = $this->newCurtainView($object_type); $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Object Type')) ->setIcon('fa-pencil') ->setDisabled(!$can_edit) ->setHref($edit_uri)); $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Create New Instance')) ->setIcon('fa-plus') ->setDisabled(!$can_create_instance) ->setHref($create_uri)); if ($object_type->isArchived()) { $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Activate Object Type')) ->setIcon('fa-check') ->setDisabled(!$can_edit) ->setWorkflow($can_edit) ->setHref($archive_uri)); - } else {/* + } else { $curtain->addAction( id(new PhabricatorActionView()) ->setName(pht('Archive Object Type')) ->setIcon('fa-ban') ->setDisabled(!$can_edit) ->setWorkflow($can_edit) - ->setHref($archive_uri)); */ + ->setHref($archive_uri)); } return $curtain; } private function buildInstancesView() { $viewer = $this->getViewer(); $object_type = $this->getObjectType(); $instances = id(new SemiStructuredObjectInstanceQuery()) ->setViewer($viewer) ->setLimit(10) ->withClassPHIDs(array($object_type->getPHID())) ->execute(); $content = id(new SemiStructuredObjectInstanceSearchEngine()) ->setViewer($viewer) ->renderResultsDirectly($instances); // $content is PhabricatorApplicationSearchResultView $box = new PHUIObjectBoxView(); $interface = 'PhabricatorApplicationSearchResultView'; if ($content->getObjectList()) { $box->setObjectList($content->getObjectList()); } if ($content->getTable()) { $box->setTable($content->getTable()); } if ($content->getContent()) { $box->appendChild($content->getContent()); } $box ->setHeader(pht('Instances of this type')); return $box; } } diff --git a/src/query/SemiStructuredObjectTypeSearchEngine.php b/src/query/SemiStructuredObjectTypeSearchEngine.php index 55a2b17..30b4e5e 100644 --- a/src/query/SemiStructuredObjectTypeSearchEngine.php +++ b/src/query/SemiStructuredObjectTypeSearchEngine.php @@ -1,149 +1,149 @@ setKey('statuses') ->setLabel(pht('Status')) ->setOptions(SemiStructuredObjectType::getStatusNameMap()), id(new PhabricatorSearchCheckboxesField()) ->setKey('editable') ->setLabel(pht('Editable')) ->setOptions(array('editable' => null)), ); } protected function getURI($path) { return '/semistruct/'.$path; } protected function getBuiltinQueryNames() { $names = array(); - $names['all'] = pht('All Types'); $names['open'] = pht('Active Types'); + $names['all'] = pht('All Types'); return $names; } public function buildSavedQueryFromBuiltin($query_key) { $query = $this->newSavedQuery(); $query->setQueryKey($query_key); $viewer = $this->requireViewer(); switch ($query_key) { case 'all': return $query; case 'open': return $query->setParameter( 'statuses', array( SemiStructuredObjectType::STATUS_ACTIVE, )); } return parent::buildSavedQueryFromBuiltin($query_key); } protected function buildQueryFromParameters(array $map) { $query = $this->newQuery(); if ($map['statuses']) { $query->withStatuses($map['statuses']); } if ($map['editable'] !== null) { $query->withCanEdit($map['editable']); } return $query; } protected function getRequiredHandlePHIDsForResultList( array $objects, PhabricatorSavedQuery $query) { return array(); } protected function renderResultList( array $items, PhabricatorSavedQuery $query, array $handles) { $viewer = $this->requireViewer(); if ($items) { $edge_query = id(new PhabricatorEdgeQuery()) ->withSourcePHIDs(mpull($items, 'getPHID')) ->withEdgeTypes( array( PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, )); $edge_query->execute(); } $list = id(new PHUIObjectItemListView()) ->setViewer($viewer); foreach ($items as $class) { $item = id(new PHUIObjectItemView()) ->setViewer($viewer) ->setObjectName($class->getObjectName()) ->setHeader($class->getName()) ->setHref($class->getURI()) ->setObject($class); if ($class->isArchived()) { $item->setDisabled(true); $bg_color = 'bg-grey'; } else { $bg_color = 'bg-dark'; } $icon = id(new PHUIIconView()) ->setIcon($class->getIcon()); $item->setImageIcon($icon); $item->setEpoch($class->getDateModified()); $phid = $class->getPHID(); $project_phids = $edge_query->getDestinationPHIDs(array($phid)); $project_handles = $viewer->loadHandles($project_phids); $item->addAttribute( id(new PHUIHandleTagListView()) ->setLimit(4) ->setNoDataString(pht('No Tags')) ->setSlim(true) ->setHandles($project_handles)); $list->addItem($item); } $result = new PhabricatorApplicationSearchResultView(); $result->setObjectList($list); $result->setNoDataString(pht('No object types found.')); return $result; } } diff --git a/src/xaction/class/SemiStructuredObjectTypeStatusTransaction.php b/src/xaction/class/SemiStructuredObjectTypeStatusTransaction.php new file mode 100644 index 0000000..c848625 --- /dev/null +++ b/src/xaction/class/SemiStructuredObjectTypeStatusTransaction.php @@ -0,0 +1,50 @@ +getStatus(); + } + + public function applyInternalEffects($object, $value) { + $object->setStatus($value); + } + + public function getTitle() { + if ($this->getNewValue() == SemiStructuredObjectType::STATUS_ARCHIVED) { + return pht( + '%s disabled this Type.', + $this->renderAuthor()); + } else { + return pht( + '%s enabled this Type.', + $this->renderAuthor()); + } + } + + public function getTitleForFeed() { + if ($this->getNewValue() == SemiStructuredObjectType::STATUS_ARCHIVED) { + return pht( + '%s disabled the Type %s.', + $this->renderAuthor(), + $this->renderObject()); + } else { + return pht( + '%s enabled the Type %s.', + $this->renderAuthor(), + $this->renderObject()); + } + } + + public function getIcon() { + if ($this->getNewValue() == SemiStructuredObjectType::STATUS_ARCHIVED) { + return 'fa-ban'; + } else { + return 'fa-check'; + } + } + +}