Skip to content

Commit 7dba860

Browse files
committed
Allow configuring icon to a command
1 parent ef86ad6 commit 7dba860

10 files changed

Lines changed: 42 additions & 5 deletions

File tree

demo/app/Sharp/Authors/Commands/VisitFacebookProfileCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ public function label(): string
1414

1515
public function buildCommandConfig(): void
1616
{
17-
$this->configureDescription('You will leave Sharp');
17+
$this->configureDescription('You will leave Sharp')
18+
->configureIcon('lucide-facebook');
1819
}
1920

2021
public function execute(mixed $instanceId, array $data = []): array

demo/app/Sharp/Posts/Commands/BulkPublishPostsCommand.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public function label(): ?string
1515
public function buildCommandConfig(): void
1616
{
1717
$this->configureDescription('Bulk command to publish posts')
18+
->configureIcon('lucide-check-check')
1819
->configureInstanceSelectionRequired();
1920
}
2021

demo/app/Sharp/Posts/Commands/ComposeEmailWithPostsWizardCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ public function label(): ?string
2121

2222
public function buildCommandConfig(): void
2323
{
24-
$this->configureDescription('Use this wizard command to compose a message choosing posts links in a list');
24+
$this->configureDescription('Use this wizard command to compose a message choosing posts links in a list')
25+
->configureIcon('lucide-mail');
2526
}
2627

2728
public function buildFormFieldsForFirstStep(FieldsContainer $formFields): void

resources/js/commands/components/CommandDropdownItems.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
77
import { useBreakpoints } from "@/composables/useBreakpoints";
88
import { showAlert } from "@/utils/dialogs";
9+
import Icon from "@/components/ui/Icon.vue";
910
1011
const props = defineProps<{
1112
commands: CommandData[][],
@@ -38,6 +39,9 @@
3839
@click="$emit('select', command)"
3940
:disabled="requiresSelection(command)"
4041
>
42+
<template v-if="command.icon">
43+
<Icon :icon="command.icon" class="size-4" />
44+
</template>
4145
<div>
4246
{{ command.label }}
4347
<template v-if="command.description">

resources/js/types/generated.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export type CommandData = {
4444
buttonLabel: string | null;
4545
} | null;
4646
hasForm: boolean;
47+
icon: IconData | null;
4748
authorization: Array<string | number> | boolean;
4849
instanceSelection: InstanceSelectionMode | null;
4950
primary: boolean | null;

src/Data/Commands/CommandData.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Code16\Sharp\Data\Commands;
44

55
use Code16\Sharp\Data\Data;
6+
use Code16\Sharp\Data\IconData;
67
use Code16\Sharp\Enums\CommandType;
78
use Code16\Sharp\Enums\InstanceSelectionMode;
89
use Spatie\TypeScriptTransformer\Attributes\LiteralTypeScriptType;
@@ -20,6 +21,7 @@ public function __construct(
2021
#[LiteralTypeScriptType('{ text: string, title: string | null, buttonLabel: string | null } | null')]
2122
public ?array $confirmation,
2223
public bool $hasForm,
24+
public ?IconData $icon,
2325
/** @var array<string|int>|bool */
2426
public array|bool $authorization,
2527
public ?InstanceSelectionMode $instanceSelection = null,
@@ -34,6 +36,7 @@ public static function from(array $command): self
3436
'instanceSelection' => isset($command['instanceSelection'])
3537
? InstanceSelectionMode::from($command['instanceSelection'])
3638
: null,
39+
'icon' => IconData::optional($command['icon'] ?? null),
3740
];
3841

3942
return new self(...$command);

src/EntityList/Commands/Command.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ abstract class Command
3333
private ?string $confirmationTitle = null;
3434
private ?string $confirmationButtonLabel = null;
3535
private ?string $description = null;
36+
private ?string $icon = null;
3637

3738
protected function info(string $message, bool $reload = false): array
3839
{
@@ -146,6 +147,13 @@ final protected function configureConfirmationText(string $confirmationText, ?st
146147
return $this;
147148
}
148149

150+
final protected function configureIcon(string $icon): self
151+
{
152+
$this->icon = $icon;
153+
154+
return $this;
155+
}
156+
149157
/**
150158
* Check if the current user is allowed to use this Command.
151159
*/
@@ -179,6 +187,11 @@ final public function getDescription(): ?string
179187
return $this->description;
180188
}
181189

190+
final public function getIcon(): ?string
191+
{
192+
return $this->icon;
193+
}
194+
182195
final public function getFormModalTitle(?array $formData): ?string
183196
{
184197
return ($callback = $this->formModalTitle) instanceof Closure

src/EntityList/Traits/Utils/CommonCommandUtils.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Code16\Sharp\EntityList\Commands\Command;
66
use Code16\Sharp\EntityList\Commands\EntityCommand;
7+
use Code16\Sharp\Utils\Icons\IconManager;
78
use Illuminate\Support\Collection;
89

910
trait CommonCommandUtils
@@ -30,6 +31,7 @@ protected function appendCommandsToConfig(Collection $commandHandlers, array &$c
3031
'authorization' => $instanceId
3132
? $handler->authorizeFor($instanceId)
3233
: $handler->getGlobalAuthorization(),
34+
'icon' => app(IconManager::class)->iconToArray($handler->getIcon()),
3335
...$handler instanceof EntityCommand ? [
3436
'instanceSelection' => $handler->getInstanceSelectionMode(),
3537
] : [],

tests/Unit/Dashboard/DashboardCommandTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public function execute(array $data = []): array {}
3434
'description' => null,
3535
'confirmation' => null,
3636
'hasForm' => false,
37+
'icon' => null,
3738
]);
3839
});
3940

@@ -113,6 +114,7 @@ public function execute(array $data = []): array {}
113114
'authorization' => true,
114115
'confirmation' => null,
115116
'description' => null,
117+
'icon' => null,
116118
],
117119
],
118120
],

tests/Unit/EntityList/SharpEntityListCommandTest.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public function execute($instanceId, array $data = []): array {}
5353
'instanceSelection' => null,
5454
'confirmation' => null,
5555
'hasForm' => false,
56+
'icon' => null,
5657
],
5758
],
5859
],
@@ -66,6 +67,7 @@ public function execute($instanceId, array $data = []): array {}
6667
'description' => null,
6768
'confirmation' => null,
6869
'hasForm' => false,
70+
'icon' => null,
6971
],
7072
],
7173
],
@@ -265,7 +267,7 @@ public function getListData(): array|\Illuminate\Contracts\Support\Arrayable
265267
expect($list->listConfig()['commands']['instance'][0][0]['authorization'])->toEqual([1, 2]);
266268
});
267269

268-
it('allows to define a description on a command', function () {
270+
it('allows to define a description & icon on a command', function () {
269271
$list = new class() extends FakeSharpEntityList
270272
{
271273
public function getEntityCommands(): ?array
@@ -280,7 +282,8 @@ public function label(): string
280282

281283
public function buildCommandConfig(): void
282284
{
283-
$this->configureDescription('My Entity Command description');
285+
$this->configureDescription('My Entity Command description')
286+
->configureIcon('testicon-user');
284287
}
285288

286289
public function execute(array $data = []): array {}
@@ -291,7 +294,13 @@ public function execute(array $data = []): array {}
291294

292295
$list->buildListConfig();
293296

294-
expect($list->listConfig()['commands']['entity'][0][0]['description'])->toEqual('My Entity Command description');
297+
expect($list->listConfig()['commands']['entity'][0][0])->toMatchArray([
298+
'description' => 'My Entity Command description',
299+
'icon' => [
300+
'name' => 'testicon-user',
301+
'svg' => '<svg><!--user--></svg>',
302+
],
303+
]);
295304
});
296305

297306
it('allows to define separators in instance commands', function () {

0 commit comments

Comments
 (0)