feat/012-windows-update-rings #18
@ -177,10 +177,15 @@ public static function getWizardSteps(): array
|
||||
});
|
||||
})
|
||||
->reactive()
|
||||
->afterStateUpdated(function (Set $set): void {
|
||||
->afterStateUpdated(function (Set $set, Get $get): void {
|
||||
$set('scope_mode', 'all');
|
||||
$set('backup_item_ids', null);
|
||||
$set('group_mapping', []);
|
||||
$set('group_mapping', static::groupMappingPlaceholders(
|
||||
backupSetId: $get('backup_set_id'),
|
||||
scopeMode: 'all',
|
||||
selectedItemIds: null,
|
||||
tenant: Tenant::current(),
|
||||
));
|
||||
$set('is_dry_run', true);
|
||||
$set('acknowledged_impact', false);
|
||||
$set('tenant_confirm', null);
|
||||
@ -204,8 +209,9 @@ public static function getWizardSteps(): array
|
||||
])
|
||||
->default('all')
|
||||
->reactive()
|
||||
->afterStateUpdated(function (Set $set, $state): void {
|
||||
$set('group_mapping', []);
|
||||
->afterStateUpdated(function (Set $set, Get $get, $state): void {
|
||||
$backupSetId = $get('backup_set_id');
|
||||
$tenant = Tenant::current();
|
||||
$set('is_dry_run', true);
|
||||
$set('acknowledged_impact', false);
|
||||
$set('tenant_confirm', null);
|
||||
@ -218,10 +224,17 @@ public static function getWizardSteps(): array
|
||||
|
||||
if ($state === 'all') {
|
||||
$set('backup_item_ids', null);
|
||||
$set('group_mapping', static::groupMappingPlaceholders(
|
||||
backupSetId: $backupSetId,
|
||||
scopeMode: 'all',
|
||||
selectedItemIds: null,
|
||||
tenant: $tenant,
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$set('group_mapping', []);
|
||||
$set('backup_item_ids', []);
|
||||
})
|
||||
->required(),
|
||||
@ -234,8 +247,18 @@ public static function getWizardSteps(): array
|
||||
->optionsLimit(300)
|
||||
->options(fn (Get $get) => static::restoreItemGroupedOptions($get('backup_set_id')))
|
||||
->reactive()
|
||||
->afterStateUpdated(function (Set $set): void {
|
||||
$set('group_mapping', []);
|
||||
->afterStateUpdated(function (Set $set, Get $get): void {
|
||||
$backupSetId = $get('backup_set_id');
|
||||
$selectedItemIds = $get('backup_item_ids');
|
||||
$selectedItemIds = is_array($selectedItemIds) ? $selectedItemIds : null;
|
||||
$tenant = Tenant::current();
|
||||
|
||||
$set('group_mapping', static::groupMappingPlaceholders(
|
||||
backupSetId: $backupSetId,
|
||||
scopeMode: 'selected',
|
||||
selectedItemIds: $selectedItemIds,
|
||||
tenant: $tenant,
|
||||
));
|
||||
$set('is_dry_run', true);
|
||||
$set('acknowledged_impact', false);
|
||||
$set('tenant_confirm', null);
|
||||
@ -249,29 +272,29 @@ public static function getWizardSteps(): array
|
||||
->visible(fn (Get $get): bool => $get('scope_mode') === 'selected')
|
||||
->required(fn (Get $get): bool => $get('scope_mode') === 'selected')
|
||||
->hintActions([
|
||||
Actions\Action::make('select_all_backup_items')
|
||||
->label('Select all')
|
||||
->icon('heroicon-o-check')
|
||||
->color('gray')
|
||||
->visible(fn (Get $get): bool => filled($get('backup_set_id')) && $get('scope_mode') === 'selected')
|
||||
->action(function (Get $get, Set $set): void {
|
||||
$groupedOptions = static::restoreItemGroupedOptions($get('backup_set_id'));
|
||||
Actions\Action::make('select_all_backup_items')
|
||||
->label('Select all')
|
||||
->icon('heroicon-o-check')
|
||||
->color('gray')
|
||||
->visible(fn (Get $get): bool => filled($get('backup_set_id')) && $get('scope_mode') === 'selected')
|
||||
->action(function (Get $get, Set $set): void {
|
||||
$groupedOptions = static::restoreItemGroupedOptions($get('backup_set_id'));
|
||||
|
||||
$allItemIds = [];
|
||||
$allItemIds = [];
|
||||
|
||||
foreach ($groupedOptions as $options) {
|
||||
$allItemIds = array_merge($allItemIds, array_keys($options));
|
||||
}
|
||||
foreach ($groupedOptions as $options) {
|
||||
$allItemIds = array_merge($allItemIds, array_keys($options));
|
||||
}
|
||||
|
||||
$set('backup_item_ids', array_values($allItemIds), shouldCallUpdatedHooks: true);
|
||||
}),
|
||||
Actions\Action::make('clear_backup_items')
|
||||
->label('Clear')
|
||||
->icon('heroicon-o-x-mark')
|
||||
->color('gray')
|
||||
->visible(fn (Get $get): bool => $get('scope_mode') === 'selected')
|
||||
->action(fn (Set $set) => $set('backup_item_ids', [], shouldCallUpdatedHooks: true)),
|
||||
])
|
||||
$set('backup_item_ids', array_values($allItemIds), shouldCallUpdatedHooks: true);
|
||||
}),
|
||||
Actions\Action::make('clear_backup_items')
|
||||
->label('Clear')
|
||||
->icon('heroicon-o-x-mark')
|
||||
->color('gray')
|
||||
->visible(fn (Get $get): bool => $get('scope_mode') === 'selected')
|
||||
->action(fn (Set $set) => $set('backup_item_ids', [], shouldCallUpdatedHooks: true)),
|
||||
])
|
||||
->helperText('Search by name or ID. Include foundations (scope tags, assignment filters) with policies to re-map IDs. Options are grouped by category, type, and platform.'),
|
||||
Section::make('Group mapping')
|
||||
->description('Some source groups do not exist in the target tenant. Map them or choose Skip.')
|
||||
@ -1383,8 +1406,43 @@ private static function unresolvedGroups(?int $backupSetId, ?array $selectedItem
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int>|null $selectedItemIds
|
||||
* @return array<string, string|null>
|
||||
*/
|
||||
private static function groupMappingPlaceholders(?int $backupSetId, string $scopeMode, ?array $selectedItemIds, ?Tenant $tenant): array
|
||||
{
|
||||
if (! $tenant || ! $backupSetId) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if ($scopeMode === 'selected' && ($selectedItemIds === null || $selectedItemIds === [])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$unresolved = static::unresolvedGroups(
|
||||
backupSetId: $backupSetId,
|
||||
selectedItemIds: $scopeMode === 'selected' ? $selectedItemIds : null,
|
||||
tenant: $tenant,
|
||||
);
|
||||
|
||||
$placeholders = [];
|
||||
|
||||
foreach ($unresolved as $group) {
|
||||
$groupId = $group['id'] ?? null;
|
||||
|
||||
if (! is_string($groupId) || $groupId === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$placeholders[$groupId] = null;
|
||||
}
|
||||
|
||||
return $placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private static function normalizeGroupMapping(mixed $mapping): array
|
||||
{
|
||||
if ($mapping instanceof \Illuminate\Contracts\Support\Arrayable) {
|
||||
@ -1449,7 +1507,7 @@ private static function normalizeGroupMapping(mixed $mapping): array
|
||||
$result[$sourceGroupId] = null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
return array_filter($result, static fn (?string $value): bool => is_string($value) && $value !== '');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
$user = User::factory()->create();
|
||||
$this->actingAs($user);
|
||||
|
||||
Livewire::test(CreateRestoreRun::class)
|
||||
$component = Livewire::test(CreateRestoreRun::class)
|
||||
->fillForm([
|
||||
'backup_set_id' => $backupSet->id,
|
||||
])
|
||||
@ -85,8 +85,15 @@
|
||||
->fillForm([
|
||||
'scope_mode' => 'selected',
|
||||
'backup_item_ids' => [$backupItem->id],
|
||||
])
|
||||
->assertFormFieldVisible('group_mapping.source-group-1');
|
||||
]);
|
||||
|
||||
$mapping = $component->get('data.group_mapping');
|
||||
|
||||
expect($mapping)->toBeArray();
|
||||
expect(array_key_exists('source-group-1', $mapping))->toBeTrue();
|
||||
expect($mapping['source-group-1'])->toBeNull();
|
||||
|
||||
$component->assertFormFieldVisible('group_mapping.source-group-1');
|
||||
});
|
||||
|
||||
test('restore wizard persists group mapping selections', function () {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user