mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 13:15:43 +00:00 
			
		
		
		
	[UI] Reimplement calendar views (#8933)
* Add deps for @fullcalendar * Basic calendar setup * Add locale support * Add custom <SegmentedIconControl> component * optional 'control' for panel * Scaffolding out build index page * Fetch build orders based on calendar dates * Display builds * Click to navigate to build * Working on custom header * Implement button functionality * Display current month name * Implement datepicker dropdown * Adjust layout * Custom rendering * Include part detail * Implement hook to track calendar state * Clearing search causes immediate update * Offload core functionality into hook - Adds search input * Spread props correctly * Cleanup * Allow build orders to be edited directly from calendar view * Cleanup * Fix for InvenTreeCalendarProps * Improve date range filtering for Build model * Simplify BuildFilter * Refactoring * PurchaseOrder calendar implementation * Allow edit of purchase orders * Refactor and implement for all order types - Add missing "issue_date" field for SalesOrder - Refactor API for other order types - Fix rendering issues * Bump API version * Add playwright tests for calendar (simple) * Fix migrations * Simplify notifications * Refactor filter components - Make them more generic * Enable custom filters for calendars * Custom filters per table * Display status label * Refactoring * Update playwright tests * Update build order docs * Bug fix for order date editing * Update purchase order docs * Return Order docs * Update date formatting
This commit is contained in:
		| @@ -101,6 +101,18 @@ export const loadTab = async (page, tabName) => { | ||||
|   await page.waitForLoadState('networkidle'); | ||||
| }; | ||||
|  | ||||
| // Activate "table" view in certain contexts | ||||
| export const activateTableView = async (page) => { | ||||
|   await page.getByLabel('segmented-icon-control-table').click(); | ||||
|   await page.waitForLoadState('networkidle'); | ||||
| }; | ||||
|  | ||||
| // Activate "calendar" view in certain contexts | ||||
| export const activateCalendarView = async (page) => { | ||||
|   await page.getByLabel('segmented-icon-control-calendar').click(); | ||||
|   await page.waitForLoadState('networkidle'); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Perform a 'global search' on the provided page, for the provided query text | ||||
|  */ | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { expect } from '@playwright/test'; | ||||
| import { test } from '../baseFixtures.ts'; | ||||
| import { | ||||
|   activateCalendarView, | ||||
|   clearTableFilters, | ||||
|   getRowFromCell, | ||||
|   loadTab, | ||||
| @@ -90,6 +91,21 @@ test('Build Order - Basic Tests', async ({ page }) => { | ||||
|     .waitFor(); | ||||
| }); | ||||
|  | ||||
| test('Build Order - Calendar', async ({ page }) => { | ||||
|   await doQuickLogin(page); | ||||
|  | ||||
|   await navigate(page, 'manufacturing/index/buildorders'); | ||||
|   await activateCalendarView(page); | ||||
|  | ||||
|   // Check "part category" filter | ||||
|   await page.getByLabel('calendar-select-filters').click(); | ||||
|   await page.getByRole('button', { name: 'Add Filter' }).click(); | ||||
|   await page.getByPlaceholder('Select filter').fill('category'); | ||||
|   await page.getByRole('option', { name: 'Category', exact: true }).click(); | ||||
|   await page.getByLabel('related-field-filter-category').click(); | ||||
|   await page.getByText('Part category, level 1').waitFor(); | ||||
| }); | ||||
|  | ||||
| test('Build Order - Edit', async ({ page }) => { | ||||
|   await doQuickLogin(page); | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| import { expect } from '@playwright/test'; | ||||
| import { test } from '../baseFixtures.ts'; | ||||
| import { | ||||
|   activateCalendarView, | ||||
|   activateTableView, | ||||
|   clearTableFilters, | ||||
|   clickButtonIfVisible, | ||||
|   clickOnRowMenu, | ||||
| @@ -11,11 +13,12 @@ import { | ||||
| } from '../helpers.ts'; | ||||
| import { doQuickLogin } from '../login.ts'; | ||||
|  | ||||
| test('Purchase Orders - List', async ({ page }) => { | ||||
| test('Purchase Orders - Table', async ({ page }) => { | ||||
|   await doQuickLogin(page); | ||||
|  | ||||
|   await page.getByRole('tab', { name: 'Purchasing' }).click(); | ||||
|   await loadTab(page, 'Purchase Orders'); | ||||
|   await activateTableView(page); | ||||
|  | ||||
|   await clearTableFilters(page); | ||||
|  | ||||
| @@ -39,6 +42,30 @@ test('Purchase Orders - List', async ({ page }) => { | ||||
|   await page.getByText('2025-07-17').waitFor(); // Target Date | ||||
| }); | ||||
|  | ||||
| test('Purchase Orders - Calendar', async ({ page }) => { | ||||
|   await doQuickLogin(page); | ||||
|  | ||||
|   await page.getByRole('tab', { name: 'Purchasing' }).click(); | ||||
|   await loadTab(page, 'Purchase Orders'); | ||||
|  | ||||
|   // Ensure view is in "calendar" mode | ||||
|   await activateCalendarView(page); | ||||
|  | ||||
|   // Check for expected components | ||||
|   await page.getByLabel('action-button-previous-month').waitFor(); | ||||
|   await page.getByLabel('action-button-next-month').waitFor(); | ||||
|  | ||||
|   await page.getByLabel('calendar-select-month').click(); | ||||
|   await page.getByRole('button', { name: 'Jan' }).waitFor(); | ||||
|   await page.getByRole('button', { name: 'Feb' }).waitFor(); | ||||
|   await page.getByRole('button', { name: 'Dec' }).click(); | ||||
|  | ||||
|   await page.getByText('December').waitFor(); | ||||
|  | ||||
|   // Put back into table view | ||||
|   await activateTableView(page); | ||||
| }); | ||||
|  | ||||
| test('Purchase Orders - Barcodes', async ({ page }) => { | ||||
|   await doQuickLogin(page); | ||||
|  | ||||
| @@ -157,6 +184,7 @@ test('Purchase Orders - Filters', async ({ page }) => { | ||||
|  | ||||
|   await page.getByRole('tab', { name: 'Purchasing' }).click(); | ||||
|   await loadTab(page, 'Purchase Orders'); | ||||
|   await activateTableView(page); | ||||
|  | ||||
|   // Open filters drawer | ||||
|   await openFilterDrawer(page); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import { expect, test } from './baseFixtures.js'; | ||||
| import { loadTab, navigate } from './helpers.js'; | ||||
| import { activateTableView, loadTab, navigate } from './helpers.js'; | ||||
| import { doQuickLogin } from './login.js'; | ||||
| import { setPluginState } from './settings.js'; | ||||
|  | ||||
| @@ -59,6 +59,7 @@ test('Report Printing', async ({ page }) => { | ||||
|   // Navigate to a specific PurchaseOrder | ||||
|   await page.getByRole('tab', { name: 'Purchasing' }).click(); | ||||
|   await loadTab(page, 'Purchase Orders'); | ||||
|   await activateTableView(page); | ||||
|  | ||||
|   await page.getByRole('cell', { name: 'PO0009' }).click(); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user