Skip to content

Commit

Permalink
Merge branch '3.x' into multi-selectors-n-fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
lee-to authored Jan 9, 2025
2 parents c4c9c84 + ad22ac7 commit a211380
Show file tree
Hide file tree
Showing 16 changed files with 78 additions and 26 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
fail-fast: true
matrix:
php: [8.2, 8.3]
laravel: [11]
laravel: [10, 11]

steps:
- uses: shivammathur/setup-php@v2
Expand Down
1 change: 1 addition & 0 deletions src/Laravel/src/Commands/MakePageCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ private function makePage(
if (! $this->option('without-register')) {
self::addResourceOrPageToProviderFile(
$stubsPath->name,
page: true,
namespace: $stubsPath->namespace
);
}
Expand Down
7 changes: 6 additions & 1 deletion src/Laravel/src/Commands/MoonShineCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

use Leeto\PackageCommand\Command;
use MoonShine\Laravel\Support\StubsPath;
use MoonShine\MenuManager\MenuItem;
use ReflectionClass;

abstract class MoonShineCommand extends Command
{
Expand Down Expand Up @@ -43,11 +45,14 @@ public static function addResourceOrPageToMenu(string $class, string $title, str
{
$namespace = rtrim($namespace, '\\');

$reflector = new ReflectionClass(moonshineConfig()->getLayout());

self::addResourceOrPageTo(
class: "$namespace\\$class",
to: app_path('MoonShine/Layouts/MoonShineLayout.php'),
to: $reflector->getFileName(),
between: static fn (Stringable $content): Stringable => $content->betweenFirst("protected function menu(): array", '}'),
replace: static fn (Stringable $content, Closure $tab): Stringable => $content->replace("];", "{$tab()}MenuItem::make('$title', $class::class),\n{$tab(2)}];"),
use: MenuItem::class
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Laravel/src/DependencyInjection/MoonShineConfigurator.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ public function __construct(Repository $repository)
$this->items = $repository->get('moonshine', []);
$this->authorizationRules = Collection::make();
$this
->set('dir', 'app/MoonShine')
->set('namespace', 'App\MoonShine');
->set('dir', $this->items['dir'] ?? 'app/MoonShine')
->set('namespace', $this->items['namespace'] ?? 'App\MoonShine');
}

public function dir(string $dir, string $namespace): self
Expand Down
2 changes: 1 addition & 1 deletion src/Laravel/src/Http/Controllers/ReactiveController.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function __invoke(MoonShineRequest $request): JsonResponse
);

foreach ($fields as $field) {
$fields = $field->getReactiveCallback(
$fields = $field->formName($form->getName())->getReactiveCallback(
$fields,
data_get($values, $field->getColumn()),
$values->toArray(),
Expand Down
1 change: 0 additions & 1 deletion src/Laravel/src/Support/StubsPath.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public function __construct(

$pathWithExt = str($this->path)
->replace('\\', '/')
->deduplicate('/')
->replaceLast('.' . $this->ext, '')
->append('.' . $this->ext)
->value();
Expand Down
18 changes: 9 additions & 9 deletions src/UI/dist/assets/app.js

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion src/UI/resources/js/Components/FormBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export default (name = '', initData = {}, reactive = {}) => ({
t.reactiveUrl = t.initData.reactiveUrl

this.$watch('reactive', async function (value) {
let values = JSON.parse(JSON.stringify(value))

if (!t.blockWatch) {
let focused = document.activeElement

Expand Down Expand Up @@ -73,13 +75,23 @@ export default (name = '', initData = {}, reactive = {}) => ({
t.$nextTick(() => (t.blockWatch = false))
})

const choices = focused.closest('.choices')
const select = choices?.querySelector('select')

if (select && select.multiple) {
await t.$nextTick(() => {
values[select.getAttribute('data-reactive-column')] =
select.dataset.choicesValue.split(',')
})
}

request(
t,
t.reactiveUrl,
'post',
{
_component_name: t.name,
values: value,
values: values,
},
{},
componentRequestData,
Expand Down
27 changes: 24 additions & 3 deletions src/UI/resources/js/Components/Select.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Choices from 'choices.js'
import {createPopper} from '@popperjs/core'
import debounce from '../Support/Debounce.js'
import {crudFormQuery, prepareFormData} from '../Support/Forms.js'
import {crudFormQuery, getQueryString, prepareFormData} from '../Support/Forms.js'
import {dispatchEvents as de} from '../Support/DispatchEvents.js'
import {formToJSON} from 'axios'
import {DEFAULT_CONFIG} from 'choices.js/src/scripts/defaults'
Expand Down Expand Up @@ -195,7 +195,17 @@ export default (asyncUrl = '') => ({
...this.customOptions,
})

this.$el.addEventListener('change', () => (this.isLoadedOptions = false), false)
this.setDataValues()

this.$el.addEventListener(
'change',
() => {
this.isLoadedOptions = false

this.setDataValues()
},
false,
)

if (asyncUrl) {
this.$el.addEventListener(
Expand Down Expand Up @@ -274,6 +284,8 @@ export default (asyncUrl = '') => ({

if (this.removeItemButton) {
this.$el.parentElement.addEventListener('click', event => {
event.target.closest('.choices')?.querySelector('select')?.focus()

if (event.target.classList.contains('choices__button--remove')) {
const choiceElement = event.target.closest('.choices__item')
const id = choiceElement.getAttribute('data-id')
Expand Down Expand Up @@ -305,6 +317,11 @@ export default (asyncUrl = '') => ({
})
}
},
setDataValues() {
if (this.$el.getAttribute('multiple')) {
this.$el.setAttribute('data-choices-value', this.choicesInstance.getValue(true).join(','))
}
},
async asyncSearch() {
const query = this.searchTerms.value ?? null
let canRequest = this.$el.dataset.asyncOnInit || (query !== null && query.length)
Expand All @@ -325,6 +342,10 @@ export default (asyncUrl = '') => ({
formQuery = crudFormQuery(inputs)
}

if (form === null) {
formQuery = getQueryString({value: this.choicesInstance.getValue(true)})
}

options = await this.fromUrl(url.toString() + (formQuery.length ? '&' + formQuery : ''))
options = options.map(item => {
const {properties, ...other} = item
Expand All @@ -344,7 +365,7 @@ export default (asyncUrl = '') => ({
if (exclude !== '*') {
extra['_data'] = form
? formToJSON(prepareFormData(new FormData(form), exclude))
: {value: this.$el.value}
: {value: this.choicesInstance.getValue(true)}
}

de(componentEvent, '', this, extra)
Expand Down
4 changes: 3 additions & 1 deletion src/UI/resources/js/Request/Sets.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export function listComponentRequest(component, pushState = false) {
delete eventData.sort
}

const originalUrl = url

url = urlWithQuery(url, getQueryString(eventData))

let stopLoading = function (data, t) {
Expand All @@ -45,7 +47,7 @@ export function listComponentRequest(component, pushState = false) {
let componentRequestData = new ComponentRequestData()
componentRequestData
.withBeforeHandleResponse(function (data, t) {
const query = url.slice(url.indexOf('?') + 1)
const query = originalUrl.slice(originalUrl.indexOf('?') + 1)

if (pushState) {
history.pushState({}, '', query ? '?' + query : location.pathname)
Expand Down
3 changes: 2 additions & 1 deletion src/UI/resources/js/Support/DispatchEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export function dispatchEvents(events, type, component, extraProperties = {}) {

let eventName = parts[0]

let attributes = extraProperties
const attributes = {}
Object.assign(attributes, extraProperties)

if (Array.isArray(parts) && parts.length > 1) {
let params = parts[1].split(';')
Expand Down
4 changes: 4 additions & 0 deletions src/UI/resources/js/Support/URLs.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@ export function prepareQueryParams(params, exclude = null) {
}

export function mergeURLString(url, merge) {
if (merge === '') {
return url
}

return url + (url.includes('?') ? '&' + merge : '?' + merge)
}
3 changes: 1 addition & 2 deletions src/UI/resources/views/components/cards.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
{{ (int) $async }},
'{{ $asyncUrl }}'
)"
data-pushstate="{{ $attributes->get('data-pushstate', false)}}"
@defineEventWhen($async, 'cards_updated', $name, 'asyncRequest')
{{ $attributes->only(['data-events'])}}
{{ $attributes }}
>
<x-moonshine::loader x-show="loading" />
<div x-show="!loading">
Expand Down
3 changes: 1 addition & 2 deletions src/UI/resources/views/components/table/builder.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@ class="js-table-builder-container"
{{ (int) $async }},
'{{ $asyncUrl }}'
)"
data-pushstate="{{ $attributes->get('data-pushstate', false)}}"
@defineEvent('table_row_added', $name, 'add(true)')
@defineEvent('table_reindex', $name, 'resolveReindex')
@defineEventWhen($async, 'table_updated', $name, 'asyncRequest')
{{ $attributes->only(['data-events'])}}
{{ $attributes }}
>
@if($async && $searchable)
<div class="flex items-center gap-2">
Expand Down
2 changes: 1 addition & 1 deletion src/UI/src/Components/FormBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ protected function viewData(): array
fn (FieldContract $field): FieldContract => $field->formName($this->getName())
);
$fields->prepend(
Hidden::make('_component_name')->setValue($this->getName())
Hidden::make('_component_name')->formName($this->getName())->setValue($this->getName())
);

$reactiveFields = $onlyFields->reactiveFields()
Expand Down
9 changes: 9 additions & 0 deletions tests/Feature/Commands/ResourceCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace MoonShine\Tests\Feature\Commands;

use MoonShine\Laravel\Commands\MakeResourceCommand;
use MoonShine\MenuManager\MenuItem;
use MoonShine\Tests\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
Expand All @@ -19,9 +20,12 @@ final class ResourceCommandTest extends TestCase
#[TestDox('it successful file created')]
public function successfulCreated(): void
{
$reflector = new \ReflectionClass(moonshineConfig()->getLayout());

$name = 'DeleteMeResource';
$file = "$name.php";
$path = __DIR__ . "/../../../app/MoonShine/Resources/$file";
$layoutPath = $reflector->getFileName();

@unlink($path);

Expand All @@ -37,6 +41,11 @@ public function successfulCreated(): void
->assertSuccessful();

$this->assertFileExists($path);

$layoutContent = file_get_contents($layoutPath);

$this->assertStringContainsString(MenuItem::class, $layoutContent);
$this->assertStringContainsString('DeleteMeResource', $layoutContent);
}

#[Test]
Expand Down

0 comments on commit a211380

Please sign in to comment.