mirror of
https://github.com/usetrmnl/byos_laravel.git
synced 2026-01-13 23:18:10 +00:00
feat: add xhrSelect Configuration
feat: add xhrSelectSearch Configuration
This commit is contained in:
parent
989ad2e985
commit
e50cbc14ec
2 changed files with 191 additions and 31 deletions
|
|
@ -6,6 +6,7 @@ use Keepsuit\Liquid\Exceptions\LiquidException;
|
|||
use Livewire\Volt\Component;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
new class extends Component {
|
||||
public Plugin $plugin;
|
||||
|
|
@ -32,6 +33,8 @@ new class extends Component {
|
|||
public array $mashup_plugins = [];
|
||||
public array $configuration_template = [];
|
||||
public array $configuration = [];
|
||||
public array $xhrSelectOptions = [];
|
||||
public array $searchQueries = [];
|
||||
|
||||
public function mount(): void
|
||||
{
|
||||
|
|
@ -345,6 +348,41 @@ HTML;
|
|||
$this->plugin->delete();
|
||||
$this->redirect(route('plugins.index'));
|
||||
}
|
||||
|
||||
public function loadXhrSelectOptions(string $fieldKey, string $endpoint, ?string $query = null): void
|
||||
{
|
||||
abort_unless(auth()->user()->plugins->contains($this->plugin), 403);
|
||||
|
||||
try {
|
||||
$requestData = [];
|
||||
if ($query !== null) {
|
||||
$requestData = [
|
||||
'function' => $fieldKey,
|
||||
'query' => $query
|
||||
];
|
||||
}
|
||||
|
||||
$response = $query !== null
|
||||
? Http::post($endpoint, $requestData)
|
||||
: Http::post($endpoint);
|
||||
|
||||
if ($response->successful()) {
|
||||
$this->xhrSelectOptions[$fieldKey] = $response->json();
|
||||
} else {
|
||||
$this->xhrSelectOptions[$fieldKey] = [];
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->xhrSelectOptions[$fieldKey] = [];
|
||||
}
|
||||
}
|
||||
|
||||
public function searchXhrSelect(string $fieldKey, string $endpoint): void
|
||||
{
|
||||
$query = $this->searchQueries[$fieldKey] ?? '';
|
||||
if (!empty($query)) {
|
||||
$this->loadXhrSelectOptions($fieldKey, $endpoint, $query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -644,6 +682,76 @@ HTML;
|
|||
@endif
|
||||
</flux:select>
|
||||
@endif
|
||||
@elseif($field['field_type'] === 'xhrSelect')
|
||||
<flux:select
|
||||
label="{{ $field['name'] }}"
|
||||
wire:model="configuration.{{ $fieldKey }}"
|
||||
description="{{ $field['description'] ?? '' }}"
|
||||
wire:init="loadXhrSelectOptions('{{ $fieldKey }}', '{{ $field['endpoint'] }}')"
|
||||
>
|
||||
<option value="">Select {{ $field['name'] }}...</option>
|
||||
@if(isset($xhrSelectOptions[$fieldKey]) && is_array($xhrSelectOptions[$fieldKey]))
|
||||
@foreach($xhrSelectOptions[$fieldKey] as $option)
|
||||
@if(is_array($option))
|
||||
@if(isset($option['id']) && isset($option['name']))
|
||||
{{-- xhrSelectSearch format: { 'id' => 'db-456', 'name' => 'Team Goals' } --}}
|
||||
<option value="{{ $option['id'] }}" {{ $currentValue === (string)$option['id'] ? 'selected' : '' }}>{{ $option['name'] }}</option>
|
||||
@else
|
||||
{{-- xhrSelect format: { 'Braves' => 123 } --}}
|
||||
@foreach($option as $label => $value)
|
||||
<option value="{{ $value }}" {{ $currentValue === (string)$value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
@endif
|
||||
@else
|
||||
<option value="{{ $option }}" {{ $currentValue === (string)$option ? 'selected' : '' }}>{{ $option }}</option>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
</flux:select>
|
||||
@elseif($field['field_type'] === 'xhrSelectSearch')
|
||||
<div class="space-y-2">
|
||||
|
||||
<flux:label>{{ $field['name'] }}</flux:label>
|
||||
<flux:description>{{ $field['description'] ?? '' }}</flux:description>
|
||||
<flux:input.group>
|
||||
<flux:input
|
||||
wire:model="searchQueries.{{ $fieldKey }}"
|
||||
placeholder="Enter search query..."
|
||||
/>
|
||||
<flux:button
|
||||
wire:click="searchXhrSelect('{{ $fieldKey }}', '{{ $field['endpoint'] }}')"
|
||||
icon="magnifying-glass"/>
|
||||
</flux:input.group>
|
||||
|
||||
@if((isset($xhrSelectOptions[$fieldKey]) && is_array($xhrSelectOptions[$fieldKey]) && count($xhrSelectOptions[$fieldKey]) > 0) || !empty($currentValue))
|
||||
<flux:select
|
||||
wire:model="configuration.{{ $fieldKey }}"
|
||||
>
|
||||
<option value="">Select {{ $field['name'] }}...</option>
|
||||
@if(isset($xhrSelectOptions[$fieldKey]) && is_array($xhrSelectOptions[$fieldKey]))
|
||||
@foreach($xhrSelectOptions[$fieldKey] as $option)
|
||||
@if(is_array($option))
|
||||
@if(isset($option['id']) && isset($option['name']))
|
||||
{{-- xhrSelectSearch format: { 'id' => 'db-456', 'name' => 'Team Goals' } --}}
|
||||
<option value="{{ $option['id'] }}" {{ $currentValue === (string)$option['id'] ? 'selected' : '' }}>{{ $option['name'] }}</option>
|
||||
@else
|
||||
{{-- xhrSelect format: { 'Braves' => 123 } --}}
|
||||
@foreach($option as $label => $value)
|
||||
<option value="{{ $value }}" {{ $currentValue === (string)$value ? 'selected' : '' }}>{{ $label }}</option>
|
||||
@endforeach
|
||||
@endif
|
||||
@else
|
||||
<option value="{{ $option }}" {{ $currentValue === (string)$option ? 'selected' : '' }}>{{ $option }}</option>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@if(!empty($currentValue) && (!isset($xhrSelectOptions[$fieldKey]) || empty($xhrSelectOptions[$fieldKey])))
|
||||
{{-- Show current value even if no options are loaded --}}
|
||||
<option value="{{ $currentValue }}" selected>{{ $currentValue }}</option>
|
||||
@endif
|
||||
</flux:select>
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<p>{{ $field['name'] }}: Field type "{{ $field['field_type'] }}" not yet supported</p>
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -23,17 +23,17 @@ test('hasMissingRequiredConfigurationFields returns true when required field is
|
|||
'field_type' => 'time_zone',
|
||||
'name' => 'Timezone',
|
||||
'description' => 'Select your timezone',
|
||||
'optional' => true // Marked as optional
|
||||
]
|
||||
]
|
||||
'optional' => true, // Marked as optional
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'timezone' => 'UTC' // Only timezone is set, api_key is missing
|
||||
]
|
||||
'timezone' => 'UTC', // Only timezone is set, api_key is missing
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
|
|
@ -56,9 +56,9 @@ test('hasMissingRequiredConfigurationFields returns false when all required fiel
|
|||
'field_type' => 'time_zone',
|
||||
'name' => 'Timezone',
|
||||
'description' => 'Select your timezone',
|
||||
'optional' => true // Marked as optional
|
||||
]
|
||||
]
|
||||
'optional' => true, // Marked as optional
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
|
|
@ -66,8 +66,8 @@ test('hasMissingRequiredConfigurationFields returns false when all required fiel
|
|||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'api_key' => 'test-api-key', // Required field is set
|
||||
'timezone' => 'UTC'
|
||||
]
|
||||
'timezone' => 'UTC',
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
|
|
@ -79,7 +79,7 @@ test('hasMissingRequiredConfigurationFields returns false when no custom fields
|
|||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => [],
|
||||
'configuration' => []
|
||||
'configuration' => [],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
|
|
@ -96,16 +96,16 @@ test('hasMissingRequiredConfigurationFields returns true when explicitly require
|
|||
'name' => 'API Key',
|
||||
'description' => 'Your API key',
|
||||
// Not marked as optional, so it's required
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'api_key' => null // Explicitly set to null
|
||||
]
|
||||
'api_key' => null, // Explicitly set to null
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
|
|
@ -122,16 +122,16 @@ test('hasMissingRequiredConfigurationFields returns true when required field is
|
|||
'name' => 'API Key',
|
||||
'description' => 'Your API key',
|
||||
// Not marked as optional, so it's required
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'api_key' => '' // Empty string
|
||||
]
|
||||
'api_key' => '', // Empty string
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
|
|
@ -149,16 +149,16 @@ test('hasMissingRequiredConfigurationFields returns true when required array fie
|
|||
'description' => 'Select items',
|
||||
'multiple' => true,
|
||||
// Not marked as optional, so it's required
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'selected_items' => [] // Empty array
|
||||
]
|
||||
'selected_items' => [], // Empty array
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
|
|
@ -178,16 +178,16 @@ test('hasMissingRequiredConfigurationFields returns false when author_bio field
|
|||
'keyname' => 'plugin_field',
|
||||
'name' => 'Field Name',
|
||||
'field_type' => 'string',
|
||||
]
|
||||
]
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'plugin_field' => 'set' // Required field is set
|
||||
]
|
||||
'plugin_field' => 'set', // Required field is set
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
|
|
@ -203,15 +203,67 @@ test('hasMissingRequiredConfigurationFields returns false when field has default
|
|||
'field_type' => 'string',
|
||||
'name' => 'API Key',
|
||||
'description' => 'Your API key',
|
||||
'default' => 'default-api-key' // Has default value
|
||||
]
|
||||
]
|
||||
'default' => 'default-api-key', // Has default value
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [] // Empty configuration, but field has default
|
||||
'configuration' => [], // Empty configuration, but field has default
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns true when required xhrSelect field is missing', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
'custom_fields' => [
|
||||
[
|
||||
'keyname' => 'team',
|
||||
'field_type' => 'xhrSelect',
|
||||
'name' => 'Baseball Team',
|
||||
'description' => 'Select your team',
|
||||
'endpoint' => 'https://usetrmnl.com/custom_plugin_example_xhr_select.json',
|
||||
// Not marked as optional, so it's required
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [], // Empty configuration
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeTrue();
|
||||
});
|
||||
|
||||
test('hasMissingRequiredConfigurationFields returns false when required xhrSelect field is set', function () {
|
||||
$user = User::factory()->create();
|
||||
|
||||
$configurationTemplate = [
|
||||
'custom_fields' => [
|
||||
[
|
||||
'keyname' => 'team',
|
||||
'field_type' => 'xhrSelect',
|
||||
'name' => 'Baseball Team',
|
||||
'description' => 'Select your team',
|
||||
'endpoint' => 'https://usetrmnl.com/custom_plugin_example_xhr_select.json',
|
||||
// Not marked as optional, so it's required
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$plugin = Plugin::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'configuration_template' => $configurationTemplate,
|
||||
'configuration' => [
|
||||
'team' => '123', // Required field is set
|
||||
],
|
||||
]);
|
||||
|
||||
expect($plugin->hasMissingRequiredConfigurationFields())->toBeFalse();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue