Skip to content

Commit

Permalink
[4.x] Allowing adding a blueprint to user groups (#6506)
Browse files Browse the repository at this point in the history
Co-authored-by: Jason Varga <jason@pixelfear.com>
  • Loading branch information
ryanmitchell and jasonvarga committed Jun 22, 2023
1 parent 99e1b49 commit ad11f29
Show file tree
Hide file tree
Showing 14 changed files with 332 additions and 155 deletions.
151 changes: 65 additions & 86 deletions resources/js/components/user-groups/PublishForm.vue
@@ -1,112 +1,87 @@
<template>

<div>
<header class="mb-6">
<breadcrumb :url="breadcrumbUrl" :title="__('User Groups')" />
<div class="flex items-center">
<h1 class="flex-1" v-text="title || __('Create Group')" />
<button type="submit" class="btn-primary" @click="save">{{ __('Save') }}</button>
</div>
</header>

<div class="card p-0 mb-6 publish-fields @container">

<form-group
:display="__('Title')"
handle="title"
:errors="errors.title"
:instructions="__('messages.user_groups_title_instructions')"
v-model="title"
:focus="true"
/>

<form-group
fieldtype="slug"
:display="__('Handle')"
handle="handle"
:instructions="__('messages.user_groups_handle_instructions')"
:errors="errors.title"
v-model="handle"
/>

<div class="text-xs text-red-500 p-6 pt-0" v-if="initialHandle && handle != initialHandle">
{{ __('messages.role_change_handle_warning') }}
</div>

<div class="form-group publish-field w-full" v-if="$permissions.has('assign roles')">
<div class="field-inner">
<label class="publish-field-label" v-text="__('Roles')" />
<div class="help-block -mt-2">
<p>{{ __('messages.user_groups_role_instructions') }}</p>
</div>
</div>
<publish-field-meta
:config="{ handle: 'roles', type: 'user_roles' }"
:initial-value="roles">
<div slot-scope="{ meta, value, loading }">
<relationship-fieldtype
v-if="!loading"
:config="{ handle: 'roles', type: 'user_roles', mode: 'select' }"
:value="value"
:meta="meta"
handle="roles"
@input="roles = $event" />
</div>
</publish-field-meta>
<small class="help-block text-red-500 mt-2 mb-0" v-if="errors.roles" v-text="errors.roles[0]" />
</div>

<div>

<header class="mb-3">
<breadcrumb :url="cp_url('user-groups')" :title="__('User Groups')" />
<div class="flex items-center">
<h1 class="flex-1" v-text="title" />
<dropdown-list class="mr-2" v-if="canEditBlueprint">
<dropdown-item :text="__('Edit Blueprint')" :redirect="actions.editBlueprint" />
</dropdown-list>

<button
class="btn-primary"
@click.prevent="save"
v-text="__('Save')" />

<slot name="action-buttons-right" />
</div>
</header>

<publish-container
v-if="fieldset"
ref="container"
:name="publishContainer"
:blueprint="fieldset"
:values="values"
:reference="initialReference"
:meta="meta"
:errors="errors"
@updated="values = $event"
>
<div slot-scope="{ container, setFieldValue, setFieldMeta }">
<publish-tabs
:enable-sidebar="false"
@updated="setFieldValue"
@meta-updated="setFieldMeta"
@focus="container.$emit('focus', $event)"
@blur="container.$emit('blur', $event)"
></publish-tabs>
</div>
</div>
</publish-container>

</div>
</template>


<script>
import HasHiddenFields from '../publish/HasHiddenFields';
export default {
mixins: [
HasHiddenFields,
],
props: {
publishContainer: String,
initialFieldset: Object,
initialValues: Object,
initialMeta: Object,
initialReference: String,
initialTitle: String,
initialHandle: String,
initialRoles: Array,
initialUsers: Array,
action: String,
actions: Object,
method: String,
creating: Boolean,
breadcrumbUrl: String,
canEditBlueprint: Boolean,
isCreating: Boolean,
},
data() {
return {
fieldset: _.clone(this.initialFieldset),
values: _.clone(this.initialValues),
meta: _.clone(this.initialMeta),
error: null,
errors: {},
title: this.initialTitle,
handle: this.initialHandle,
roles: this.initialRoles,
users: this.initialUsers,
}
},
watch: {
'title': function(display) {
if (this.creating) {
this.handle = this.$slugify(display, '_');
}
}
},
computed: {
hasErrors() {
return this.error || Object.keys(this.errors).length;
},
payload() {
return {
title: this.title,
handle: this.handle,
roles: this.roles,
users: this.users,
}
}
},
Expand All @@ -121,16 +96,20 @@ export default {
save() {
this.clearErrors();
this.$axios[this.method](this.action, this.payload).then(response => {
window.location = response.data.redirect;
this.$axios[this.method](this.actions.save, this.visibleValues).then(response => {
this.title = response.data.title;
this.$refs.container.saved();
if (this.isCreating) window.location = response.data.redirect;
this.$toast.success(__('Saved'));
this.$nextTick(() => this.$emit('saved', response));
}).catch(e => {
if (e.response && e.response.status === 422) {
const { message, errors } = e.response.data;
this.error = message;
this.errors = errors;
this.$toast.error(message);
} else {
this.$toast.error(__('Unable to save user group'));
this.$toast.error(__('Something went wrong'));
}
});
}
Expand Down
10 changes: 9 additions & 1 deletion resources/views/blueprints/index.blade.php
Expand Up @@ -155,7 +155,7 @@
</div>
@endforeach

<h3 class="little-heading pl-0 mb-2">{{ __('Other') }}</h3>
<h3 class="little-heading pl-0 mb-2">{{ __('Users') }}</h3>
<div class="card p-0 mb-4">
<table class="data-table">
<tr>
Expand All @@ -166,6 +166,14 @@
</div>
</td>
</tr>
<tr>
<td>
<div class="flex items-center">
<div class="w-4 h-4 mr-4">@cp_svg('icons/light/user_groups')</div>
<a href="{{ cp_route('user-groups.blueprint.edit') }}">{{ __('Group') }}</a>
</div>
</td>
</tr>
</table>
</div>

Expand Down
21 changes: 21 additions & 0 deletions resources/views/usergroups/blueprints/edit.blade.php
@@ -0,0 +1,21 @@
@extends('statamic::layout')
@section('title', __('Edit Blueprint'))

@section('content')

@include('statamic::partials.breadcrumb', [
'url' => cp_route('user-groups.index'),
'title' => __('User Groups'),
])

<blueprint-builder
action="{{ cp_route('user-groups.blueprint.update') }}"
:initial-blueprint="{{ json_encode($blueprintVueObject) }}"
></blueprint-builder>

@include('statamic::partials.docs-callout', [
'topic' => __('Blueprints'),
'url' => Statamic::docsUrl('blueprints')
])

@endsection
12 changes: 7 additions & 5 deletions resources/views/usergroups/create.blade.php
Expand Up @@ -4,12 +4,14 @@
@section('content')

<user-group-publish-form
action="{{ cp_route('user-groups.store') }}"
breadcrumb-url="{{ cp_route('user-groups.index') }}"
:actions="{{ json_encode($actions) }}"
method="post"
:creating="true"
v-cloak

publish-container="base"
:initial-title="__('Create Group')"
:initial-fieldset="{{ json_encode($blueprint) }}"
:initial-values="{{ json_encode($values) }}"
:initial-meta="{{ json_encode($meta) }}"
:is-creating="true"
></user-group-publish-form>

@endsection
18 changes: 8 additions & 10 deletions resources/views/usergroups/edit.blade.php
Expand Up @@ -3,18 +3,16 @@

@section('content')

<collection-edit-form>
</collection-edit-form>

<user-group-publish-form
action="{{ cp_route('user-groups.update', $group->handle()) }}"
:actions="{{ json_encode($actions) }}"
method="patch"
initial-title="{{ $group->title() }}"
initial-handle="{{ $group->handle() }}"
:initial-roles="{{ json_encode($roles) }}"
:creating="false"
breadcrumb-url="{{ cp_route('user-groups.show', $group->handle()) }}"
v-cloak
publish-container="base"
initial-title="{{ $title }}"
initial-reference="{{ $reference }}"
:initial-fieldset="{{ json_encode($blueprint) }}"
:initial-values="{{ json_encode($values) }}"
:initial-meta="{{ json_encode($meta) }}"
:can-edit-blueprint="{{ Statamic\Support\Str::bool($user->can('configure fields')) }}"
></user-group-publish-form>

@endsection
3 changes: 3 additions & 0 deletions routes/cp.php
Expand Up @@ -89,6 +89,7 @@
use Statamic\Http\Controllers\CP\Users\RolesController;
use Statamic\Http\Controllers\CP\Users\UserActionController;
use Statamic\Http\Controllers\CP\Users\UserBlueprintController;
use Statamic\Http\Controllers\CP\Users\UserGroupBlueprintController;
use Statamic\Http\Controllers\CP\Users\UserGroupsController;
use Statamic\Http\Controllers\CP\Users\UsersController;
use Statamic\Http\Controllers\CP\Users\UserWizardController;
Expand Down Expand Up @@ -268,6 +269,8 @@
Route::resource('users', UsersController::class);
Route::patch('users/{user}/password', [PasswordController::class, 'update'])->name('users.password.update');
Route::get('account', AccountController::class)->name('account');
Route::get('user-groups/blueprint', [UserGroupBlueprintController::class, 'edit'])->name('user-groups.blueprint.edit');
Route::patch('user-groups/blueprint', [UserGroupBlueprintController::class, 'update'])->name('user-groups.blueprint.update');
Route::resource('user-groups', UserGroupsController::class);
Route::resource('roles', RolesController::class);

Expand Down
7 changes: 4 additions & 3 deletions src/Auth/File/UserGroupRepository.php
Expand Up @@ -30,7 +30,8 @@ public function all(): Collection
return $this->groups = $this->raw()->map(function ($data, $handle) {
$group = Facades\UserGroup::make()
->handle($handle)
->title(array_get($data, 'title'));
->title(array_get($data, 'title'))
->data($data);

foreach ($data['roles'] ?? [] as $role) {
if ($role = Facades\Role::find($role)) {
Expand All @@ -46,10 +47,10 @@ public function save(UserGroupContract $group)
{
$groups = $this->raw();

$groups->put($group->handle(), array_filter([
$groups->put($group->handle(), array_filter(array_merge($group->data()->all(), [
'title' => $group->title(),
'roles' => $group->roles()->map->handle()->values()->all(),
]));
])));

if ($group->handle() !== $group->originalHandle()) {
$groups->forget($group->originalHandle());
Expand Down
21 changes: 18 additions & 3 deletions src/Auth/UserGroup.php
Expand Up @@ -7,6 +7,7 @@
use Statamic\Contracts\Auth\Role;
use Statamic\Contracts\Auth\UserGroup as UserGroupContract;
use Statamic\Contracts\Data\Augmentable;
use Statamic\Data\ContainsData;
use Statamic\Data\HasAugmentedData;
use Statamic\Events\UserGroupDeleted;
use Statamic\Events\UserGroupSaved;
Expand All @@ -20,11 +21,12 @@ abstract class UserGroup implements UserGroupContract, Augmentable, ArrayAccess,
protected $originalHandle;
protected $roles;

use HasAugmentedData;
use ContainsData, HasAugmentedData;

public function __construct()
{
$this->roles = collect();
$this->data = collect();
}

public function title(string $title = null)
Expand Down Expand Up @@ -161,6 +163,11 @@ public function editUrl()
return cp_route('user-groups.edit', $this->handle());
}

public function updateUrl()
{
return cp_route('user-groups.update', $this->handle());
}

public function deleteUrl()
{
return cp_route('user-groups.destroy', $this->handle());
Expand All @@ -173,9 +180,17 @@ public static function __callStatic($method, $parameters)

public function augmentedArrayData()
{
return [
return $this->data()->merge([
'title' => $this->title(),
'handle' => $this->handle(),
];
])->all();
}

/**
* @return \Statamic\Fields\Blueprint
*/
public function blueprint()
{
return Facades\UserGroup::blueprint();
}
}

0 comments on commit ad11f29

Please sign in to comment.