2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-12-15 16:58:14 +00:00

Merge branch 'generic-parameters' of https://github.com/schrodingersgat/inventree into pr/SchrodingersGat/10699

This commit is contained in:
Matthias Mair
2025-11-26 13:08:55 +01:00
4 changed files with 136 additions and 109 deletions

View File

@@ -768,6 +768,9 @@ class ContentTypeField(serializers.ChoiceField):
content_type = None
if data in ['', None]:
return None
# First, try to resolve the content type via direct pk value
try:
content_type_id = int(data)

View File

@@ -182,7 +182,14 @@ test('Parts - Locking', async ({ browser }) => {
.waitFor();
await loadTab(page, 'Parameters');
await page.getByLabel('action-button-add-parameter').waitFor();
await page
.getByRole('button', { name: 'action-menu-add-parameters' })
.click();
await page
.getByRole('menuitem', {
name: 'action-menu-add-parameters-create-parameter'
})
.click();
// Navigate to a known assembly which *is* locked
await navigate(page, 'part/100/bom');
@@ -495,7 +502,14 @@ test('Parts - Parameters', async ({ browser }) => {
const page = await doCachedLogin(browser, { url: 'part/69/parameters' });
// Create a new template
await page.getByLabel('action-button-add-parameter').click();
await page
.getByRole('button', { name: 'action-menu-add-parameters' })
.click();
await page
.getByRole('menuitem', {
name: 'action-menu-add-parameters-create-parameter'
})
.click();
// Select the "Color" parameter template (should create a "choice" field)
await page.getByLabel('related-field-template').fill('Color');
@@ -509,7 +523,7 @@ test('Parts - Parameters', async ({ browser }) => {
// Select the "polarized" parameter template (should create a "checkbox" field)
await page.getByLabel('related-field-template').fill('Polarized');
await page.getByText('Is this part polarized?').click();
await page.getByRole('option', { name: 'Polarized Is this part' }).click();
// Submit with "false" value
await page.getByRole('button', { name: 'Submit' }).click();
@@ -538,15 +552,19 @@ test('Parts - Parameters', async ({ browser }) => {
// Finally, delete the parameter
await row.getByLabel(/row-action-menu-/i).click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete', exact: true }).click();
await page.getByText('No records found').first().waitFor();
});
test('Parts - Parameter Filtering', async ({ browser }) => {
const page = await doCachedLogin(browser, { url: 'part/' });
await loadTab(page, 'Part Parameters');
await loadTab(page, 'Parts', true);
await page
.getByRole('button', { name: 'segmented-icon-control-parametric' })
.click();
await clearTableFilters(page);
// All parts should be available (no filters applied)

View File

@@ -254,7 +254,7 @@ test('Settings - Admin', async ({ browser }) => {
await loadTab(page, 'Currencies');
await loadTab(page, 'Project Codes');
await loadTab(page, 'Custom Units');
await loadTab(page, 'Part Parameters');
await loadTab(page, 'Parameters', true);
await loadTab(page, 'Category Parameters');
await loadTab(page, 'Label Templates');
await loadTab(page, 'Report Templates');
@@ -373,6 +373,115 @@ test('Settings - Admin - Barcode History', async ({ browser }) => {
});
});
test('Settings - Admin - Parameter', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'admin',
password: 'inventree'
});
await page.getByRole('button', { name: 'admin' }).click();
await page.getByRole('menuitem', { name: 'Admin Center' }).click();
await loadTab(page, 'Parameters', true);
await page.waitForTimeout(1000);
await page.waitForLoadState('networkidle');
// Clean old template data if exists
await page
.getByRole('cell', { name: 'my custom parameter' })
.waitFor({ timeout: 500 })
.then(async (cell) => {
await page
.getByRole('cell', { name: 'my custom parameter' })
.locator('..')
.getByLabel('row-action-menu-')
.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
})
.catch(() => {});
await page.getByRole('button', { name: 'Selection Lists' }).click();
// Allow time for the table to load
await page.waitForTimeout(1000);
await page.waitForLoadState('networkidle');
// Clean old list data if exists
await page
.getByRole('cell', { name: 'some list' })
.waitFor({ timeout: 500 })
.then(async (cell) => {
await page
.getByRole('cell', { name: 'some list' })
.locator('..')
.getByLabel('row-action-menu-')
.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
})
.catch(() => {});
// Add selection list
await page.getByLabel('action-button-add-selection-').waitFor();
await page.getByLabel('action-button-add-selection-').click();
await page.getByLabel('text-field-name').fill('some list');
await page.getByLabel('text-field-description').fill('Listdescription');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('cell', { name: 'some list' }).waitFor();
await page.getByLabel('action-button-add-parameter').waitFor();
await page.getByLabel('action-button-add-parameter').click();
await page.getByLabel('text-field-name').fill('my custom parameter');
await page.getByLabel('text-field-description').fill('description');
await page
.locator('div')
.filter({ hasText: /^Search\.\.\.$/ })
.nth(2)
.click();
await page
.getByRole('option', { name: 'some list' })
.locator('div')
.first()
.click();
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('cell', { name: 'my custom parameter' }).click();
// Fill parameter
await navigate(page, 'part/104/parameters/');
await page.getByLabel('Parameters').getByText('Parameters').waitFor();
await page.waitForLoadState('networkidle');
await page
.getByRole('button', { name: 'action-menu-add-parameters' })
.click();
await page
.getByRole('menuitem', {
name: 'action-menu-add-parameters-create-parameter'
})
.click();
await page.waitForTimeout(500);
await page.getByText('Add Parameter').waitFor();
await page
.getByText('Template *Parameter')
.locator('div')
.filter({ hasText: /^Search\.\.\.$/ })
.first()
.click();
await page
.getByText('Template *Parameter')
.locator('div')
.filter({ hasText: /^Search\.\.\.$/ })
.locator('input')
.fill('my custom parameter');
await page.getByRole('option', { name: 'my custom parameter' }).click();
await page.getByLabel('choice-field-data').fill('2');
await page.getByRole('button', { name: 'Submit' }).click();
await page.waitForTimeout(2500);
});
test('Settings - Admin - Unauthorized', async ({ browser }) => {
// Try to access "admin" page with a non-staff user
const page = await doCachedLogin(browser, {

View File

@@ -1,103 +0,0 @@
import { test } from '../baseFixtures';
import { navigate } from '../helpers';
import { doCachedLogin } from '../login';
test('PUI - Admin - Parameter', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'admin',
password: 'inventree'
});
await page.getByRole('button', { name: 'admin' }).click();
await page.getByRole('menuitem', { name: 'Admin Center' }).click();
await page.getByRole('tab', { name: 'Part Parameters' }).click();
await page.getByRole('button', { name: 'Selection Lists' }).click();
await page.waitForLoadState('networkidle');
// clean old data if exists
await page
.getByRole('cell', { name: 'some list' })
.waitFor({ timeout: 200 })
.then(async (cell) => {
await page
.getByRole('cell', { name: 'some list' })
.locator('..')
.getByLabel('row-action-menu-')
.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
})
.catch(() => {});
// clean old data if exists
await page.getByRole('button', { name: 'Part Parameter Template' }).click();
await page.waitForLoadState('networkidle');
await page
.getByRole('cell', { name: 'my custom parameter' })
.waitFor({ timeout: 200 })
.then(async (cell) => {
await page
.getByRole('cell', { name: 'my custom parameter' })
.locator('..')
.getByLabel('row-action-menu-')
.click();
await page.getByRole('menuitem', { name: 'Delete' }).click();
await page.getByRole('button', { name: 'Delete' }).click();
})
.catch(() => {});
// Add selection list
await page.getByRole('button', { name: 'Selection Lists' }).click();
await page.waitForLoadState('networkidle');
await page.getByLabel('action-button-add-selection-').waitFor();
await page.getByLabel('action-button-add-selection-').click();
await page.getByLabel('text-field-name').fill('some list');
await page.getByLabel('text-field-description').fill('Listdescription');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('cell', { name: 'some list' }).waitFor();
await page.waitForTimeout(200);
// Add parameter
await page.waitForLoadState('networkidle');
await page.getByRole('button', { name: 'Part Parameter Template' }).click();
await page.getByLabel('action-button-add-parameter').waitFor();
await page.getByLabel('action-button-add-parameter').click();
await page.getByLabel('text-field-name').fill('my custom parameter');
await page.getByLabel('text-field-description').fill('description');
await page
.locator('div')
.filter({ hasText: /^Search\.\.\.$/ })
.nth(2)
.click();
await page
.getByRole('option', { name: 'some list' })
.locator('div')
.first()
.click();
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByRole('cell', { name: 'my custom parameter' }).click();
// Fill parameter
await navigate(page, 'part/104/parameters/');
await page.getByLabel('Parameters').getByText('Parameters').waitFor();
await page.waitForLoadState('networkidle');
await page.getByLabel('action-button-add-parameter').waitFor();
await page.getByLabel('action-button-add-parameter').click();
await page.waitForTimeout(200);
await page.getByText('New Part Parameter').waitFor();
await page
.getByText('Template *Parameter')
.locator('div')
.filter({ hasText: /^Search\.\.\.$/ })
.first()
.click();
await page
.getByText('Template *Parameter')
.locator('div')
.filter({ hasText: /^Search\.\.\.$/ })
.locator('input')
.fill('my custom parameter');
await page.getByRole('option', { name: 'my custom parameter' }).click();
await page.getByLabel('choice-field-data').fill('2');
await page.getByRole('button', { name: 'Submit' }).click();
});