diff --git a/lang/en/groups.php b/lang/en/groups.php
index 8bb447603..3348c93bd 100644
--- a/lang/en/groups.php
+++ b/lang/en/groups.php
@@ -89,6 +89,7 @@
'events' => 'event|events',
'no_volunteers' => 'There are no volunteers in this group',
'remove_volunteer' => 'Remove Volunteer',
+ 'remove_host_role' => 'Remove Host role',
'make_host' => 'Make Host',
'not_counting' => 'Not counting toward this group\'s environmental impact is|Not counting toward this group\'s environmental impact are',
'calendar_copy_title' => 'Access all group events in your personal calendar',
diff --git a/lang/fr-BE/groups.php b/lang/fr-BE/groups.php
index 732540ad4..37540c624 100644
--- a/lang/fr-BE/groups.php
+++ b/lang/fr-BE/groups.php
@@ -88,6 +88,7 @@
'events' => 'évenement|évenements',
'group_facts' => 'Réalisations du Repair Café',
'make_host' => 'Nommer organisateur',
+ 'remove_host_role' => 'Retirer rôle d\'organisateur',
'not_counting' => 'L\'impact environnemental de ce Repair Café n\'est pas pris en compte',
'no_volunteers' => 'Il n\'y a pas de bénévoles dans ce repair café',
'read_less' => ' LIRE MOINS',
diff --git a/lang/fr/groups.php b/lang/fr/groups.php
index e2ab0af84..14d7f391b 100644
--- a/lang/fr/groups.php
+++ b/lang/fr/groups.php
@@ -88,6 +88,7 @@
'events' => 'évenement|évenements',
'group_facts' => 'Réalisations du Repair Café',
'make_host' => 'Nommer organisateur',
+ 'remove_host_role' => 'Retirer rôle d\'organisateur',
'not_counting' => 'L\'impact environnemental de ce Repair Café n\'est pas pris en compte',
'no_volunteers' => 'Il n\'y a pas de bénévoles dans ce repair café',
'read_less' => ' LIRE MOINS',
diff --git a/resources/js/components/GroupPage.vue b/resources/js/components/GroupPage.vue
index 1202ac867..594651a39 100644
--- a/resources/js/components/GroupPage.vue
+++ b/resources/js/components/GroupPage.vue
@@ -92,6 +92,11 @@ export default {
required: false,
default: false
},
+ candemote: {
+ type: Boolean,
+ required: false,
+ default: false
+ },
canSeeDelete: {
type: Boolean,
required: false,
@@ -164,6 +169,7 @@ export default {
// computed properties once we have good access to the session on the client.
this.initialGroup.idgroups = this.idgroups
this.initialGroup.canedit = this.canedit
+ this.initialGroup.candemote = this.candemote
this.initialGroup.ingroup = this.ingroup
this.$store.dispatch('groups/set', this.initialGroup)
diff --git a/resources/js/components/GroupVolunteer.vue b/resources/js/components/GroupVolunteer.vue
index 2633366fd..2fb4cfa1d 100644
--- a/resources/js/components/GroupVolunteer.vue
+++ b/resources/js/components/GroupVolunteer.vue
@@ -38,6 +38,7 @@
+ {{ __('groups.remove_host_role') }}
{{ __('groups.make_host') }}
{{ __('groups.remove_volunteer') }}
@@ -67,6 +68,11 @@ export default {
required: false,
default: false
},
+ candemote: {
+ type: Boolean,
+ required: false,
+ default: false
+ },
},
data () {
return {
@@ -140,6 +146,13 @@ export default {
this.error = e.message
}
},
+ async removeHostRole() {
+ try {
+ await this.$store.dispatch('volunteers/removehost', this.volunteer.id)
+ } catch (e) {
+ this.error = e.message
+ }
+ },
confirm() {
this.$refs.confirm.show()
}
diff --git a/resources/js/components/GroupVolunteers.vue b/resources/js/components/GroupVolunteers.vue
index 2c5d5b31c..5bd9affc0 100644
--- a/resources/js/components/GroupVolunteers.vue
+++ b/resources/js/components/GroupVolunteers.vue
@@ -12,7 +12,7 @@
-
+
diff --git a/resources/js/mixins/group.js b/resources/js/mixins/group.js
index 70b913cae..661c5fd15 100644
--- a/resources/js/mixins/group.js
+++ b/resources/js/mixins/group.js
@@ -11,6 +11,9 @@ export default {
canedit() {
return this.group ? this.group.canedit : false
},
+ candemote() {
+ return this.group ? this.group.candemote : false
+ },
ingroup() {
return this.group ? this.group.ingroup : false
}
diff --git a/resources/js/store/volunteers.js b/resources/js/store/volunteers.js
index e11cb653b..049aad9db 100644
--- a/resources/js/store/volunteers.js
+++ b/resources/js/store/volunteers.js
@@ -34,6 +34,9 @@ export default {
},
makeHost(state, id) {
state.listGroup[id].host = true
+ },
+ removeHost(state, id) {
+ state.listGroup[id].host = false
}
},
actions: {
@@ -58,6 +61,13 @@ export default {
host: true
})
commit('makeHost', id)
+ },
+ async removehost({commit, dispatch}, id) {
+ const vol = this.state.volunteers.listGroup[id]
+ const ret = await axios.patch('/api/v2/groups/' + vol.group + '/volunteers/' + vol.user, {
+ host: false
+ })
+ commit('removeHost', id)
}
},
}
\ No newline at end of file
diff --git a/resources/views/group/view.blade.php b/resources/views/group/view.blade.php
index 8e561640b..06ba74af7 100644
--- a/resources/views/group/view.blade.php
+++ b/resources/views/group/view.blade.php
@@ -43,6 +43,7 @@
}
$can_edit_group = App\Helpers\Fixometer::hasRole($user, 'Administrator') || $isCoordinatorForGroup || $is_host_of_group;
+ $can_demote = App\Helpers\Fixometer::hasRole($user, 'Administrator') || $isCoordinatorForGroup;
$can_see_delete = App\Helpers\Fixometer::hasRole($user, 'Administrator');
$can_perform_delete = $can_see_delete && $group->canDelete();
@@ -148,6 +149,7 @@
:top-devices="{{ json_encode($top, JSON_INVALID_UTF8_IGNORE) }}"
:events="{{ json_encode($expanded_events, JSON_INVALID_UTF8_IGNORE) }}"
:canedit="{{ $can_edit_group ? 'true' : 'false' }}"
+ :candemote="{{ $can_demote ? 'true' : 'false' }}"
:can-see-delete="{{ $can_see_delete ? 'true' : 'false' }}"
:can-perform-delete="{{ $can_perform_delete ? 'true' : 'false' }}"
calendar-copy-url="{{ $showCalendar ? url("/calendar/group/{$group->idgroups}") : '' }}"
diff --git a/tests/Feature/Groups/GroupHostTest.php b/tests/Feature/Groups/GroupHostTest.php
index c288521f1..0b09d471b 100644
--- a/tests/Feature/Groups/GroupHostTest.php
+++ b/tests/Feature/Groups/GroupHostTest.php
@@ -114,4 +114,35 @@ public function testHostMakeHost()
$this->expectException(AuthenticationException::class);
$response = $this->delete("/api/v2/groups/{$this->idgroups}/volunteers/{$host->id}?api_token=" . $host->api_token);
}
+
+ public function providerTrueFalse()
+ {
+ return [
+ [false],
+ [true],
+ ];
+ }
+
+ /**
+ * @dataProvider providerTrueFalse
+ */
+ public function testNetworkCoordinatorDemoteHost($addToNetwork) {
+ $host = User::factory()->host()->create();
+ $this->group->addVolunteer($host);
+ $this->group->makeMemberAHost($host);
+
+ $coordinator = User::factory()->networkCoordinator()->create();
+
+ if ($addToNetwork) {
+ $this->network->addCoordinator($coordinator);
+ } else {
+ $this->expectException(AuthenticationException::class);
+ }
+
+ $response = $this->patch("/api/v2/groups/{$this->idgroups}/volunteers/{$host->id}?api_token=".$coordinator->api_token, [
+ 'host' => true,
+ ]);
+
+ $response->assertSuccessful();
+ }
}