feat(helpdesk): polish handover schema editor UI/UX
Auto-generate field keys and option values from labels via slugify, add live preview panel with hover-highlight, insert-between-fields dividers, and various spacing/styling improvements. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -128,8 +128,8 @@ class SoftwareProductServiceTest extends TestCase
|
||||
->willReturn(true);
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'date', 'key' => 'handover_date', 'label' => 'Handover date', 'required' => true],
|
||||
['type' => 'textarea', 'key' => 'notes', 'label' => 'Notes', 'required' => false],
|
||||
['type' => 'date', 'label' => 'Handover date', 'required' => true],
|
||||
['type' => 'textarea', 'label' => 'Notes', 'required' => false],
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
@@ -149,37 +149,25 @@ class SoftwareProductServiceTest extends TestCase
|
||||
$this->assertTrue($result['ok']);
|
||||
}
|
||||
|
||||
public function testSaveHandoverSchemaRejectsDuplicateKeys(): void
|
||||
public function testSaveHandoverSchemaRejectsDuplicateGeneratedKeys(): void
|
||||
{
|
||||
[$service] = $this->createServiceWithProduct();
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'text', 'key' => 'name', 'label' => 'Name 1'],
|
||||
['type' => 'text', 'key' => 'name', 'label' => 'Name 2'],
|
||||
['type' => 'text', 'label' => 'Name'],
|
||||
['type' => 'text', 'label' => 'Name'],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertArrayHasKey('field_2_key', $result['errors']);
|
||||
}
|
||||
|
||||
public function testSaveHandoverSchemaRejectsInvalidKeyFormat(): void
|
||||
{
|
||||
[$service] = $this->createServiceWithProduct();
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'text', 'key' => '1invalid', 'label' => 'Bad key'],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertArrayHasKey('field_1_key', $result['errors']);
|
||||
}
|
||||
|
||||
public function testSaveHandoverSchemaRejectsUnknownType(): void
|
||||
{
|
||||
[$service] = $this->createServiceWithProduct();
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'unknown_type', 'key' => 'field', 'label' => 'Field'],
|
||||
['type' => 'unknown_type', 'label' => 'Field'],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
@@ -192,7 +180,7 @@ class SoftwareProductServiceTest extends TestCase
|
||||
|
||||
$fields = [];
|
||||
for ($i = 0; $i < 51; $i++) {
|
||||
$fields[] = ['type' => 'text', 'key' => 'field_' . $i, 'label' => 'Field ' . $i];
|
||||
$fields[] = ['type' => 'text', 'label' => 'Field ' . $i];
|
||||
}
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', $fields);
|
||||
@@ -206,13 +194,54 @@ class SoftwareProductServiceTest extends TestCase
|
||||
[$service] = $this->createServiceWithProduct();
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'select', 'key' => 'choice', 'label' => 'Choice', 'options' => []],
|
||||
['type' => 'select', 'label' => 'Choice', 'options' => []],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertArrayHasKey('field_1_options', $result['errors']);
|
||||
}
|
||||
|
||||
public function testSaveHandoverSchemaRejectsSelectOptionWithEmptyLabel(): void
|
||||
{
|
||||
[$service] = $this->createServiceWithProduct();
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'select', 'label' => 'Choice', 'options' => [
|
||||
['label' => ''],
|
||||
]],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
$this->assertArrayHasKey('field_1_option_1', $result['errors']);
|
||||
}
|
||||
|
||||
public function testSaveHandoverSchemaAutoGeneratesOptionValues(): void
|
||||
{
|
||||
[$service, $repository] = $this->createServiceWithProduct();
|
||||
$repository->expects($this->once())
|
||||
->method('updateHandoverSchema')
|
||||
->with('INFO', $this->callback(function ($json) {
|
||||
$data = json_decode($json, true);
|
||||
$options = $data['fields'][0]['options'] ?? [];
|
||||
|
||||
return count($options) === 2
|
||||
&& $options[0]['value'] === 'niedrig'
|
||||
&& $options[0]['label'] === 'Niedrig'
|
||||
&& $options[1]['value'] === 'sehr_hoch'
|
||||
&& $options[1]['label'] === 'Sehr hoch';
|
||||
}))
|
||||
->willReturn(true);
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'select', 'label' => 'Risk', 'options' => [
|
||||
['label' => 'Niedrig'],
|
||||
['label' => 'Sehr hoch'],
|
||||
]],
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
}
|
||||
|
||||
public function testSaveHandoverSchemaAllowsHeadingWithoutKey(): void
|
||||
{
|
||||
[$service, $repository] = $this->createServiceWithProduct();
|
||||
@@ -244,7 +273,7 @@ class SoftwareProductServiceTest extends TestCase
|
||||
->willReturn(true);
|
||||
|
||||
$result = $service->saveHandoverSchema('INFO', [
|
||||
['type' => 'text', 'key' => 'name', 'label' => 'Name'],
|
||||
['type' => 'text', 'label' => 'Name'],
|
||||
]);
|
||||
|
||||
$this->assertTrue($result['ok']);
|
||||
@@ -257,7 +286,7 @@ class SoftwareProductServiceTest extends TestCase
|
||||
|
||||
$service = $this->createService($repository);
|
||||
$result = $service->saveHandoverSchema('NONEXISTENT', [
|
||||
['type' => 'text', 'key' => 'name', 'label' => 'Name'],
|
||||
['type' => 'text', 'label' => 'Name'],
|
||||
]);
|
||||
|
||||
$this->assertFalse($result['ok']);
|
||||
|
||||
Reference in New Issue
Block a user