Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
0b63d8b
Change `read_only` toggle in field config to `visibility` select.
jesseleite Apr 29, 2022
767faec
Normalize field visibility in `toPublishArray()`.
jesseleite Apr 29, 2022
10d8b85
Rename this method for clarity versus publish visibility.
jesseleite Apr 29, 2022
eb63c0f
Update English instruction text.
jesseleite Apr 29, 2022
1e38ca6
Use new `visibility` read only state on publish forms.
jesseleite Apr 29, 2022
5b75060
Normalize visibility in field transformer for blueprint edit form, etc.
jesseleite Apr 29, 2022
6d17e5e
Wire up `hidden` visibility state on publish forms.
jesseleite Apr 29, 2022
c084503
Clean up fallback logic for old `read_only` boolean config.
jesseleite Apr 29, 2022
29db265
Update the other references to old `read_only` field config.
jesseleite Apr 29, 2022
6e825c7
Remove old translation instructions for other languages.
jesseleite Apr 29, 2022
8eb2bd7
Pass tests again.
jesseleite Apr 29, 2022
4e480cb
Move this logic into our `showField()` handler.
jesseleite Apr 29, 2022
bd7c7d2
Be super clear in VueX state that nothing is getting omitted unless e…
jesseleite Apr 29, 2022
81a6f39
Deprecate old `read_only` field config for addon fieldtypes.
jesseleite Apr 29, 2022
068c672
Pass tests again.
jesseleite Apr 29, 2022
cced197
Add hidden state to width selector.
jesseleite Apr 29, 2022
9260eea
Merge branch '3.3' of https://github.com/statamic/cms into feature/co…
jesseleite Jun 6, 2022
85edf49
Revert `nextTick` from #6021; Everything seems to work now without it?
jesseleite Jun 7, 2022
0897273
Re-implement changes since merge conflict.
jesseleite Jun 7, 2022
dd6e88c
Re-implement styles since merge conflict.
jesseleite Jun 7, 2022
d01892f
Bring back `nextTick` to ensure revealers are properly loaded before …
jesseleite Jun 7, 2022
29e9334
Merge branch '3.3' into feature/configurable-field-visibility
jasonvarga Jun 29, 2022
a53b912
Move hidden logic out of width selector
jasonvarga Jun 29, 2022
309653e
change back to lets to lessen the diff
jasonvarga Jun 29, 2022
a426719
Alias and deprecate `Field@isVisible()`.
jesseleite Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion resources/js/components/blueprints/RegularField.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,12 @@
<svg-icon name="hyperlink" v-if="isReferenceField" class="text-grey-60 text-3xs ml-1 h-4 w-4" v-tooltip="__('Imported from fieldset') + ': ' + field.field_reference" />
</div>
<div class="flex-none pr-1 flex">
<width-selector v-model="width" class="mr-1" />
<width-selector v-if="!isHidden" v-model="width" class="mr-1" />

<div v-else class="relative border border-grey-40 opacity-50 w-12 flex items-center justify-center mr-1">
<svg-icon name="hidden" class="h-4 w-4 opacity-50"></svg-icon>
</div>

<button v-if="canDefineLocalizable"
class="hover:text-grey-100 mr-1 flex items-center"
:class="{ 'text-grey-100': localizable, 'text-grey-60': !localizable }"
Expand DownExpand Up@@ -101,6 +106,10 @@ export default {
}
},

isHidden() {
return this.fieldConfig.visibility === 'hidden';
},

widthClass() {
if (! this.isSectionExpanded) return 'blueprint-section-field-w-full';

Expand Down
20 changes: 13 additions & 7 deletions resources/js/components/field-conditions/ValidatorMixin.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,25 +11,31 @@ export default {
methods: {
showField(field, dottedKey) {
let dottedFieldPath = dottedKey || field.handle;
let dottedPrefix = dottedKey? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';
let dottedPrefix = dottedKey ? dottedKey.replace(new RegExp('\.'+field.handle+'$'), '') : '';

// If we know the field is to permanently hidden, bypass validation.
if (field.visibility === 'hidden' || this.shouldForceHiddenField(dottedFieldPath)) {
this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: 'force',
omitValue: false,
});

if (this.shouldForceHiddenField(dottedFieldPath)) {
return false;
}

// Use validation to determine whether field should be shown.
let validator = new Validator(field, this.values, this.$store, this.storeName);
let passes = validator.passesConditions();

// TODO: The next tick here is necessary to fix #6018, but not sure it's the _right_ fix.
// Something is loading differently, causing the below `hiddenByRevealerField` check
// to fail, when the replicator is configured to collapse all sets by default 🤔
// Ensure DOM is updated to ensure all revealers are properly loaded and tracked before committing to store.
this.$nextTick(() => {
let hiddenByRevealerField = validator.hasRevealerCondition(dottedPrefix);
let hasRevealerCondition = validator.hasRevealerCondition(dottedPrefix);

this.$store.commit(`publish/${this.storeName}/setHiddenField`, {
dottedKey: dottedFieldPath,
hidden: ! passes,
omitValue: ! hiddenByRevealerField,
omitValue: (! passes) && (! hasRevealerCondition),
});
});

Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/Fieldtype.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,7 +49,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.config.read_only || false;
return this.readOnly || this.config.visibility === 'read_only' || false;
},

replicatorPreview() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/fieldtypes/replicator/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -112,7 +112,7 @@ export default {
},

isReadOnly() {
return this.readOnly || this.field.read_only || false;
return this.readOnly || this.field.visibility === 'read_only' || false;
},

classes() {
Expand Down
2 changes: 1 addition & 1 deletion resources/js/components/publish/Field.vue
Original file line numberDiff line numberDiff line change
Expand Up@@ -139,7 +139,7 @@ export default {
isReadOnly() {
if (this.storeState.isRoot === false && !this.config.localizable) return true;

return this.isLocked || this.readOnly || this.config.read_only || false;
return this.isLocked || this.readOnly || this.config.visibility === 'read_only' || false;
},

isLocalizable() {
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/de_CH/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wird unter der Bezeichnung des Feldes angezeigt, genau wie dieser Text hier. Markdown wird unterstützt.',
'fields_instructions_position_instructions' => 'Beschreibung über oder unter dem Feld anzeigen.',
'fields_listable_instructions' => 'Steuert die Darstellung in der Listenansicht.',
'fields_read_only_instructions' => 'Die Bearbeitungsmöglichkeit im Control Panel deaktivieren.',
'fieldset_import_fieldset_instructions' => 'Das zu importierende Fieldset.',
'fieldset_import_prefix_instructions' => 'Ein Präfix, welches jedem Feld beim Import vorangestellt werden soll (z.B. hero_)',
'fieldset_intro' => 'Fieldsets sind optionale Ergänzungen zu Blueprints und dienen als wiederverwendbare Partials, die in Blueprints verwendet werden können.',
Expand Down
2 changes: 1 addition & 1 deletion resources/lang/en/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,7 @@
'fields_instructions_instructions' => 'Shown under the field\'s display label, like this very text. Markdown is supported.',
'fields_instructions_position_instructions' => 'Show instructions above or below the field.',
'fields_listable_instructions' => 'Control the listing column visibility.',
'fields_read_only_instructions' => 'Disable editing in the control panel.',
'fields_visibility_instructions' => 'Control field visibility on publish forms.',
'fieldset_import_fieldset_instructions' => 'The fieldset to be imported.',
'fieldset_import_prefix_instructions' => 'The prefix that should be applied to each field when they are imported. eg. hero_',
'fieldset_intro' => 'Fieldsets are an optional companion to blueprints, acting as reusable partials that can be used within blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/fr/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Texte affiché sous l’étiquette du champ (comme celui-ci). Markdown est pris en compte.',
'fields_instructions_position_instructions' => 'Défini le positionnement des instructions par rapport au champ.',
'fields_listable_instructions' => 'Contrôle la visibilité de ce champ dans les colonnes.',
'fields_read_only_instructions' => 'Désactivez la possibilité de modifier dans le panneau de contrôle.',
'fieldset_import_fieldset_instructions' => 'Le jeu de champs à importer.',
'fieldset_import_prefix_instructions' => 'Le préfixe à appliquer à chaque champ lors de leur importation. Ex. hero_',
'fieldset_intro' => 'Les jeux de champs sont des compagnons optionnels des Blueprints qui vous permettent de créer des partiels réutilisables dans tous vos Blueprints.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nb/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Vises under feltets visningsetikett, slik som denne teksten. Markdown støttes.',
'fields_instructions_position_instructions' => 'Vis instruksjoner over eller under feltet.',
'fields_listable_instructions' => 'Styrer om feltet skjules eller vises i lister.',
'fields_read_only_instructions' => 'Deaktiver redigering i kontrollpanelet.',
'fieldset_import_fieldset_instructions' => 'Feltsettet som skal importeres.',
'fieldset_import_prefix_instructions' => 'Prefikset som skal brukes på hvert felt når de importeres, for eksempel helt_',
'fieldset_intro' => 'Feltsett er en valgfri ledsager til blueprint og fungerer som gjenbrukbare delreplikaer som kan brukes i blueprint.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/nl/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Wordt getoond onder het velds weergavelabel, net zoals deze tekst. Markdown is toegestaan.',
'fields_instructions_position_instructions' => 'Waar de instructie gepositioneerd moet worden ten opzichte van het veld.',
'fields_listable_instructions' => 'Bepaal of dit veld getoond moet worden als kolom in overzichtstabellen.',
'fields_read_only_instructions' => 'Schakel uit dat je het veld kunt wijzigen in het controle paneel.',
'fieldset_import_fieldset_instructions' => 'De fieldset die geïmporteerd moet worden.',
'fieldset_import_prefix_instructions' => 'Het voorvoegsel dat op ieder veld toegepast moet worden als ze worden geïmporteerd. Bijv: hero_',
'fieldset_intro' => 'Fieldsets zijn een optionele toevoeging aan blueprints, het zijn herbruikbare partials die in blueprints gebruikt kunnen worden.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/ru/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => 'Показывается под отображаемой меткой поля, как этот самый текст. Поддерживается Markdown.',
'fields_instructions_position_instructions' => 'Где должны располагаться инструкции относительно поля.',
'fields_listable_instructions' => 'Управление видимостью столбца этого поля.',
'fields_read_only_instructions' => 'Отключить редактирование в панели управления.',
'fieldset_import_fieldset_instructions' => 'Набор полей, который необходимо импортировать.',
'fieldset_import_prefix_instructions' => 'Префикс, который должен быть применен к каждому полю при импорте. Например, `hero_`',
'fieldset_intro' => 'Наборы полей являются дополнением к чертежам, действуя как многократно используемые частицы.',
Expand Down
1 change: 0 additions & 1 deletion resources/lang/zh_CN/messages.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -71,7 +71,6 @@
'fields_instructions_instructions' => '显示在字段的显示标签下,就像文本一样。支持Markdown。',
'fields_instructions_position_instructions' => '在字段上方或下方显示指示。',
'fields_listable_instructions' => '控制此字段列的可见性。',
'fields_read_only_instructions' => '禁用控制面板中的编辑。',
'fieldset_import_fieldset_instructions' => '要导入的字段集。',
'fieldset_import_prefix_instructions' => '导入每个字段时应应用的前缀。例如。hero_',
'fieldset_intro' => '字段集是蓝图的可选伴侣,允许您创建要在蓝图中使用的部分。',
Expand Down
2 changes: 1 addition & 1 deletion resources/sass/components/blueprints.scss
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,8 +89,8 @@
}

.field-width-selector {
@apply w-12;
display: flex;
width: 49px;
height: 20px;
position: relative;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/Blueprint.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,8 +340,8 @@ public function columns()
->fieldtype($field->fieldtype()->indexComponent())
->label(__($field->display()))
->listable($field->isListable())
->defaultVisibility($field->isVisible())
->visible($field->isVisible())
->defaultVisibility($field->isVisibleOnListing())
->visible($field->isVisibleOnListing())
->sortable($field->isSortable())
->defaultOrder($index + 1);
})
Expand Down
25 changes: 24 additions & 1 deletion src/Fields/Field.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -88,6 +88,19 @@ public function instructions()
return array_get($this->config, 'instructions');
}

public function visibility()
{
$visibility = Arr::get($this->config, 'visibility');

$legacyReadOnly = Arr::get($this->config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
return 'read_only';
}

return $visibility ?? 'visible';
}

public function rules()
{
$rules = [$this->handle => $this->addNullableRule(array_merge(
Expand DownExpand Up@@ -172,7 +185,7 @@ public function isListable()
return (bool) $this->get('listable');
}

public function isVisible()
public function isVisibleOnListing()
Comment thread
jesseleite marked this conversation as resolved.
{
if (is_null($this->get('listable'))) {
return in_array($this->handle, ['title', 'slug', 'date', 'author']);
Expand All@@ -181,6 +194,14 @@ public function isVisible()
return ! in_array($this->get('listable'), [false, 'hidden'], true);
}

/**
* @deprecated Use isVisibleOnListing() instead.
*/
public function isVisible()
{
return $this->isVisibleOnListing();
}

public function isSortable()
{
if (is_null($this->get('sortable'))) {
Expand DownExpand Up@@ -208,6 +229,8 @@ public function toPublishArray()
'display' => $this->display(),
'instructions' => $this->instructions(),
'required' => $this->isRequired(),
'visibility' => $this->visibility(),
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
]);
}

Expand Down
14 changes: 14 additions & 0 deletions src/Fields/FieldTransformer.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -92,6 +92,7 @@ private static function inlineFieldToVue($field): array
$config['width'] = $config['width'] ?? 100;
$config['localizable'] = $config['localizable'] ?? false;
$config = static::normalizeRequiredValidation($config);
$config = static::normalizeVisibility($config);

return [
'handle' => $field['handle'],
Expand DownExpand Up@@ -158,4 +159,17 @@ protected static function normalizeRequiredValidation($config)

return $config;
}

protected static function normalizeVisibility($config)
{
$visibility = Arr::get($config, 'visibility');

$legacyReadOnly = Arr::pull($config, 'read_only');

if ($legacyReadOnly && ! $visibility) {
$config['visibility'] = 'read_only';
}

return $config;
}
}
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Collections/EntriesController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -85,7 +85,7 @@ public function edit(Request $request, $collection, $entry)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

[$values, $meta] = $this->extractFromFields($entry, $blueprint);
Expand DownExpand Up@@ -248,7 +248,7 @@ public function create(Request $request, $collection, $site)
}

if (User::current()->cant('edit-other-authors-entries', [EntryContract::class, $collection, $blueprint])) {
$blueprint->ensureFieldHasConfig('author', ['read_only' => true]);
$blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only']);
}

$values = [];
Expand Down
15 changes: 10 additions & 5 deletions src/Http/Controllers/CP/Fields/FieldsController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -128,11 +128,16 @@ protected function blueprint($blueprint)
'type' => 'section',
],
],
'read_only' => [
'display' => __('Read Only'),
'instructions' => __('statamic::messages.fields_read_only_instructions'),
'type' => 'toggle',
'validate' => 'boolean',
'visibility' => [
'display' => __('Visibility'),
'instructions' => __('statamic::messages.fields_visibility_instructions'),
'options' => [
'visible' => __('Visible'),
'read_only' => __('Read Only'),
'hidden' => __('Hidden'),
],
'default' => 'visible',
'type' => 'select',
'width' => 33,
],
]);
Expand Down
4 changes: 2 additions & 2 deletions src/Http/Controllers/CP/Users/UsersController.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,11 +172,11 @@ public function edit(Request $request, $user)
$blueprint = $user->blueprint();

if (! User::current()->can('edit roles')) {
$blueprint->ensureField('roles', ['read_only' => true]);
$blueprint->ensureField('roles', ['visibility' => 'read_only']);
}

if (! User::current()->can('edit user groups')) {
$blueprint->ensureField('groups', ['read_only' => true]);
$blueprint->ensureField('groups', ['visibility' => 'read_only']);
}

$fields = $blueprint
Expand Down
12 changes: 10 additions & 2 deletions tests/Fields/BlueprintTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'append' => null,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand All@@ -380,6 +382,8 @@ public function converts_to_array_suitable_for_rendering_fields_in_publish_compo
'component' => 'textarea',
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -454,6 +458,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
[
'handle' => 'nested_deeper_two',
Expand All@@ -470,6 +476,8 @@ public function converts_to_array_suitable_for_rendering_prefixed_conditional_fi
'required' => false,
'antlers' => false,
'default' => null,
'visibility' => 'visible',
'read_only' => false, // deprecated
],
],
],
Expand DownExpand Up@@ -563,15 +571,15 @@ public function it_ensures_a_field_has_config()
],
]]);

$fields = $blueprint->ensureFieldHasConfig('author', ['read_only' => true])->fields();
$fields = $blueprint->ensureFieldHasConfig('author', ['visibility' => 'read_only'])->fields();

$this->assertEquals(['type' => 'text'], $fields->get('title')->config());
$this->assertEquals(['type' => 'text'], $fields->get('content')->config());

$expectedConfig = [
'type' => 'text',
'do_not_touch_other_config' => true,
'read_only' => true,
'visibility' => 'read_only',
];

$this->assertEquals($expectedConfig, $fields->get('author')->config());
Expand Down
2 changes: 2 additions & 0 deletions tests/Fields/FieldTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -324,6 +324,8 @@ public function preProcess($data)
'instructions' => 'Test instructions',
'required' => true,
'validate' => 'required',
'visibility' => 'visible',
'read_only' => false, // deprecated
'component' => 'example',
'a_config_field_with_pre_processing' => 'foo preprocessed',
'a_config_field_without_pre_processing' => 'foo',
Expand Down
Loading