Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(admin): add batch updating #157

Merged
merged 60 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
cdf22ad
fix(admin): fix error with strapi v4.8
layaxx Mar 18, 2023
71b60a3
Merge pull request #143 from Fekide/142-bug-cannot-read-properties-of…
sargreal Mar 19, 2023
62e8a25
chore(release): 1.0.1 [skip ci]
semantic-release-bot Mar 19, 2023
c313e27
chore(release): 1.1.2 [skip ci]
semantic-release-bot Mar 19, 2023
c556d3c
chore(release): 1.1.2 [skip ci]
semantic-release-bot Mar 19, 2023
f0249a1
Merge branch 'main' into next
layaxx Mar 19, 2023
32ca027
build(deps-dev): bump multi-semantic-release from 3.0.1 to 3.0.2
dependabot[bot] Mar 20, 2023
83c26d7
Merge pull request #145 from Fekide/dependabot/npm_and_yarn/multi-sem…
sargreal Mar 20, 2023
f12262e
test(e2e): setup e2e tests using cypress
sargreal Mar 15, 2023
7c5ee48
ci(test): create default test environment variables
sargreal Mar 19, 2023
cf96db5
test(cypress): add additional tests for direct and batch translation
sargreal Mar 19, 2023
bd915e3
ci(pr): add copy of env file to pr pipeline
sargreal Mar 19, 2023
dfe4c1b
ci(test): add playground strapi build before test
sargreal Mar 19, 2023
e45aeb7
ci(e2e): move cypress tests to own e2e job
sargreal Mar 20, 2023
1095148
test(e2e): fix failing test with node 14
sargreal Mar 20, 2023
b24f692
test(e2e): add test for auto publish
sargreal Mar 20, 2023
4f107c1
test(e2e): disable ratelimit as tests are sometimes too fast
sargreal Mar 20, 2023
d3c9c9b
test(e2e): wait for server on 0.0.0.0 instead of localhost
sargreal Mar 20, 2023
ba44a12
test(e2e): wait for first uid generate command
sargreal Mar 20, 2023
d576d7e
ci(e2e): add upload action for cypress artifacts
sargreal Mar 20, 2023
d6527bb
test(e2e): fill slug field manually
sargreal Mar 20, 2023
9f95982
ci(e2e): add node version to cypress results
sargreal Mar 20, 2023
9e5246b
ci(e2e): add matrix for strapi versions
sargreal Mar 20, 2023
bf88e10
feat(admin): add batch updating
layaxx Mar 24, 2023
2bd372f
feat(batch-update): add customization options
layaxx Mar 27, 2023
c7d3267
docs(batch-update): add configuration options to README
layaxx Mar 27, 2023
2506054
feat(plugin): optionally regenerate uids after single translation
layaxx Mar 27, 2023
f44b8a4
ci(workflows): restructure workflows to be reusable and remove code d…
sargreal Apr 2, 2023
1c3b9c6
chore(e2e): load environment variables with dotenv
sargreal Apr 2, 2023
e5776b2
chore(e2e): remove unnecessary fixture file
sargreal Apr 2, 2023
edc2d0c
ci(e2e): always upload videos
sargreal Apr 2, 2023
c781446
Merge pull request #141 from Fekide/test/e2e
sargreal Apr 2, 2023
4f1f697
ci(build): fix release job dependencies
sargreal Apr 2, 2023
867d47b
build(deps): playground: remove graphql plugin
sargreal Apr 6, 2023
99a7762
test(e2e): update login command to not use login page
sargreal Apr 6, 2023
dba0ec1
chore(playground): add single type categories-page
sargreal Apr 6, 2023
0039644
test(e2e): add failing test for translating relations in components
sargreal Apr 6, 2023
9599782
fix(direct-translation): issue with translating relations in components
sargreal Apr 6, 2023
4aea538
chore(playground): remove graphql plugin from template
sargreal Apr 6, 2023
e54b751
test(e2e): fix flaky batch translation
sargreal Apr 7, 2023
bf03402
fix(relations): make default behavior translations
sargreal Apr 7, 2023
fc25bc2
ci(github-actions): add action to check files that should be identical
layaxx Apr 8, 2023
7f39047
chore(playground): fix mismatch between package.json and template
layaxx Apr 8, 2023
ce88000
docs(readme): update content
sargreal Apr 9, 2023
79c664c
Merge pull request #171 from Fekide/170-feature-development-automatic…
sargreal Apr 9, 2023
3bb91cc
Merge pull request #169 from Fekide/doc/update
sargreal Apr 9, 2023
beca6f9
Merge pull request #168 from Fekide/161-bug-when-we-use-translator-we…
sargreal Apr 9, 2023
815243a
Merge pull request #167 from Fekide/152-bug-no-correct-direct-transla…
sargreal Apr 9, 2023
ee69a88
chore(release): 1.0.2 [skip ci]
semantic-release-bot Apr 9, 2023
74658b7
chore(release): 1.1.3 [skip ci]
semantic-release-bot Apr 9, 2023
62d2744
chore(release): 1.1.3 [skip ci]
semantic-release-bot Apr 9, 2023
d692ccf
Merge branch 'next' into 109-update-translations
layaxx Apr 16, 2023
27d33f0
Merge branch 'main' into 109-update-translations
layaxx Apr 16, 2023
53baa9b
test(batch-update): add first e2e test for batch updating
layaxx Apr 16, 2023
c9ae544
fix(batch-update): fix error during updating updated-entry entity
layaxx Apr 16, 2023
1cd1d0b
feat(batch-update): group updates by content type
layaxx Apr 16, 2023
8c327e4
refactor(batch-update): change update process
layaxx Jun 2, 2023
3184891
test(batch-update): fix failing e2e test
layaxx Jun 2, 2023
01b987e
refactor(batch-update): improve layout and localization
layaxx Jun 3, 2023
31c5ebc
ci(commitlint): fix parsing of release commit
sargreal Jun 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 7 additions & 37 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,18 @@ on:
- main
- next
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install modules
run: yarn
- name: Run ESLint
run: yarn lint

commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5

lint:
uses: ./.github/workflows/lint.yml
unittest:
strategy:
matrix:
version: [14, 16, 18]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.version }}
cache: 'yarn'
- run: yarn
- run: yarn test
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./plugin/coverage/clover.xml,./providers/deepl/coverage/clover.xml
flags: unittests
name: codecov-umbrella
uses: ./.github/workflows/unittest.yml
e2e:
uses: ./.github/workflows/e2e.yml

release:
needs:
- eslint
- commitlint
- lint
- unittest
- e2e
name: Release
runs-on: ubuntu-latest
steps:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/diff.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
on:
workflow_call:
jobs:
diff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run diff script
run: sh ./scripts/diff.sh
26 changes: 26 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
on:
workflow_call:
jobs:
e2e:
strategy:
matrix:
node: [14, 16, 18]
strapi: [4.6, 4.7, 4.8, 4.9]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: 'yarn'
- run: VERSION=${{ matrix.strapi }} envsubst < playground/templates/template.package.json > playground/package.json
- run: yarn
- run: yarn workspace playground build
- run: yarn workspace playground e2e
- uses: actions/upload-artifact@v3
if: always()
with:
name: cypress results (node=${{ matrix.node }},strapi=${{ matrix.strapi }})
path: |
playground/cypress/videos/*
playground/cypress/screenshots/*
19 changes: 19 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
on:
workflow_call:
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install modules
run: yarn
- name: Run ESLint
run: yarn lint

commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5
42 changes: 7 additions & 35 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,11 @@
name: Pull Request
on: pull_request
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install modules
run: yarn
- name: Run ESLint
run: yarn lint

commitlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v5

lint:
uses: ./.github/workflows/lint.yml
diff:
uses: ./.github/workflows/diff.yml
unittest:
strategy:
matrix:
version: [14, 16, 18]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.version }}
cache: 'yarn'
- run: yarn
- run: yarn test
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./plugin/coverage/clover.xml,./providers/deepl/coverage/clover.xml
flags: unittests
name: codecov-umbrella
uses: ./.github/workflows/unittest.yml
e2e:
uses: ./.github/workflows/e2e.yml
22 changes: 22 additions & 0 deletions .github/workflows/unittest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
on:
workflow_call:
jobs:
unittest:
strategy:
matrix:
version: [14, 16, 18]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.version }}
cache: 'yarn'
- run: yarn
- run: yarn test
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./plugin/coverage/clover.xml,./providers/deepl/coverage/clover.xml,./providers/libretranslate/coverage/clover.xml
flags: unittests
name: codecov-umbrella
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,7 @@ dist
.vscode

build/


**/cypress/videos
**/cypress/screenshots
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
This plugin requires the following, in order to work correctly:

- Strapi v4 (this plugin is not compatible with v3)
- Plugin tested for `v4.6` to `v4.9`
- The plugin **i18n** installed and enabled (`@strapi/plugin-i18n` [[npm](https://www.npmjs.com/package/@strapi/plugin-i18n)])
- The content type to have internationalization enabled (advanced settings in the content type builder)
- In the internationalization settings at least **two** locales
Expand Down Expand Up @@ -92,6 +93,7 @@ module.exports = {
#### Available providers

- [strapi-provider-translate-deepl](https://www.npmjs.com/package/strapi-provider-translate-deepl)
- [strapi-provider-translate-libretranslate](https://www.npmjs.com/package/strapi-provider-translate-libretranslate)

### Configure translation of individual fields/attributes

Expand Down Expand Up @@ -189,6 +191,12 @@ _The related objects are not translated directly, only the relation itself is tr
- the relation goes both ways and would be removed from another object or localization if it was used (the case with oneToOne or oneToMany) -> it is removed
- otherwise the relation is kept

## 🔐 Permissions

Since RBAC was moved to the community edition in Strapi v4.8.0, permissions for endpoints of direct translation, batch translation and api usage can now be granted to other roles than super admins:

![Permissions for Translate plugin](https://github.com/Fekide/strapi-plugin-deepl/blob/main/assets/permissions.png)

## 🧑‍💻 Creating your own translation provider

A translation provider should have the following:
Expand Down Expand Up @@ -270,5 +278,4 @@ return providerClient.translateTexts(texts)
## ⚠ Limitations:

- The translation of Markdown and HTML may vary between different providers
- **Only super admins can translate**. This is currently the case, since permissions were added to the `translate` endpoint. Probably you can change the permissions with an enterprise subscription but I am not sure. If you know how to do that also in the community edition please tell me or open a merge request!
- Relations that do not have a translation of the desired locale will not be translated. To keep the relation you will need to translate both in succession (Behaviour for multi-relations has not yet been analyzed)
Binary file added assets/permissions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"husky": "^8.0.1",
"jest": "^29.4.1",
"lint-staged": "^13.2.0",
"multi-semantic-release": "^3.0.1",
"multi-semantic-release": "^3.0.2",
"semantic-release": "^19.0.5"
},
"config": {
Expand Down
6 changes: 6 additions & 0 deletions playground/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ API_TOKEN_SALT=tobemodified
ADMIN_JWT_SECRET=tobemodified
JWT_SECRET=tobemodified
DEEPL_API_KEY=tobemodified
INIT_ADMIN=true
INIT_ADMIN_USERNAME=admin
INIT_ADMIN_PASSWORD=admin
INIT_ADMIN_FIRSTNAME=Admin
INIT_ADMIN_LASTNAME=Admin
INIT_ADMIN_EMAIL=[email protected]
#DEEPL_API_URL=optional
14 changes: 14 additions & 0 deletions playground/.env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
HOST=0.0.0.0
PORT=1337
APP_KEYS="toBeModified1,toBeModified2"
API_TOKEN_SALT=tobemodified
ADMIN_JWT_SECRET=tobemodified
JWT_SECRET=tobemodified
TRANSLATE_PROVIDER=dummy
INIT_ADMIN=true
INIT_ADMIN_USERNAME=admin
INIT_ADMIN_PASSWORD=admin
INIT_ADMIN_FIRSTNAME=Admin
INIT_ADMIN_LASTNAME=Admin
INIT_ADMIN_EMAIL=[email protected]
#DEEPL_API_URL=optional
4 changes: 4 additions & 0 deletions playground/config/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ module.exports = ({ env }) => ({
apiToken: {
salt: env('API_TOKEN_SALT'),
},
rateLimit: {
enabled: false,
},
watchIgnoreFiles: ['./cypress/**/*'],
})
5 changes: 3 additions & 2 deletions playground/config/plugins.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
module.exports = ({ env }) => ({
// ...
translate: {
resolve: "../plugin",
resolve: '../plugin',
enabled: true,
config: {
provider: 'deepl',
provider: env('TRANSLATE_PROVIDER', 'deepl'),
providerOptions: {},
regenerateUids: true,
},
},
// ...
Expand Down
18 changes: 18 additions & 0 deletions playground/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const { defineConfig } = require('cypress')

const dotenv = require('dotenv')

dotenv.config({ path: process.env.ENV_PATH })

module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: `http://${process.env.HOST}:${process.env.PORT}`,
},
env: {
ADMIN_MAIL: process.env.INIT_ADMIN_EMAIL,
ADMIN_PASSWORD: process.env.INIT_ADMIN_PASSWORD,
},
})
93 changes: 93 additions & 0 deletions playground/cypress/e2e/batch-translation.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
describe('batch translation', () => {
beforeEach(() => {
cy.exec('yarn reset')
})

it('should translate all articles', () => {
cy.intercept('/translate/batch-translate').as('batchTranslateExecution')
cy.intercept('/translate/batch-translate/content-types/').as(
'batchTranslateContentTypes'
)

// Login and Navigate to Translate Page
cy.login()
cy.get('nav').contains('Translate').click()

cy.wait('@batchTranslateContentTypes')

// Start batch translation

cy.get('button[data-cy="api::article.article.de.translate"]').focus()
cy.get('button[data-cy="api::article.article.de.translate"]').click()

// Complete dialog
cy.get('div[role=dialog]')
.contains('label', 'Locales')
.invoke('attr', 'for')
.then((id) => {
cy.get('#' + id)
})
.click()
cy.get('li[data-strapi-value=en]').click()
cy.get('div[role=dialog] button').filter(':contains("Translate")').click()

// Verify translation finished

cy.wait('@batchTranslateContentTypes')

cy.get('[data-cy="api::article.article.de"]')
.contains('Job finished')
.should('exist')
cy.get('[data-cy="api::article.article.de"]')
.contains('complete')
.should('exist')
})

it('should translate and publish all articles', () => {
cy.intercept('/translate/batch-translate').as('batchTranslateExecution')
cy.intercept('/translate/batch-translate/content-types/').as(
'batchTranslateContentTypes'
)

// Login and Navigate to Translate Page
cy.login()
cy.get('nav').contains('Translate').click()

cy.wait('@batchTranslateContentTypes')

// Start batch translation

cy.get('button[data-cy="api::article.article.de.translate"]').focus()
cy.get('button[data-cy="api::article.article.de.translate"]').click()

// Complete dialog
cy.get('div[role=dialog]')
.contains('label', 'Locales')
.invoke('attr', 'for')
.then((id) => {
cy.get('#' + id)
})
.click()
cy.get('li[data-strapi-value=en]').click()
cy.get('div[role=dialog]')
.contains('label', 'Auto-Publish')
.invoke('attr', 'for')
.then((id) => {
cy.get('#' + id)
})
.parent()
.click()
cy.get('div[role=dialog] button').filter(':contains("Translate")').click()

// Verify translation finished

cy.wait('@batchTranslateContentTypes')

cy.get('[data-cy="api::article.article.de"]')
.contains('Job finished')
.should('exist')
cy.get('[data-cy="api::article.article.de"]')
.contains('complete')
.should('exist')
})
})
Loading