diff --git a/src/Forms/GridField/GridFieldConfig_RecordEditor.php b/src/Forms/GridField/GridFieldConfig_RecordEditor.php
index c67d116bb..30fbd0f4b 100644
--- a/src/Forms/GridField/GridFieldConfig_RecordEditor.php
+++ b/src/Forms/GridField/GridFieldConfig_RecordEditor.php
@@ -21,6 +21,7 @@ class GridFieldConfig_RecordEditor extends GridFieldConfig
$this->addComponent($sort = new GridFieldSortableHeader());
$this->addComponent($filter = new GridFieldFilterHeader());
$this->addComponent(new GridFieldDataColumns());
+ $this->addComponent(new GridFieldVersionedState([ 'Name', 'Title' ]));
$this->addComponent(new GridFieldEditButton());
$this->addComponent(new GridFieldDeleteAction());
$this->addComponent(new GridFieldPageCount('toolbar-header-right'));
diff --git a/src/Forms/GridField/GridFieldVersionedState.php b/src/Forms/GridField/GridFieldVersionedState.php
new file mode 100644
index 000000000..d668cf9b5
--- /dev/null
+++ b/src/Forms/GridField/GridFieldVersionedState.php
@@ -0,0 +1,174 @@
+versionedLabelFields = $versionedLabelFields;
+ }
+ }
+
+ /**
+ * Modify the list of columns displayed in the table.
+ *
+ * @see {@link GridFieldDataColumns->getDisplayFields()}
+ * @see {@link GridFieldDataColumns}.
+ *
+ * @param GridField $gridField
+ * @param array $columns List reference of all column names.
+ */
+ public function augmentColumns($gridField, &$columns)
+ {
+ $model = $gridField->getModelClass();
+ $isModelVersioned = $model::has_extension(Versioned::class);
+
+ if (!$isModelVersioned) {
+ return;
+ }
+
+ $matchedVersionedFields = array_intersect(
+ $columns,
+ $this->versionedLabelFields
+ );
+
+ if (count($matchedVersionedFields) > 0) {
+ $this->column = array_values($matchedVersionedFields)[0];
+ } elseif ($columns) {
+ // Use first column
+ $this->column = $columns[0];
+ }
+ }
+
+ /**
+ * Names of all columns which are affected by this component.
+ *
+ * @param GridField $gridField
+ * @return array
+ */
+ public function getColumnsHandled($gridField)
+ {
+ return [$this->column];
+ }
+
+ /**
+ * HTML for the column, content of the
element.
+ *
+ * @param GridField $gridField
+ * @param DataObject $record - Record displayed in this row
+ * @param string $columnName
+ * @return string - HTML for the column. Return NULL to skip.
+ */
+ public function getColumnContent($gridField, $record, $columnName)
+ {
+
+ $flagContent = '';
+ $flags = $this->getStatusFlags($record);
+ foreach ($flags as $class => $data) {
+ if (is_string($data)) {
+ $data = array('text' => $data);
+ }
+ $flagContent .= sprintf(
+ " %s",
+ 'status-' . Convert::raw2xml($class),
+ (isset($data['title'])) ? sprintf(' title="%s"', Convert::raw2xml($data['title'])) : '',
+ Convert::raw2xml($data['text'])
+ );
+ }
+ return $flagContent;
+ }
+
+ /**
+ * Attributes for the element containing the content returned by {@link getColumnContent()}.
+ *
+ * @param GridField $gridField
+ * @param DataObject $record displayed in this row
+ * @param string $columnName
+ * @return array
+ */
+ public function getColumnAttributes($gridField, $record, $columnName)
+ {
+ return [];
+ }
+
+ /**
+ * Additional metadata about the column which can be used by other components,
+ * e.g. to set a title for a search column header.
+ *
+ * @param GridField $gridField
+ * @param string $columnName
+ * @return array - Map of arbitrary metadata identifiers to their values.
+ */
+ public function getColumnMetadata($gridField, $columnName)
+ {
+ return [];
+ }
+
+
+ /**
+ * A flag provides the user with additional data about the current item
+ * status, for example a "removed from draft" status. Each item can have
+ * more than one status flag. Returns a map of a unique key to a
+ * (localized) title for the flag. The unique key can be reused as a CSS
+ * class.
+ *
+ * Example (simple):
+ *
+ * ```php
+ * "deletedonlive" => "Deleted"
+ * ```
+ *
+ * Example (with optional title attribute):
+ *
+ * ```php
+ * "deletedonlive" => array(
+ * 'text' => "Deleted",
+ * 'title' => 'This page has been deleted'
+ * )
+ * ```
+ *
+ * @param DataObject $record - the record to check status for
+ * @return array
+ */
+ protected function getStatusFlags($record)
+ {
+ $flags = array();
+
+ if ($record->isOnLiveOnly()) {
+ $flags['removedfromdraft'] = array(
+ 'text' => _t(__CLASS__.'.ONLIVEONLYSHORT', 'On live only'),
+ 'title' => _t(__CLASS__.'.ONLIVEONLYSHORTHELP', 'Item is published, but has been deleted from draft'),
+ );
+ } elseif ($record->isArchived()) {
+ $flags['archived'] = array(
+ 'text' => _t(__CLASS__.'.ARCHIVEDPAGESHORT', 'Archived'),
+ 'title' => _t(__CLASS__.'.ARCHIVEDPAGEHELP', 'Item is removed from draft and live'),
+ );
+ } elseif ($record->isOnDraftOnly()) {
+ $flags['addedtodraft'] = array(
+ 'text' => _t(__CLASS__.'.ADDEDTODRAFTSHORT', 'Draft'),
+ 'title' => _t(__CLASS__.'.ADDEDTODRAFTHELP', "Item has not been published yet")
+ );
+ } elseif ($record->isModifiedOnDraft()) {
+ $flags['modified'] = array(
+ 'text' => _t(__CLASS__.'.MODIFIEDONDRAFTSHORT', 'Modified'),
+ 'title' => _t(__CLASS__.'.MODIFIEDONDRAFTHELP', 'Item has unpublished changes'),
+ );
+ }
+
+ return $flags;
+ }
+}
diff --git a/tests/behat/features/profile.feature b/tests/behat/features/profile.feature
index 8c21656ec..af1536728 100644
--- a/tests/behat/features/profile.feature
+++ b/tests/behat/features/profile.feature
@@ -18,7 +18,7 @@ Feature: Manage my own settings
Given I go to "admin/myprofile"
Then I should not see "Joe"
Then I should see "Jack"
- And I should see "Johnson"
+ And I should not see "Johnson"
Scenario: I can't reset the password without the original
Given I follow "Change Password"
|