@kronor/dtv 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/assets/InterVariable-CWi-zmRD.woff2 +0 -0
  2. package/dist/assets/InterVariable-Italic-d6KXgdvN.woff2 +0 -0
  3. package/dist/assets/index-BNgm6iTo.js +2105 -0
  4. package/dist/assets/index-CKkrV_Rb.css +1 -0
  5. package/dist/assets/primeicons-C6QP2o4f.woff2 +0 -0
  6. package/dist/assets/primeicons-DMOk5skT.eot +0 -0
  7. package/dist/assets/primeicons-Dr5RGzOO.svg +345 -0
  8. package/dist/assets/primeicons-MpK4pl85.ttf +0 -0
  9. package/dist/assets/primeicons-WjwUDZjB.woff +0 -0
  10. package/dist/index.html +17 -0
  11. package/package.json +5 -1
  12. package/.editorconfig +0 -12
  13. package/.github/copilot-instructions.md +0 -64
  14. package/.github/workflows/ci.yml +0 -51
  15. package/.husky/pre-commit +0 -8
  16. package/e2e/app.spec.ts +0 -6
  17. package/e2e/cell-renderer-setfilterstate.spec.ts +0 -63
  18. package/e2e/filter-sharing.spec.ts +0 -113
  19. package/e2e/filter-url-persistence.spec.ts +0 -36
  20. package/e2e/graphqlMock.ts +0 -144
  21. package/e2e/multi-field-filters.spec.ts +0 -95
  22. package/e2e/pagination.spec.ts +0 -38
  23. package/e2e/payment-request-email-filter.spec.ts +0 -67
  24. package/e2e/save-filter-splitbutton.spec.ts +0 -68
  25. package/e2e/simple-view-email-filter.spec.ts +0 -67
  26. package/e2e/simple-view-transforms.spec.ts +0 -171
  27. package/e2e/simple-view.spec.ts +0 -104
  28. package/e2e/transform-regression.spec.ts +0 -108
  29. package/eslint.config.js +0 -30
  30. package/index.html +0 -17
  31. package/jest.config.js +0 -10
  32. package/playwright.config.ts +0 -54
  33. package/src/App.externalRuntime.test.ts +0 -190
  34. package/src/App.tsx +0 -540
  35. package/src/assets/react.svg +0 -1
  36. package/src/components/AIAssistantForm.tsx +0 -241
  37. package/src/components/FilterForm.test.ts +0 -82
  38. package/src/components/FilterForm.tsx +0 -375
  39. package/src/components/PhoneNumberFilter.tsx +0 -102
  40. package/src/components/SavedFilterList.tsx +0 -181
  41. package/src/components/SpeechInput.tsx +0 -67
  42. package/src/components/Table.tsx +0 -119
  43. package/src/components/TablePagination.tsx +0 -40
  44. package/src/components/aiAssistant.test.ts +0 -270
  45. package/src/components/aiAssistant.ts +0 -291
  46. package/src/framework/cell-renderer-components/CurrencyAmount.tsx +0 -30
  47. package/src/framework/cell-renderer-components/LayoutHelpers.tsx +0 -74
  48. package/src/framework/cell-renderer-components/Link.tsx +0 -28
  49. package/src/framework/cell-renderer-components/Mapping.tsx +0 -11
  50. package/src/framework/cell-renderer-components.test.ts +0 -353
  51. package/src/framework/column-definition.tsx +0 -85
  52. package/src/framework/currency.test.ts +0 -46
  53. package/src/framework/currency.ts +0 -62
  54. package/src/framework/data.staticConditions.test.ts +0 -46
  55. package/src/framework/data.test.ts +0 -167
  56. package/src/framework/data.ts +0 -162
  57. package/src/framework/filter-form-state.test.ts +0 -189
  58. package/src/framework/filter-form-state.ts +0 -185
  59. package/src/framework/filter-sharing.test.ts +0 -135
  60. package/src/framework/filter-sharing.ts +0 -118
  61. package/src/framework/filters.ts +0 -194
  62. package/src/framework/graphql.buildHasuraConditions.test.ts +0 -473
  63. package/src/framework/graphql.paginationKey.test.ts +0 -29
  64. package/src/framework/graphql.test.ts +0 -286
  65. package/src/framework/graphql.ts +0 -462
  66. package/src/framework/native-runtime/index.tsx +0 -33
  67. package/src/framework/native-runtime/nativeComponents.test.ts +0 -108
  68. package/src/framework/runtime-reference.test.ts +0 -172
  69. package/src/framework/runtime.ts +0 -15
  70. package/src/framework/saved-filters.test.ts +0 -422
  71. package/src/framework/saved-filters.ts +0 -293
  72. package/src/framework/state.test.ts +0 -86
  73. package/src/framework/state.ts +0 -148
  74. package/src/framework/transform.test.ts +0 -51
  75. package/src/framework/view-parser-initialvalues.test.ts +0 -228
  76. package/src/framework/view-parser.ts +0 -714
  77. package/src/framework/view.test.ts +0 -1805
  78. package/src/framework/view.ts +0 -38
  79. package/src/index.css +0 -6
  80. package/src/main.tsx +0 -99
  81. package/src/views/index.ts +0 -12
  82. package/src/views/payment-requests/components/NoRowsExtendDateRange.tsx +0 -37
  83. package/src/views/payment-requests/components/PaymentMethod.tsx +0 -184
  84. package/src/views/payment-requests/components/PaymentStatusTag.tsx +0 -61
  85. package/src/views/payment-requests/index.ts +0 -1
  86. package/src/views/payment-requests/runtime.tsx +0 -145
  87. package/src/views/payment-requests/view.json +0 -692
  88. package/src/views/payment-requests-initial-values.test.ts +0 -73
  89. package/src/views/request-log/index.ts +0 -2
  90. package/src/views/request-log/runtime.tsx +0 -47
  91. package/src/views/request-log/view.json +0 -123
  92. package/src/views/simple-test-view/index.ts +0 -3
  93. package/src/views/simple-test-view/runtime.tsx +0 -85
  94. package/src/views/simple-test-view/view.json +0 -191
  95. package/src/vite-env.d.ts +0 -1
  96. package/tailwind.config.js +0 -7
  97. package/tsconfig.app.json +0 -26
  98. package/tsconfig.jest.json +0 -6
  99. package/tsconfig.json +0 -7
  100. package/tsconfig.node.json +0 -24
  101. package/vite.config.ts +0 -11
  102. /package/{public → dist}/vite.svg +0 -0
@@ -1,38 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- const APP_URL = 'http://localhost:5173/?test-view=simple-test-view';
5
- const nextButton = '[data-testid="pagination-next"]';
6
- const prevButton = '[data-testid="pagination-prev"]';
7
- const pageIndicator = '[data-testid="pagination-page"]';
8
- const tableRows = 'table tbody tr';
9
-
10
- test.describe('Simple View Pagination', () => {
11
- test.beforeEach(async ({ page }) => {
12
- await page.route('**/graphql', mockPaginationGraphQL);
13
- await page.goto(APP_URL);
14
- await page.waitForSelector(tableRows);
15
- });
16
-
17
- test('shows first page and disables previous button', async ({ page }) => {
18
- await expect(page.locator(pageIndicator)).toHaveText('1-20');
19
- await expect(page.locator(prevButton)).toBeDisabled();
20
- const rowCount = await page.locator(tableRows).count();
21
- expect(rowCount).toBe(20);
22
- });
23
-
24
- test('can go to next and previous page', async ({ page }) => {
25
- await page.click(nextButton);
26
- await expect(page.locator(pageIndicator)).toHaveText('21-30');
27
- await expect(page.locator(prevButton)).toBeEnabled();
28
- await page.click(prevButton);
29
- await expect(page.locator(pageIndicator)).toHaveText('1-20');
30
- });
31
-
32
- test('next button disables on last page', async ({ page }) => {
33
- await page.click(nextButton); // to 2nd page
34
- await expect(page.locator(pageIndicator)).toHaveText('21-30');
35
- await expect(page.locator(tableRows)).toHaveCount(10);
36
- await expect(page.locator(nextButton)).toBeDisabled();
37
- });
38
- });
@@ -1,67 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- test.describe('Simple View Email Filter', () => {
5
- test('should set email filter when clicking on email', async ({ page }) => {
6
- // Intercept the GraphQL request and mock the response
7
- await page.route('**/v1/graphql', mockPaginationGraphQL);
8
-
9
- // Navigate to the simple test view
10
- await page.goto('/?test-view=simple-test-view');
11
-
12
- // Wait for the table to be present and visible
13
- const table = page.getByRole('table');
14
- await expect(table).toBeVisible();
15
-
16
- // Verify that the table headers are rendered correctly
17
- await expect(table.getByText('Test Column Header')).toBeVisible();
18
- await expect(table.getByText('Email')).toBeVisible();
19
-
20
- // Find the first email button in the Email column
21
- const firstEmailButton = table.locator('td button').filter({ hasText: '@' }).first();
22
- await expect(firstEmailButton).toBeVisible();
23
-
24
- // Verify the button has the expected styling classes
25
- await expect(firstEmailButton).toHaveClass(/text-blue-500/);
26
- await expect(firstEmailButton).toHaveClass(/underline/);
27
-
28
- // Get the email text before clicking
29
- const emailText = await firstEmailButton.textContent();
30
- expect(emailText).toMatch(/@/);
31
- expect(emailText).toBeTruthy(); // Ensure it's not null
32
-
33
- // Click the email button
34
- await firstEmailButton.click();
35
-
36
- // Show filters to see the filter form
37
- await page.getByText('Filters', { exact: true }).click();
38
-
39
- // Verify that the Email filter is now populated with the clicked email
40
- const emailFilterInput = page.getByText('Email', { exact: true }).locator('..').locator('~ div input');
41
- await expect(emailFilterInput).toHaveValue(emailText!);
42
-
43
- // Verify that the table now shows only rows with that email (should be just 1 row)
44
- const emailButtons = table.locator('td button').filter({ hasText: emailText! });
45
- await expect(emailButtons).toHaveCount(1);
46
- });
47
-
48
- test('should show tooltip on email hover', async ({ page }) => {
49
- // Intercept the GraphQL request and mock the response
50
- await page.route('**/v1/graphql', mockPaginationGraphQL);
51
-
52
- // Navigate to the simple test view
53
- await page.goto('/?test-view=simple-test-view');
54
-
55
- // Wait for the table to be present and visible
56
- const table = page.getByRole('table');
57
- await expect(table).toBeVisible();
58
-
59
- // Find the first email button
60
- const emailButton = table.locator('td button').filter({ hasText: '@' }).first();
61
- await expect(emailButton).toBeVisible();
62
-
63
- // Check for title attribute (tooltip)
64
- const title = await emailButton.getAttribute('title');
65
- expect(title).toMatch(/Filter by email:/);
66
- });
67
- });
@@ -1,68 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- test.describe('Save Filter SplitButton', () => {
5
- test.beforeEach(async ({ page }) => {
6
- // Set up GraphQL mock
7
- await page.route('**/v1/graphql', mockPaginationGraphQL);
8
-
9
- // Navigate to the app
10
- await page.goto('/?test-view=simple-test-view');
11
- });
12
-
13
- test('should render SplitButton for save filter', async ({ page }) => {
14
- // Show filters
15
- await page.getByText('Filters', { exact: true }).click();
16
-
17
- // Look for the Save Filter SplitButton
18
- const saveFilterButton = page.locator('.p-splitbutton').filter({ hasText: 'Save Filter' });
19
- await expect(saveFilterButton).toBeVisible();
20
-
21
- // Verify the main button text
22
- const mainButton = saveFilterButton.locator('.p-splitbutton-defaultbutton');
23
- await expect(mainButton).toContainText('Save Filter');
24
-
25
- // Verify the dropdown exists
26
- const dropdownButton = saveFilterButton.locator('.p-splitbutton-menubutton');
27
- await expect(dropdownButton).toBeVisible();
28
- });
29
-
30
- test('should open dropdown menu when arrow is clicked', async ({ page }) => {
31
- // Show filters
32
- await page.getByText('Filters', { exact: true }).click();
33
-
34
- // Find the SplitButton
35
- const saveFilterButton = page.locator('.p-splitbutton').filter({ hasText: 'Save Filter' });
36
- await expect(saveFilterButton).toBeVisible();
37
-
38
- // Click the dropdown arrow
39
- const dropdownButton = saveFilterButton.locator('.p-splitbutton-menubutton');
40
- await dropdownButton.click();
41
-
42
- // Should see a menu appear (even if empty)
43
- const menu = page.locator('.p-menu', { hasText: /Update/ }).or(page.locator('.p-menu'));
44
- await expect(menu.first()).toBeVisible();
45
- });
46
-
47
- test('main button click should trigger save dialog', async ({ page }) => {
48
- // Show filters
49
- await page.getByText('Filters', { exact: true }).click();
50
-
51
- // Set up dialog handler to verify it's triggered
52
- let dialogTriggered = false;
53
- page.on('dialog', async dialog => {
54
- expect(dialog.type()).toBe('prompt');
55
- expect(dialog.message()).toBe('Enter a name for this filter:');
56
- dialogTriggered = true;
57
- await dialog.dismiss(); // Just dismiss to avoid actually saving
58
- });
59
-
60
- // Click the main save button
61
- const saveFilterButton = page.locator('.p-splitbutton').filter({ hasText: 'Save Filter' });
62
- await saveFilterButton.locator('.p-splitbutton-defaultbutton').click();
63
-
64
- // Verify dialog was triggered
65
- await page.waitForTimeout(500);
66
- expect(dialogTriggered).toBe(true);
67
- });
68
- });
@@ -1,67 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- test.describe('Simple View Email Filter', () => {
5
- test('should set email filter when clicking on email', async ({ page }) => {
6
- // Intercept the GraphQL request and mock the response
7
- await page.route('**/v1/graphql', mockPaginationGraphQL);
8
-
9
- // Navigate to the simple test view
10
- await page.goto('/?test-view=simple-test-view');
11
-
12
- // Wait for the table to be present and visible
13
- const table = page.getByRole('table');
14
- await expect(table).toBeVisible();
15
-
16
- // Verify that the table headers are rendered correctly
17
- await expect(table.getByText('Test Column Header')).toBeVisible();
18
- await expect(table.getByText('Email')).toBeVisible();
19
-
20
- // Find the first email button in the Email column
21
- const firstEmailButton = table.locator('td button').filter({ hasText: '@' }).first();
22
- await expect(firstEmailButton).toBeVisible();
23
-
24
- // Verify the button has the expected styling classes
25
- await expect(firstEmailButton).toHaveClass(/text-blue-500/);
26
- await expect(firstEmailButton).toHaveClass(/underline/);
27
-
28
- // Get the email text before clicking
29
- const emailText = await firstEmailButton.textContent();
30
- expect(emailText).toMatch(/@/);
31
- expect(emailText).toBeTruthy(); // Ensure it's not null
32
-
33
- // Click the email button
34
- await firstEmailButton.click();
35
-
36
- // Show filters to see the filter form
37
- await page.getByText('Filters', { exact: true }).click();
38
-
39
- // Verify that the Email filter is now populated with the clicked email
40
- const emailFilterInput = page.getByText('Email', { exact: true }).locator('..').locator('~ div input');
41
- await expect(emailFilterInput).toHaveValue(emailText!);
42
-
43
- // Verify that the table now shows only rows with that email (should be just 1 row)
44
- const emailButtons = table.locator('td button').filter({ hasText: emailText! });
45
- await expect(emailButtons).toHaveCount(1);
46
- });
47
-
48
- test('should show tooltip on email hover', async ({ page }) => {
49
- // Intercept the GraphQL request and mock the response
50
- await page.route('**/v1/graphql', mockPaginationGraphQL);
51
-
52
- // Navigate to the simple test view
53
- await page.goto('/?test-view=simple-test-view');
54
-
55
- // Wait for the table to be present and visible
56
- const table = page.getByRole('table');
57
- await expect(table).toBeVisible();
58
-
59
- // Find the first email button
60
- const emailButton = table.locator('td button').filter({ hasText: '@' }).first();
61
- await expect(emailButton).toBeVisible();
62
-
63
- // Check for title attribute (tooltip)
64
- const title = await emailButton.getAttribute('title');
65
- expect(title).toMatch(/Filter by email:/);
66
- });
67
- });
@@ -1,171 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- test.describe('Simple View Transform Functionality', () => {
5
-
6
- test('should apply transform functions when filtering by amount', async ({ page }) => {
7
- // Intercept the GraphQL request and mock the response
8
- await page.route('**/v1/graphql', mockPaginationGraphQL);
9
-
10
- // Navigate to the page with the simple test view
11
- await page.goto('/?test-view=simple-test-view');
12
-
13
- // Wait for the table to be present and visible
14
- const table = page.getByRole('table');
15
- await expect(table).toBeVisible();
16
-
17
- // Verify all rows are initially visible
18
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
19
- await expect(table.getByText('Test 29', { exact: true })).toBeVisible();
20
- await expect(table.getByText('Test 28', { exact: true })).toBeVisible();
21
- await expect(table.getByText('Test 27', { exact: true })).toBeVisible();
22
- await expect(table.getByText('Test 26', { exact: true })).toBeVisible();
23
- await expect(table.getByText('Test 25', { exact: true })).toBeVisible();
24
- await expect(table.getByText('$300', { exact: true })).toBeVisible(); // amount for Test 30
25
- await expect(table.getByText('$290', { exact: true })).toBeVisible(); // amount for Test 29
26
- await expect(table.getByText('$280', { exact: true })).toBeVisible(); // amount for Test 28
27
- await expect(table.getByText('$270', { exact: true })).toBeVisible(); // amount for Test 27
28
- await expect(table.getByText('$260', { exact: true })).toBeVisible(); // amount for Test 26
29
- await expect(table.getByText('$250', { exact: true })).toBeVisible(); // amount for Test 25
30
-
31
- // Show filters first
32
- await page.getByText('Filters', { exact: true }).click();
33
-
34
- // Find the amount filter input
35
- const amountLabel = page.getByText('Amount', { exact: true });
36
- const amountInput = amountLabel.locator('..').locator('~ div input');
37
-
38
- // Enter 255 in the input field
39
- // With transform: toQuery adds 5, so 255 becomes 260 in the query
40
- // This should show only rows with amount >= 260 (Test 26, 27, 28, 29, 30)
41
- await amountInput.fill('255');
42
- await amountInput.press('Enter');
43
-
44
- // Wait for filtering to complete and verify results
45
- // These should still be visible (amount >= 260)
46
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
47
- await expect(table.getByText('Test 29', { exact: true })).toBeVisible();
48
- await expect(table.getByText('Test 28', { exact: true })).toBeVisible();
49
- await expect(table.getByText('Test 27', { exact: true })).toBeVisible();
50
- await expect(table.getByText('Test 26', { exact: true })).toBeVisible();
51
- await expect(table.getByText('$300', { exact: true })).toBeVisible();
52
- await expect(table.getByText('$290', { exact: true })).toBeVisible();
53
- await expect(table.getByText('$280', { exact: true })).toBeVisible();
54
- await expect(table.getByText('$270', { exact: true })).toBeVisible();
55
- await expect(table.getByText('$260', { exact: true })).toBeVisible();
56
-
57
- // These should not be visible (amount < 260)
58
- await expect(table.getByText('Test 25', { exact: true })).not.toBeVisible();
59
- await expect(table.getByText('Test 24', { exact: true })).not.toBeVisible();
60
- await expect(table.getByText('Test 23', { exact: true })).not.toBeVisible();
61
- await expect(table.getByText('$250', { exact: true })).not.toBeVisible();
62
- await expect(table.getByText('$240', { exact: true })).not.toBeVisible();
63
- await expect(table.getByText('$230', { exact: true })).not.toBeVisible();
64
- });
65
-
66
- test('should handle multiple filter value changes with transforms', async ({ page }) => {
67
- // Intercept the GraphQL request and mock the response
68
- await page.route('**/v1/graphql', mockPaginationGraphQL);
69
-
70
- // Navigate to the page with the simple test view
71
- await page.goto('/?test-view=simple-test-view');
72
-
73
- // Wait for the table to be present and visible
74
- const table = page.getByRole('table');
75
- await expect(table).toBeVisible();
76
-
77
- // Show filters first
78
- await page.getByText('Filters', { exact: true }).click();
79
-
80
- // Find the amount filter input
81
- const amountLabel = page.getByText('Amount', { exact: true });
82
- const amountInput = amountLabel.locator('..').locator('~ div input');
83
-
84
- // Test 1: Enter 245 (transforms to 250), should show Test 25 and up
85
- await amountInput.fill('245');
86
- await amountInput.press('Enter');
87
-
88
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
89
- await expect(table.getByText('Test 25', { exact: true })).toBeVisible();
90
- await expect(table.getByText('Test 24', { exact: true })).not.toBeVisible();
91
-
92
- // Test 2: Change to 265 (transforms to 270), should show Test 27 and up
93
- await amountInput.clear();
94
- await amountInput.fill('265');
95
- await amountInput.press('Enter');
96
-
97
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
98
- await expect(table.getByText('Test 27', { exact: true })).toBeVisible();
99
- await expect(table.getByText('Test 26', { exact: true })).not.toBeVisible();
100
- await expect(table.getByText('Test 25', { exact: true })).not.toBeVisible();
101
-
102
- // Test 3: Clear filter should show all items again
103
- await amountInput.clear();
104
- await amountInput.press('Enter');
105
-
106
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
107
- await expect(table.getByText('Test 25', { exact: true })).toBeVisible();
108
- await expect(table.getByText('Test 24', { exact: true })).toBeVisible();
109
- });
110
-
111
- test('should handle key-value transform objects', async ({ page }) => {
112
- // Intercept the GraphQL request and mock the response
113
- await page.route('**/v1/graphql', mockPaginationGraphQL);
114
-
115
- // Navigate to the page with the simple test view
116
- await page.goto('/?test-view=simple-test-view');
117
-
118
- // Wait for the table to be present and visible
119
- const table = page.getByRole('table');
120
- await expect(table).toBeVisible();
121
-
122
- // Verify all rows are initially visible
123
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
124
- await expect(table.getByText('Test 29', { exact: true })).toBeVisible();
125
-
126
- // Show filters first
127
- await page.getByText('Filters', { exact: true }).click();
128
-
129
- // Find the extra filters panel
130
- const extraFiltersPanel = page.locator('.p-panel-header', { hasText: 'Extra Filters' });
131
- await expect(extraFiltersPanel).toBeVisible();
132
-
133
- // Expand the extra filters panel if needed
134
- if (await extraFiltersPanel.getAttribute('aria-expanded') !== 'true') {
135
- await extraFiltersPanel.click();
136
- }
137
-
138
- // Find the key-value transform filter input
139
- const keyValueLabel = page.getByText('Test Field (Key-Value Transform)', { exact: true });
140
- await expect(keyValueLabel).toBeVisible();
141
-
142
- const keyValueInput = keyValueLabel.locator('..').locator('~ div input');
143
- await expect(keyValueInput).toBeVisible();
144
-
145
- // Test 1: Enter a value that should be transformed
146
- // The transform should add "prefix_" to the input and change the field to "transformedField"
147
- await keyValueInput.fill('30');
148
- await keyValueInput.press('Enter');
149
-
150
- // Wait a bit for the filter to apply
151
- await page.waitForTimeout(2000);
152
-
153
- // Verify the correct row is shown (Test 30 should be visible since it matches the transformed query)
154
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
155
- // Verify other rows are hidden
156
- await expect(table.getByText('Test 29', { exact: true })).not.toBeVisible();
157
-
158
- // Test 2: Clear the filter to verify all rows show again
159
- await keyValueInput.clear();
160
- await keyValueInput.press('Enter');
161
-
162
- // Wait for the filter to clear
163
- await page.waitForTimeout(1000);
164
-
165
- // All rows should be visible again
166
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
167
- await expect(table.getByText('Test 29', { exact: true })).toBeVisible();
168
- await expect(table.getByText('Test 28', { exact: true })).toBeVisible();
169
- });
170
-
171
- });
@@ -1,104 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- test.describe('Simple View Rendering', () => {
5
-
6
- test('should filter by phone using a custom filter component', async ({ page }) => {
7
- // Intercept the GraphQL request and mock the response
8
- await page.route('**/v1/graphql', mockPaginationGraphQL);
9
-
10
- // Navigate to the page with the simple test view
11
- await page.goto('/?test-view=simple-test-view');
12
-
13
- // Wait for the table to be present and visible
14
- const table = page.getByRole('table');
15
- await expect(table).toBeVisible();
16
-
17
- // Show filters first
18
- await page.getByText('Filters', { exact: true }).click();
19
-
20
- // Find the phone filter input (by placeholder or input type)
21
- const phoneInput = page.locator('input[placeholder="Phone number"]');
22
-
23
- const phoneNumber = '+46700000025';
24
- await phoneInput.fill(phoneNumber);
25
-
26
- // Submit the filter form (by aria-label)
27
- await page.getByLabel('Apply filter').click();
28
-
29
- // Wait for the table to update and check that results are filtered
30
- await expect(table.getByText(phoneNumber)).toBeVisible();
31
- });
32
- test('should render a view with a single column header and data', async ({ page }) => {
33
- // Intercept the GraphQL request and mock the response
34
- await page.route('**/v1/graphql', mockPaginationGraphQL);
35
-
36
- // Navigate to the page with the simple test view
37
- await page.goto('/?test-view=simple-test-view');
38
-
39
- // Wait for the table to be present and visible
40
- const table = page.getByRole('table');
41
- await expect(table).toBeVisible();
42
-
43
- // Get the expected header text from the simple test view JSON (first column name)
44
- const expectedHeaderText = "Test Column Header";
45
-
46
- // Locate the column header by its text content
47
- const columnHeader = table.getByText(expectedHeaderText, { exact: true });
48
-
49
- // Assert that the column header is visible
50
- await expect(columnHeader).toBeVisible();
51
-
52
- // Assert that all rows are visible before applying the filter
53
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
54
- await expect(table.getByText('Test 29', { exact: true })).toBeVisible();
55
- await expect(table.getByText('Test 28', { exact: true })).toBeVisible();
56
- await expect(table.getByText('Test 27', { exact: true })).toBeVisible();
57
- await expect(table.getByText('Test 25', { exact: true })).toBeVisible();
58
- await expect(table.getByText('Test 24', { exact: true })).toBeVisible();
59
- await expect(table.getByText('$300', { exact: true })).toBeVisible();
60
- await expect(table.getByText('$290', { exact: true })).toBeVisible();
61
- await expect(table.getByText('$280', { exact: true })).toBeVisible();
62
- await expect(table.getByText('$270', { exact: true })).toBeVisible();
63
- await expect(table.getByText('$250', { exact: true })).toBeVisible();
64
- await expect(table.getByText('$240', { exact: true })).toBeVisible();
65
-
66
- // Show filters first
67
- await page.getByText('Filters', { exact: true }).click();
68
-
69
- // Use the filter to only show rows with amount >= 30
70
- // Find the Amount label, then its parent, then the sibling div, then the input inside
71
- const amountLabel = page.getByText('Amount', { exact: true });
72
- const amountInput = amountLabel.locator('..').locator('~ div input');
73
- await amountInput.fill('260');
74
- await amountInput.press('Enter');
75
-
76
- // Assert that only the filtered rows are visible
77
- await expect(table.getByText('Test 30', { exact: true })).toBeVisible();
78
- await expect(table.getByText('Test 27', { exact: true })).toBeVisible();
79
- await expect(table.getByText('Test 25', { exact: true })).not.toBeVisible();
80
- await expect(table.getByText('Test 24', { exact: true })).not.toBeVisible();
81
- });
82
-
83
- test('should render filter group captions in the filter form', async ({ page }) => {
84
- // Intercept the GraphQL request and mock the response
85
- await page.route('**/v1/graphql', mockPaginationGraphQL);
86
-
87
- // Navigate to the page with the simple test view
88
- await page.goto('/?test-view=simple-test-view');
89
-
90
- // Show filters first
91
- await page.getByText('Filters', { exact: true }).click();
92
-
93
- // Wait for the filter form to be present
94
- const filterForm = page.locator('form');
95
- await expect(filterForm).toBeVisible();
96
-
97
- // Check for the presence of the new group label ("Extra Filters") as a Panel header
98
- const extraFiltersPanel = page.locator('.p-panel-header', { hasText: 'Extra Filters' });
99
- await expect(extraFiltersPanel).toBeVisible();
100
-
101
- // Check that the filter label is present under the new group
102
- await expect(page.getByText('Test Field', { exact: true })).toBeVisible();
103
- });
104
- });
@@ -1,108 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import { mockPaginationGraphQL } from './graphqlMock';
3
-
4
- test.describe('Transform Regression Tests', () => {
5
-
6
- test('should preserve display value after applying transform', async ({ page }) => {
7
- // Intercept the GraphQL request and mock the response
8
- await page.route('**/v1/graphql', mockPaginationGraphQL);
9
-
10
- // Navigate to the page with the simple test view
11
- await page.goto('/?test-view=simple-test-view');
12
-
13
- // Wait for the table to be present and visible
14
- const table = page.getByRole('table');
15
- await expect(table).toBeVisible();
16
-
17
- // Show filters first
18
- await page.getByText('Filters', { exact: true }).click();
19
-
20
- // Find the amount filter input
21
- const amountLabel = page.getByText('Amount', { exact: true });
22
- const amountInput = amountLabel.locator('..').locator('~ div input');
23
-
24
- // Enter 255 in the input field
25
- // With transform: toQuery adds 5, so 255 becomes 260 in the query
26
- // Display should remain 255 (the user's input)
27
- await amountInput.fill('255');
28
-
29
- // Apply the filter
30
- await page.getByRole('button', { name: 'Apply filter' }).click();
31
-
32
- // Wait for the filter to be applied
33
- await page.waitForTimeout(100);
34
-
35
- // Check that the input still shows the original value (255) after applying the transform
36
- // This is the regression test - it should show the original user input
37
- await expect(amountInput).toHaveValue('255');
38
- });
39
-
40
- test('should correctly apply toQuery transforms', async ({ page }) => {
41
- // Intercept the GraphQL request and mock the response
42
- await page.route('**/v1/graphql', mockPaginationGraphQL);
43
-
44
- // Navigate to the page with the simple test view
45
- await page.goto('/?test-view=simple-test-view');
46
-
47
- // Wait for the table to be present and visible
48
- const table = page.getByRole('table');
49
- await expect(table).toBeVisible();
50
-
51
- // Show filters first
52
- await page.getByText('Filters', { exact: true }).click();
53
-
54
- // Find the amount filter input
55
- const amountLabel = page.getByText('Amount', { exact: true });
56
- const amountInput = amountLabel.locator('..').locator('~ div input');
57
-
58
- // Test multiple values to ensure the transform roundtrip works correctly
59
- const testValues = ['100', '255', '300'];
60
-
61
- for (const testValue of testValues) {
62
- // Clear and enter the test value
63
- await amountInput.fill('');
64
- await amountInput.fill(testValue);
65
-
66
- // Apply the filter
67
- await page.getByRole('button', { name: 'Apply filter' }).click();
68
-
69
- // Wait for the filter to be applied
70
- await page.waitForTimeout(100);
71
-
72
- // Verify the input still shows the original value
73
- await expect(amountInput).toHaveValue(testValue);
74
- }
75
- });
76
-
77
- test('should handle empty values correctly with transforms', async ({ page }) => {
78
- // Intercept the GraphQL request and mock the response
79
- await page.route('**/v1/graphql', mockPaginationGraphQL);
80
-
81
- // Navigate to the page with the simple test view
82
- await page.goto('/?test-view=simple-test-view');
83
-
84
- // Wait for the table to be present and visible
85
- const table = page.getByRole('table');
86
- await expect(table).toBeVisible();
87
-
88
- // Show filters first
89
- await page.getByText('Filters', { exact: true }).click();
90
-
91
- // Find the amount filter input
92
- const amountLabel = page.getByText('Amount', { exact: true });
93
- const amountInput = amountLabel.locator('..').locator('~ div input');
94
-
95
- // Enter a value, then clear it
96
- await amountInput.fill('255');
97
- await page.getByRole('button', { name: 'Apply filter' }).click();
98
- await page.waitForTimeout(100);
99
-
100
- // Clear the input
101
- await amountInput.fill('');
102
- await page.getByRole('button', { name: 'Apply filter' }).click();
103
- await page.waitForTimeout(100);
104
-
105
- // Verify the input remains empty
106
- await expect(amountInput).toHaveValue('');
107
- });
108
- });
package/eslint.config.js DELETED
@@ -1,30 +0,0 @@
1
- import js from '@eslint/js'
2
- import globals from 'globals'
3
- import reactHooks from 'eslint-plugin-react-hooks'
4
- import reactRefresh from 'eslint-plugin-react-refresh'
5
- import tseslint from 'typescript-eslint'
6
-
7
- export default tseslint.config(
8
- { ignores: ['dist'] },
9
- {
10
- extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
- files: ['**/*.{ts,tsx}'],
12
- languageOptions: {
13
- ecmaVersion: 2020,
14
- globals: globals.browser,
15
- },
16
- plugins: {
17
- 'react-hooks': reactHooks,
18
- 'react-refresh': reactRefresh,
19
- },
20
- rules: {
21
- ...reactHooks.configs.recommended.rules,
22
- 'react-refresh/only-export-components': [
23
- 'warn',
24
- { allowConstantExport: true },
25
- ],
26
- '@typescript-eslint/no-explicit-any': 'off',
27
- 'indent': ['error', 4, { 'SwitchCase': 1 }],
28
- },
29
- },
30
- )