Skip to content

Commit

Permalink
New abilities subpage
Browse files Browse the repository at this point in the history
  • Loading branch information
ilestis committed May 24, 2024
1 parent ba16cee commit 8d87443
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 246 deletions.
2 changes: 1 addition & 1 deletion app/Http/Controllers/Entity/Abilities/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public function index(Campaign $campaign, Entity $entity)
'data' => $this->service
->campaign($campaign)
->entity($entity)
->abilities()
->get()
]);
}
}
112 changes: 73 additions & 39 deletions app/Services/Abilities/AbilityService.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
use App\Models\Attribute;
use App\Models\Entity;
use App\Models\EntityAbility;
use App\Models\Tag;
use App\Traits\CampaignAware;
use App\Traits\EntityAware;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;

class AbilityService extends BaseAbilityService
{
Expand All @@ -17,25 +20,27 @@ class AbilityService extends BaseAbilityService

/** @var array All the abilities of this entity, nicely prepared */
protected array $abilities = [
'parents' => [],
'abilities' => [],
'meta' => []
'groups' => [],
'meta' => [],
];

/** @var array A list of abilities that have already been loaded */
protected array $abilityIds = [];

protected array $groups = [];

/**
* Build a list of entities grouped by their parent
*/
public function abilities(): array
public function get(): array
{
$abilities = $this->entity->abilities()
->select('entity_abilities.*')
->with(['ability',
// entity
'ability.entity', 'ability.entity.image', 'ability.entity.attributes',
'ability.entity', 'ability.entity.image', 'ability.entity.attributes', 'ability.entity.attributes.entity',
// parent
'ability.ability', 'ability.ability.entity', 'ability.ability.entity.tags', 'ability.ability.entity.image'
'ability.ability', 'ability.ability.entity', 'ability.ability.entity.tags', 'ability.ability.entity.image',
])
->join('abilities as a', 'a.id', 'entity_abilities.ability_id')
->defaultOrder()
Expand All @@ -51,7 +56,8 @@ public function abilities(): array
}

// Reorder parents
usort($this->abilities['parents'], function ($a, $b) {
$this->abilities['groups'] = $this->groups;
usort($this->abilities['groups'], function ($a, $b) {
return strcmp(mb_strtoupper($a['name']), mb_strtoupper($b['name']));
});

Expand All @@ -73,41 +79,42 @@ protected function add(EntityAbility $entityAbility): void
$ability = $entityAbility->ability;
$parent = $ability->ability;

if (empty($parent)) {
if (in_array($ability->id, $this->abilityIds)) {
return;
$groupKey = $parent->id ?? 'unorganised';

if (empty($this->groups[$groupKey])) {
if (empty($parent)) {
$this->groups[$groupKey] = [
'id' => 0,
'name' => __('entities/abilities.groups.unorganised'),
'type' => __('entities/abilities.types.unorganised'),
'abilities' => [],
];
} else {
$type = empty($parent->type) ? Str::limit(strip_tags($parent->entry), 200) : $parent->type;
$this->groups[$groupKey] = [
'id' => $parent->id,
'name' => $parent->name,
'type' => $type,
'image' => Avatar::entity($parent->entity)->size(192)->thumbnail(),
'has_image' => $parent->entity->hasImage(),
'entry' => $parent->parsedEntry(),
'url' => $parent->getLink(),
'abilities' => [],
];
}
// Abilities need to be added to the array in the order they get loaded, but we also want to avoid abilities
// appearing multiple times somehow.
$this->abilities['abilities'][] = $this->format($entityAbility);
$this->abilityIds[] = $ability->id;
return;
}

if (!isset($this->abilities['parents'][$parent->id])) {
$this->abilities['parents'][$parent->id] = [
'id' => $parent->id,
'name' => $parent->name,
'type' => $parent->type,
'image' => Avatar::entity($parent->entity)->size(192)->thumbnail(),
'has_image' => !empty($parent->entity->image_path) || !empty($parent->entity->image),
'entry' => $parent->parsedEntry(),
'parent' => true,
'abilities' => [],
'url' => $parent->getLink(),
];
}

// Add to their parent's abilities
$this->abilities['parents'][$parent->id]['abilities'][] = $this->format($entityAbility);
$this->groups[$groupKey]['abilities'][] = $this->formatAbility($entityAbility);
}

/**
* Prepare the entity ability into a json object that can be used on the frontend
*/
protected function format(EntityAbility $entityAbility): array
protected function formatAbility(EntityAbility $entityAbility): array
{
$classes = [];
foreach ($entityAbility->ability->entity->tagsWithEntity() as $tag) {
$tags = $entityAbility->ability->entity->tagsWithEntity();
foreach ($tags as $tag) {
$classes[] = ' kanka-tag-' . $tag->id;
$classes[] = ' kanka-tag-' . $tag->slug;

Expand All @@ -117,19 +124,27 @@ protected function format(EntityAbility $entityAbility): array
}
//implode(' ', $classes);

$note = nl2br((string) $this->mapAttributes(
Mentions::mapAny($entityAbility, 'note'),
false
));
if (!empty($note)) {
$note = '<strong>' . __('entities/abilities.fields.note') . ':</strong> ' . $note;
}

$data = [
'id' => $entityAbility->id,
'ability_id' => $entityAbility->ability_id,
'name' => $entityAbility->ability->name,
'entry' => $this->parseEntry($entityAbility->ability),
'type' => $entityAbility->ability->type,
'charges' => $this->parseCharges($entityAbility->ability),
'used_charges' => $entityAbility->charges,
'class' => $classes,
'note' => nl2br((string) $this->mapAttributes(
Mentions::mapAny($entityAbility, 'note'),
false
)),
'note' => $note,
'tags' => $this->formatTags($tags),
'visibility_id' => $entityAbility->visibility_id,
'visibility' => $entityAbility->visibilityName(),
'created_by' => $entityAbility->created_by,
'attributes' => $this->attributes($entityAbility->ability->entity),
'images' => [
Expand All @@ -143,10 +158,14 @@ protected function format(EntityAbility $entityAbility): array
'delete' => route('entities.entity_abilities.destroy', [$this->campaign, $this->entity, $entityAbility]),
'view' => route('entities.show', [$this->campaign, $entityAbility->ability->entity]),
],
'i18n' => [
'edit' => __('crud.update'),
'left' => __('entities/abilities.charges.left')
],
'entity' => [
'id' => $entityAbility->ability->entity->id,
'tooltip' => route('entities.tooltip', [$this->campaign, $entityAbility->ability->entity->id])
]
'tooltip' => route('entities.tooltip', [$this->campaign, $entityAbility->ability->entity->id]),
],
];

if (!empty($entityAbility->ability->charges)) {
Expand All @@ -172,4 +191,19 @@ protected function attributes(Entity $entity): array
}
return $attributes;
}

protected function formatTags(Collection $tags): array
{
$formatted = [];
/** @var Tag $tag */
foreach ($tags as $tag) {
$formatted[] = [
'id' => $tag->id,
'name' => $tag->name,
'url' => $tag->getLink(),
];
}

return $formatted;
}
}
9 changes: 9 additions & 0 deletions lang/en/entities/abilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
'note' => 'Note',
'position' => 'Position',
],
'charges' => [
'left' => ':amount left',
],
'groups' => [
'unorganised' => 'Unorganised',
],
'helpers' => [
'note' => 'You can reference entities using advanced mentions (ex :code) and attributes of the entity (ex :attr) in this field.',
'recharge' => 'Reset all charges for abilities that have been used.',
Expand All @@ -39,6 +45,9 @@
'reorder' => 'Reorder',
'title' => ':name Abilities',
],
'types' => [
'unorganised' => 'Abilities are grouped by their parent field, and fallback to being here.',
],
'update' => [
'success' => 'Entity ability :ability updated.',
'title' => 'Entity Ability for :name',
Expand Down
79 changes: 16 additions & 63 deletions resources/js/components/abilities/Abilities.vue
Original file line number Diff line number Diff line change
@@ -1,52 +1,18 @@
<template>
<div class="viewport box-abilities relative flex flex-col gap-5">
<div v-if="loading" class="load more text-center">
<i class="fa-solid fa-spin fa-spinner"></i>
<i class="fa-solid fa-spin fa-spinner" aria-hidden="true"></i>
</div>

<div class="flex gap-5 flex-wrap">
<parent v-for="parent in parents"
:key="parent.id"
:ability="parent">
<parent v-for="group in groups"
:key="group.id"
:group="group"
:permission="permission"
:meta="meta"
:trans="trans">
</parent>
</div>

<div v-if="show_parent" class="flex flex-col gap-5">
<div v-if="parent.entry" class="parent-box p-3 rounded bg-box shadow-xs">
<div class="parent-header mb-2">
<a class="text-lg" v-bind:href="parent.url">
{{ parent.name }}
</a>
</div>
<div class="entity-content parent-body" v-html="parent.entry">

</div>
</div>
<ability v-for="ability in parent.abilities"
:key="ability.id"
:ability="ability"
:permission="permission"
:meta="meta"
:trans="json_trans">
</ability>
</div>

<div class="flex flex-col gap-5">
<ability v-if="!show_parent" v-for="ability in abilities"
:key="ability.id"
:ability="ability"
:permission="permission"
:meta="meta"
:trans="json_trans">
</ability>
</div>

<AbilityForm :trans="json_trans">
</AbilityForm>

<div v-if="waiting" class="box-waiting absolute top-0 w-full h-full bg-black/20 text-center">
<i class="fa-solid fa-spin fa-spinner fa-4x mt-5"></i>
</div>
</div>
</template>

Expand All @@ -71,12 +37,9 @@
data() {
return {
abilities: [],
parents: [],
groups: [],
meta: [],
loading: true,
show_parent: false,
parent: null,
waiting: false,
modal: false,
json_trans: [],
Expand All @@ -88,24 +51,12 @@
fetch(this.api)
.then(response => response.json())
.then(response => {
this.abilities = response.data.abilities;
this.parents = response.data.parents;
this.groups = response.data.groups;
this.meta = response.data.meta;
this.loading = false;
this.waiting = false;
if (this.parent) {
// We need to find our parent again to "reload" it properly
this.parent = this.parents[this.parent.id];
this.showParent(this.parent);
}
});
},
//
showParent: function (parent) {
this.show_parent = !!parent;
},
/**
* Add an ability
Expand Down Expand Up @@ -138,11 +89,11 @@
mounted() {
this.getAbilities();
this.emitter.on('click_parent', (parent) => {
this.parent = parent;
this.showParent(parent);
});
//
// this.emitter.on('click_parent', (parent) => {
// this.parent = parent;
// this.showParent(parent);
// });
this.emitter.on('delete_ability', (ability) => {
this.deleteAbility(ability);
Expand All @@ -157,3 +108,5 @@
}
}
</script>
<script setup>
</script>
Loading

0 comments on commit 8d87443

Please sign in to comment.