diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000..86f25a1db8
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,13 @@
+# The .dockerignore file excludes files from the container build process.
+#
+# https://docs.docker.com/engine/reference/builder/#dockerignore-file
+
+# Exclude locally vendored dependencies.
+src/vendor/
+
+# Exclude "build-time" ignore files.
+.dockerignore
+
+# Exclude git history and configuration.
+.gitignore
+.git
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 30a7e4ff55..7ea2ff1f59 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -22,9 +22,10 @@ Please provide screenshots / animations for any change that involves the UI. Ple
## Checklist
- [ ] I have performed a self-review of my own code
-- [ ] I have reviewed the title/description of this PR which will be used as the squashed PR commit message
+- [ ] I have reviewed the title & description of this PR which I will use as the squashed PR commit message
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have added tests that prove my fix is effective or that my feature works
+- [ ] I have enabled auto-merge (optional)
## How to test
diff --git a/.github/workflows/integrate-and-deploy.yml b/.github/workflows/integrate-and-deploy.yml
index 440976506e..3ce082b79c 100644
--- a/.github/workflows/integrate-and-deploy.yml
+++ b/.github/workflows/integrate-and-deploy.yml
@@ -74,12 +74,16 @@ jobs:
-
name: Unit Tests
run: make unit-tests-ci
- # -
- # name: E2E Tests
- # run: |
- # docker compose -f docker-compose.yml up -d app-for-playwright
- # npx playwright install chromium
- # npx playwright test
+ -
+ name: Playwright E2E Tests
+ run: make playwright-tests-ci
+ -
+ name: Upload Playwright test results
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: test-results
+ path: test-results
-
name: Log in to Docker Hub
uses: docker/login-action@v2
diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index f5765bd670..e98c13bcaa 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -62,12 +62,12 @@ jobs:
run: make playwright-tests-ci
-
- name: Upload test results
+ name: Upload Playwright test results
if: always()
uses: actions/upload-artifact@v3
with:
name: test-results
- path: test-results
+ path: test/e2e/test-results
check-code-formatting:
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 6445ffc77d..60502aa4fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,6 @@ test/php/\.phpunit\.result\.cache
node_modules
.DS_Store
docker-scan-results.txt
-test-results/
-playwright-report/
+test-results
+test-storage-state
*storageState.json
diff --git a/Makefile b/Makefile
index 1b79ec7434..f508db34dd 100644
--- a/Makefile
+++ b/Makefile
@@ -13,19 +13,19 @@ dev: start
playwright-tests-ci:
npm ci
$(MAKE) playwright-app
- npx playwright install chromium && npx playwright test
+ npx playwright install chromium && npx playwright test -c ./test/e2e/playwright.config.ts
.PHONY: playwright-tests
playwright-tests:
npm install
$(MAKE) playwright-app
docker compose up -d ui-builder
- npx playwright install chromium && npx playwright test $(params)
+ npx playwright install chromium && npx playwright test -c ./test/e2e/playwright.config.ts $(params)
.PHONY: playwright-app
playwright-app:
# delete any cached session storage state files if the service isn't running
- docker compose ps app-for-playwright > /dev/null 2>&1 || rm -f *-storageState.json
+ docker compose ps app-for-playwright > /dev/null 2>&1 || $(MAKE) clean-test
docker compose up -d app-for-playwright
# wait until the app-for-playwright service is serving up HTTP before continuing
until curl localhost:3238 > /dev/null 2>&1; do sleep 1; done
@@ -83,9 +83,12 @@ clean:
docker compose down
docker system prune -f
+clean-test:
+ cd test/e2e && npx rimraf test-storage-state test-results
+
.PHONY: clean-powerwash
clean-powerwash: clean
- npx rimraf *storageState.json test-results
+ $(MAKE) clean-test
docker system prune -f --volumes
- docker rmi -f `docker images -q "lf-*"` sillsdev/web-languageforge:base-php
docker builder prune -f
diff --git a/next-app/src/routes/projects/[project_code]/activities/+server.ts b/next-app/src/routes/projects/[project_code]/activities/+server.ts
index be00ec015d..638bb72241 100644
--- a/next-app/src/routes/projects/[project_code]/activities/+server.ts
+++ b/next-app/src/routes/projects/[project_code]/activities/+server.ts
@@ -4,23 +4,24 @@ import { sf } from '$lib/fetch/server'
export async function GET({ params: { project_code }, request: { headers } }) {
const cookie = headers.get('cookie')
- const activities = await get_activities({ project_code, cookie })
+ await sf({ name: 'set_project', args: [ project_code ], cookie })
+
+ const activities = await get_activities({ cookie })
return json(activities)
}
// src/Api/Model/Shared/Dto/ActivityListDto.php
// src/Api/Model/Shared/Dto/ActivityListDto.php->ActivityListModel.__construct
-export async function get_activities({ project_code, cookie, start_date, end_date }) {
+export async function get_activities({ cookie, start_date, end_date }) {
const args = {
- name: 'activity_list_dto_for_project',
+ name: 'activity_list_dto_for_current_project',
args: [
- project_code,
{
startDate: start_date,
endDate: end_date,
limit: start_date || end_date ? 50 : 0,
- }
+ },
],
cookie,
}
diff --git a/package.json b/package.json
index fbaba18850..aeb429d5d7 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"webpack:dev:watch": "webpack -w --config webpack-dev.config.js",
"webpack:prd": "webpack --config webpack-prd.config.js",
"compile-test-e2e": "tsc -p test/app",
- "test-e2e": "protractor test/app/protractorConf.js",
+ "test-e2e": "npx playwright test -c ./test/e2e/playwright.config.ts",
"prepare": "husky install"
},
"license": "MIT",
diff --git a/src/Api/Model/Shared/Dto/RightsHelper.php b/src/Api/Model/Shared/Dto/RightsHelper.php
index 3434bf80bb..47252d1ed8 100644
--- a/src/Api/Model/Shared/Dto/RightsHelper.php
+++ b/src/Api/Model/Shared/Dto/RightsHelper.php
@@ -210,9 +210,6 @@ public function userCanAccessMethod($methodName)
case "activity_list_dto_for_current_project":
return $this->userHasSiteRight(Domain::PROJECTS + Operation::VIEW_OWN);
- case "activity_list_dto_for_project":
- return $this->userHasSiteRight(Domain::PROJECTS + Operation::VIEW_OWN);
-
case "activity_list_dto_for_lexical_entry":
return $this->userHasProjectRight(Domain::ENTRIES + Operation::VIEW);
diff --git a/src/Api/Service/Sf.php b/src/Api/Service/Sf.php
index 52b371d82e..006a6ad8bb 100644
--- a/src/Api/Service/Sf.php
+++ b/src/Api/Service/Sf.php
@@ -438,16 +438,6 @@ public function activity_list_dto_for_current_project($filterParams = [])
return ActivityListDto::getActivityForOneProject($projectModel, $this->userId, $filterParams);
}
- public function activity_list_dto_for_project($projectCode, $filterParams = [])
- {
- $projectModel = ProjectModel::getByProjectCode($projectCode);
- $user = new UserModel($this->userId);
- if ($user->isMemberOfProject($projectModel->id->asString())) {
- return ActivityListDto::getActivityForOneProject($projectModel, $this->userId, $filterParams);
- }
- throw new UserUnauthorizedException("User $this->userId is not a member of project $projectCode");
- }
-
public function activity_list_dto_for_lexical_entry($entryId, $filterParams = [])
{
$projectModel = ProjectModel::getById($this->projectId);
diff --git a/src/angular-app/languageforge/lexicon/editor/editor-list.view.html b/src/angular-app/languageforge/lexicon/editor/editor-list.view.html
index e079db03a7..b4ba963515 100644
--- a/src/angular-app/languageforge/lexicon/editor/editor-list.view.html
+++ b/src/angular-app/languageforge/lexicon/editor/editor-list.view.html
@@ -109,12 +109,12 @@
-
+
Looks like there are no entries yet.
-
diff --git a/src/angular-app/languageforge/lexicon/editor/field/dc-picture.component.ts b/src/angular-app/languageforge/lexicon/editor/field/dc-picture.component.ts
index e3b0a4dcd4..5d978ea29e 100644
--- a/src/angular-app/languageforge/lexicon/editor/field/dc-picture.component.ts
+++ b/src/angular-app/languageforge/lexicon/editor/field/dc-picture.component.ts
@@ -72,7 +72,7 @@ export class FieldPictureController implements angular.IController {
const fileName: string = this.pictures[index].fileName;
if (fileName) {
const deleteMsg: string = 'Are you sure you want to delete the picture
\'' +
- FieldPictureController.originalFileName(fileName) + '\'';
+ FieldPictureController.originalFileName(fileName) + '\'?';
this.modalService.showModalSimple('Delete Picture', deleteMsg, 'Cancel', 'Delete Picture').then(() => {
this.pictures.splice(index, 1);
this.lexProjectService.removeMediaFile('sense-image', fileName, result => {
diff --git a/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.html b/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.html
index 1fba4075fb..7201e10671 100644
--- a/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.html
+++ b/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.html
@@ -6,15 +6,15 @@
-
+
diff --git a/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.ts b/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.ts
index 3fd4439714..028c577379 100644
--- a/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.ts
+++ b/src/angular-app/languageforge/lexicon/editor/field/dc-sense.component.ts
@@ -67,10 +67,10 @@ export class FieldSenseController implements angular.IController {
// noinspection JSUnusedGlobalSymbols
deleteExample = (index: number): void => {
- const deletemsg = 'Are you sure you want to delete the example
\' ' +
+ const deletemsg = 'Are you sure you want to delete the example \'' +
LexiconUtilityService.getExample(this.control.config, this.config.fields.examples as LexConfigFieldList,
this.model.examples[index], 'sentence')
- + ' \'';
+ + '\'?';
this.modal.showModalSimple('Delete Example', deletemsg, 'Cancel', 'Delete Example')
.then(() => {
// Adding or removing examples makes for a non-delta update, so save a possible delta update first
diff --git a/src/angular-app/languageforge/lexicon/settings/configuration/configuration-option-lists.component.ts b/src/angular-app/languageforge/lexicon/settings/configuration/configuration-option-lists.component.ts
index 6a5c1c9cb3..d63c0ea762 100644
--- a/src/angular-app/languageforge/lexicon/settings/configuration/configuration-option-lists.component.ts
+++ b/src/angular-app/languageforge/lexicon/settings/configuration/configuration-option-lists.component.ts
@@ -18,7 +18,7 @@ export class OptionListConfigurationController implements angular.IController {
return null;
}
- return this.olcOptionListsDirty[this.currentListIndex].items;
+ return this.olcOptionListsDirty[this.currentListIndex]?.items;
},
(newVal: LexOptionListItem[], oldVal: LexOptionListItem[]) => {
if (newVal != null && newVal !== oldVal) {
diff --git a/src/angular-app/languageforge/lexicon/settings/configuration/field-unified-view.model.ts b/src/angular-app/languageforge/lexicon/settings/configuration/field-unified-view.model.ts
index b7c1bfe018..9b2070ba4f 100644
--- a/src/angular-app/languageforge/lexicon/settings/configuration/field-unified-view.model.ts
+++ b/src/angular-app/languageforge/lexicon/settings/configuration/field-unified-view.model.ts
@@ -422,9 +422,9 @@ export class ConfigurationFieldUnifiedViewModel {
const userView: LexUserViewConfig = config.userViews[userId];
if (userView != null) {
if (userView.inputSystems && userView.inputSystems.length) {
- inputSystemSettings.groups[groupIndex].show = userView.inputSystems.includes(tag);
+ inputSystemSettings.groups[groupIndex] = {show: userView.inputSystems.includes(tag)};
} else {
- inputSystemSettings.groups[groupIndex].show = true;
+ inputSystemSettings.groups[groupIndex] = {show: true};
}
}
}
diff --git a/src/angular-app/languageforge/lexicon/settings/project-settings.component.html b/src/angular-app/languageforge/lexicon/settings/project-settings.component.html
index 404c81491e..d010c1a0be 100644
--- a/src/angular-app/languageforge/lexicon/settings/project-settings.component.html
+++ b/src/angular-app/languageforge/lexicon/settings/project-settings.component.html
@@ -27,7 +27,7 @@