diff --git a/.github/ISSUE_TEMPLATE/app_issue.md b/.github/ISSUE_TEMPLATE/app_issue.md new file mode 100644 index 0000000000..e71861394c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/app_issue.md @@ -0,0 +1,30 @@ +--- +name: App issue +about: Report a bug or issue with the InvenTree app +title: "[APP] Enter bug description" +labels: bug, app +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of the bug or issue + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to ... +2. Select ... +3. ... + +**Expected Behavior** +A clear and concise description of what you expected to happen + +**Screenshots** +If applicable, add screenshots to help explain your problem + +**Version Information** + +- App platform: *Select iOS or Android* +- App version: *Enter app version* +- Server version: *Enter server version* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4af3fc5386..0677e61de4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,22 +1,102 @@ -Contributions to InvenTree are welcomed - please follow the guidelines below. +Please read the contribution guidelines below, before submitting your first pull request to the InvenTree codebase. -## Feature Branches +## Branches and Versioning -No pushing to master! New featues must be submitted in a separate branch (one branch per feature). +InvenTree roughly follow the [GitLab flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html) branching style, to allow simple management of multiple tagged releases, short-lived branches, and development on the main branch. -## Include Migration Files +### Version Numbering + +InvenTree version numbering follows the [semantic versioning](https://semver.org/) specification. + +### Master Branch + +The HEAD of the "main" or "master" branch of InvenTree represents the current "latest" state of code development. + +- All feature branches are merged into master +- All bug fixes are merged into master + +**No pushing to master:** New featues must be submitted as a pull request from a separate branch (one branch per feature). + +#### Feature Branches + +Feature branches should be branched *from* the *master* branch. + +- One major feature per branch / pull request +- Feature pull requests are merged back *into* the master branch +- Features *may* also be merged into a release candidate branch + +### Stable Branch + +The HEAD of the "stable" branch represents the latest stable release code. + +- Versioned releases are merged into the "stable" branch +- Bug fix branches are made *from* the "stable" branch + +#### Release Candidate Branches + +- Release candidate branches are made from master, and merged into stable. +- RC branches are targetted at a major/minor version e.g. "0.5" +- When a release candidate branch is merged into *stable*, the release is tagged + +#### Bugfix Branches + +- If a bug is discovered in a tagged release version of InvenTree, a "bugfix" or "hotfix" branch should be made *from* that tagged release +- When approved, the branch is merged back *into* stable, with an incremented PATCH number (e.g. 0.4.1 -> 0.4.2) +- The bugfix *must* also be cherry picked into the *master* branch. + +## Migration Files Any required migration files **must** be included in the commit, or the pull-request will be rejected. If you change the underlying database schema, make sure you run `invoke migrate` and commit the migration files before submitting the PR. +*Note: A github action checks for unstaged migration files and will reject the PR if it finds any!* -## Testing +## Unit Testing -Any new code should be covered by unit tests - a submitted PR may not be accepted if the code coverage is decreased. +Any new code should be covered by unit tests - a submitted PR may not be accepted if the code coverage for any new features is insufficient, or the overall code coverage is decreased. + +The InvenTree code base makes use of [GitHub actions](https://github.com/features/actions) to run a suite of automated tests against the code base every time a new pull request is received. These actions include (but are not limited to): + +- Checking Python and Javascript code against standard style guides +- Running unit test suite +- Automated building and pushing of docker images +- Generating translation files + +The various github actions can be found in the `./github/workflows` directory + +## Code Style + +Sumbitted Python code is automatically checked against PEP style guidelines. Locally you can run `invoke style` to ensure the style checks will pass, before submitting the PR. ## Documentation New features or updates to existing features should be accompanied by user documentation. A PR with associated documentation should link to the matching PR at https://github.com/inventree/inventree-docs/ -## Code Style +## Translations -Sumbitted Python code is automatically checked against PEP style guidelines. Locally you can run `invoke style` to ensure the style checks will pass, before submitting the PR. +Any user-facing strings *must* be passed through the translation engine. + +- InvenTree code is written in English +- User translatable strings are provided in English as the primary language +- Secondary language translations are provided [via Crowdin](https://crowdin.com/project/inventree) + +*Note: Translation files are updated via GitHub actions - you do not need to compile translations files before submitting a pull request!* + +### Python Code + +For strings exposed via Python code, use the following format: + +```python +from django.utils.translation import ugettext_lazy as _ + +user_facing_string = _('This string will be exposed to the translation engine!') +``` + +### Templated Strings + +HTML and javascript files are passed through the django templating engine. Translatable strings are implemented as follows: + +```html +{% load i18n %} + +{% trans "This string will be translated" %} - this string will not! +``` \ No newline at end of file diff --git a/InvenTree/part/test_api.py b/InvenTree/part/test_api.py index ebef21b84b..660b573e33 100644 --- a/InvenTree/part/test_api.py +++ b/InvenTree/part/test_api.py @@ -588,6 +588,27 @@ class PartAPITest(InvenTreeAPITestCase): self.assertEqual(new_part.supplier_parts.count(), 1) self.assertEqual(new_part.manufacturer_parts.count(), 1) + def test_strange_chars(self): + """ + Test that non-standard ASCII chars are accepted + """ + + url = reverse('api-part-list') + + name = "Kaltgerätestecker" + description = "Gerät" + + data = { + "name": name, + "description": description, + "category": 2 + } + + response = self.post(url, data, expected_code=201) + + self.assertEqual(response.data['name'], name) + self.assertEqual(response.data['description'], description) + class PartDetailTests(InvenTreeAPITestCase): """ diff --git a/InvenTree/templates/js/translated/modals.js b/InvenTree/templates/js/translated/modals.js index 5195c67b46..96e41fd6ec 100644 --- a/InvenTree/templates/js/translated/modals.js +++ b/InvenTree/templates/js/translated/modals.js @@ -793,14 +793,25 @@ function attachSecondaries(modal, secondaries) { function insertActionButton(modal, options) { /* Insert a custom submission button */ - var html = ` - - - `; + var element = $(modal).find('#modal-footer-buttons'); - $(modal).find('#modal-footer-buttons').append(html); + // check if button already present + var already_present = false; + for (var child=element[0].firstElementChild; child; child=child.nextElementSibling) { + if (item.firstElementChild.name == options.name) { + already_present = true; + } + } + + if (already_present == false) { + var html = ` + + + `; + element.append(html); + } } function attachButtons(modal, buttons) {