diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 917bdc39a..8807b802d 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -15,14 +15,21 @@ jobs: uses: actions/setup-node@v1 with: node-version: '12.x' - - run: npm ci - - run: git clone --branch master --depth 1 git://github.com/moodle/moodle $GITHUB_WORKSPACE/moodle - - run: git clone --branch ionic5 --depth 1 git://github.com/moodlehq/moodle-local_moodlemobileapp $GITHUB_WORKSPACE/moodle/local/moodlemobileapp - - run: git clone --branch MOBILE-3738 --depth 1 git://github.com/NoelDeMartin/moodle-docker $GITHUB_WORKSPACE/moodle-docker - - run: cp $GITHUB_WORKSPACE/moodle-docker/config.docker-template.php $GITHUB_WORKSPACE/moodle/config.php - - run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose pull - - run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose up -d - - run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-wait-for-db - - run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-wait-for-app - - run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose exec -T webserver sh -c "php admin/tool/behat/cli/init.php" - - run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose exec -T webserver sh -c "php admin/tool/behat/cli/run.php --tags="@app" --auto-rerun" + - name: Install npm packages + run: npm ci + - name: Additional checkouts + run: | + git clone --branch master --depth 1 git://github.com/moodle/moodle $GITHUB_WORKSPACE/moodle + git clone --branch ionic5 --depth 1 git://github.com/moodlehq/moodle-local_moodlemobileapp $GITHUB_WORKSPACE/moodle/local/moodlemobileapp + git clone --branch MOBILE-3738 --depth 1 git://github.com/NoelDeMartin/moodle-docker $GITHUB_WORKSPACE/moodle-docker + - name: Setup docker machine + run: | + cp $GITHUB_WORKSPACE/moodle-docker/config.docker-template.php $GITHUB_WORKSPACE/moodle/config.php + MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose pull + MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose up -d + MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-wait-for-db + MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-wait-for-app + - name: Init behat + run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose exec -T webserver sh -c "php admin/tool/behat/cli/init.php" + - name: Run tests + run: MOODLE_DOCKER_WWWROOT=$GITHUB_WORKSPACE/moodle MOODLE_DOCKER_APP_PATH=$GITHUB_WORKSPACE $GITHUB_WORKSPACE/moodle-docker/bin/moodle-docker-compose exec -T webserver sh -c "php admin/tool/behat/cli/run.php --tags="@app" --auto-rerun" diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index bb24d1c75..7c8d1e4fe 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -13,8 +13,45 @@ jobs: uses: actions/setup-node@v1 with: node-version: '12.x' - - run: npm ci - - run: npm run lint - - run: npm run test:ci - - run: npm run build:prod - - run: result=$(npx check-es-compat www/*.js 2> /dev/null | grep -v -E "Array\.prototype\.includes|Promise\.prototype\.finally|String\.prototype\.(matchAll|trimRight)|globalThis" | grep -Po "(?<=error).*?(?=\s+ecmascript)" | wc -l); test $result -eq 0 + - name: Install npm packages + run: npm ci + - name: Check langindex + run: | + result=$(cat scripts/langindex.json | grep \"TBD\" | wc -l); test $result -eq 0 + if [ $result -ne 0 ]; then + echo "There are lang strings to be decided on langindex.json" + exit 1 + fi + gulp + langlength=`jq -r '. | length' src/assets/lang/en.json` + langindexlength=`jq -r '. | length' scripts/langindex.json` + if [ $langlength -ne $langindexlength ]; then + echo "Lang file has $langlength while langindex $langindexlength" + exit 1 + fi + + langkeys=`jq -r 'keys[]' src/assets/lang/en.json` + langindex=`jq -r 'keys[]' scripts/langindex.json` + found=0 + for i in $langkeys; do + skip= + for j in $langindex; do + if [ "$i" == "$j" ]; then + skip=1 + break; + fi + done + [[ -n $skip ]] || { echo "$i key not found"; found=$(($found + 1)); } + done + if [ $found -ne 0 ]; then + echo "Found $found missing langkeys" + exit 1 + fi + - name: Run Linter + run: npm run lint + - name: Run tests + run: npm run test:ci + - name: Production builds + run: npm run build:prod + - name: JavaScript code compatibility + run: result=$(npx check-es-compat www/*.js 2> /dev/null | grep -v -E "Array\.prototype\.includes|Promise\.prototype\.finally|String\.prototype\.(matchAll|trimRight)|globalThis" | grep -Po "(?<=error).*?(?=\s+ecmascript)" | wc -l); test $result -eq 0 diff --git a/scripts/create_langindex.sh b/scripts/create_langindex.sh index 432419b3c..c17d77c20 100755 --- a/scripts/create_langindex.sh +++ b/scripts/create_langindex.sh @@ -1,5 +1,12 @@ #!/bin/bash +# +# Script to create langindex from available language packs. +# ./create_langindex.sh [findbetter] +# If findbetter is set it will try to find a better solution for every key. +# + source "functions.sh" +source "lang_functions.sh" #Saves or updates a key on langindex_old.json function save_key { @@ -48,7 +55,8 @@ function exists_in_mobile { } function do_match { - match=$1 + match=${1/\{\{/\{} + match=${match/\}\}/\}} filematch="" coincidence=`grep "$match" $LANGPACKSFOLDER/en/*.php | wc -l` @@ -56,7 +64,7 @@ function do_match { filematch=`grep "$match" $LANGPACKSFOLDER/en/*.php | cut -d'/' -f5 | cut -d'.' -f1` exists_in_file $filematch $plainid elif [ $coincidence -gt 0 ] && [ "$#" -gt 1 ]; then - print_message $2 + print_message "$2" tput setaf 6 grep "$match" $LANGPACKSFOLDER/en/*.php fi @@ -67,18 +75,21 @@ function find_matches { do_match "string\[\'$plainid\'\] = \'$value\'" "Found EXACT match for $key in the following paths" if [ $coincidence -gt 0 ]; then case=1 + save_key $key "TBD" return fi do_match " = \'$value\'" "Found some string VALUES for $key in the following paths" if [ $coincidence -gt 0 ]; then case=2 + save_key $key "TBD" return fi do_match "string\[\'$plainid\'\]" "Found some string KEYS for $key in the following paths, value $value" if [ $coincidence -gt 0 ]; then case=3 + save_key $key "TBD" return fi @@ -297,17 +308,13 @@ function array_contains { done } + print_title 'Generating language from code...' gulp lang print_title 'Getting languages' -git clone https://git.in.moodle.com/moodle/moodle-langpacks.git $LANGPACKSFOLDER -pushd $LANGPACKSFOLDER -BRANCHES=($(git branch -r --format="%(refname:lstrip=3)" --sort="refname" | grep MOODLE_)) -BRANCH=${BRANCHES[${#BRANCHES[@]}-1]} -git checkout $BRANCH -git pull -popd + +get_language en print_title 'Processing file' #Create langindex.json if not exists. diff --git a/scripts/functions.sh b/scripts/functions.sh index f90399189..45d2ab331 100644 --- a/scripts/functions.sh +++ b/scripts/functions.sh @@ -1,7 +1,5 @@ #!/bin/bash -LANGPACKSFOLDER='../../moodle-langpacks' - function check_success_exit { if [ $? -ne 0 ]; then print_error "$1" diff --git a/scripts/lang_functions.sh b/scripts/lang_functions.sh new file mode 100755 index 000000000..d8bcf38ae --- /dev/null +++ b/scripts/lang_functions.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# +# Functions to fetch languages. +# + +LANGPACKSFOLDER='../../moodle-langpacks' +BUCKET='moodle-lang-prod' +MOODLEORG_URL='https://download.moodle.org/download.php/direct/langpack' +DEFAULT_LASTVERSION='4.0' + +# Checks if AWS is available and configured. +function check_aws { + aws --version &> /dev/null + AWS_SERVICE=1 + if [ $? -ne 0 ]; then + AWS_SERVICE=0 + echo 'AWS not installed. Check https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html for more info.' + return + fi + + # In order to login to AWS, use credentials file or AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY vars. + if [ ! -f ~/.aws/credentials ] && [ [ -z $AWS_ACCESS_KEY_ID ] || [ -z $AWS_SECRET_ACCESS_KEY ] ]; then + AWS_SERVICE=0 + lastversion=$DEFAULT_LASTVERSION + echo 'AWS Cannot authenticate. Use aws configure or set the proper env vars.' + return + fi +} + +# Get last version of Moodle to fetch latest languages. +function get_last_version { + if [ ! -z "${lastversion}" ]; then + return + fi + + check_aws + if [ $AWS_SERVICE -eq 0 ]; then + lastversion=$DEFAULT_LASTVERSION + echo "Using default version $lastversion" + return + fi + + list=`aws s3 ls s3://$BUCKET/` + if [ $? -ne 0 ]; then + AWS_SERVICE=0 + lastversion=$DEFAULT_LASTVERSION + echo "AWS Cannot authenticate. Using default version $lastversion" + return + fi + + lastversion='' + for folder in $list; do + if [ $folder != 'PRE' ]; then + lastversion=${folder/\//} + fi + done + + if [ ! -z "${lastversion}" ]; then + echo "Last version $lastversion detected" + return + fi + + lastversion=$DEFAULT_LASTVERSION +} + +# Get all language list from AWS. +function get_all_languages_aws { + langsfiles=`aws s3 ls s3://$BUCKET/$lastversion/` + langs="" + for file in $langsfiles; do + if [[ "$file" == *.zip ]]; then + file=${file/\.zip/} + langs+="$file " + fi + done +} + +# Get language list from the installed ones (will not discover new translations). +function get_installed_languages { + langs=`jq -r '.languages | keys[]' ../moodle.config.json` +} + +# Entry function to get a language file. +function get_language { + lang=$1 + lang=${lang/-/_} + + get_last_version + + echo "Getting $lang language" + + pushd $LANGPACKSFOLDER > /dev/null + + curl -s $MOODLEORG_URL/$lastversion/$lang.zip --output $lang.zip > /dev/null + rm -R $lang + unzip -o -u $lang.zip > /dev/null + + # This is the AWS version to get the language but right now it's slower. + # aws s3 cp s3://$BUCKET/$lastversion/$lang.zip . > /dev/null + + rm $lang.zip + popd > /dev/null +} + +# Entry function to get all language files. +function get_languages { + get_last_version + + if [ -d $LANGPACKSFOLDER ]; then + lastupdate=`date -r $LANGPACKSFOLDER +%s` + currenttime=`date +%s` + ellapsedtime=$((currenttime - lastupdate)) + if [ $ellapsedtime -lt 3600 ]; then + echo 'Recently updated, skip update languages' + return + fi + else + mkdir $LANGPACKSFOLDER + fi + + + if [ $AWS_SERVICE -eq 1 ]; then + get_all_languages_aws + else + echo "Fallback language list will only get current installation languages" + get_installed_languages + fi + + for lang in $langs; do + get_language "$lang" + done +} diff --git a/scripts/update_lang.sh b/scripts/update_lang.sh index dac901789..b47df3a7d 100755 --- a/scripts/update_lang.sh +++ b/scripts/update_lang.sh @@ -1,23 +1,23 @@ #!/bin/bash +# +# Script to update language packs on assets and detect new translated languages. +# ./update_lang.sh [language] +# If language is set it will only update the selected language. +# source "functions.sh" -forceLang=$1 +source "lang_functions.sh" -print_title 'Getting languages' -git clone --depth 1 --no-single-branch https://git.in.moodle.com/moodle/moodle-langpacks.git $LANGPACKSFOLDER -pushd $LANGPACKSFOLDER -BRANCHES=($(git branch -r --format="%(refname:lstrip=3)" --sort="refname" | grep MOODLE_)) -BRANCH=${BRANCHES[${#BRANCHES[@]}-1]} -git checkout $BRANCH -git pull -popd +forceLang=$1 print_title 'Getting local mobile langs' git clone --depth 1 https://github.com/moodlehq/moodle-local_moodlemobileapp.git ../../moodle-local_moodlemobileapp if [ -z $forceLang ]; then + get_languages php -f moodle_to_json.php else + get_language "$forceLang" php -f moodle_to_json.php "$forceLang" fi -print_ok 'All done!' \ No newline at end of file +print_ok 'All done!' diff --git a/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html b/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html index f91a08355..ed9bba085 100644 --- a/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html +++ b/src/addons/block/myoverview/components/myoverview/addon-block-myoverview.html @@ -74,7 +74,7 @@ + [message]="'addon.block_myoverview.nocourses' | translate" inline="true"> diff --git a/src/addons/block/timeline/components/events/addon-block-timeline-events.html b/src/addons/block/timeline/components/events/addon-block-timeline-events.html index 17b10812d..8a3c70adc 100644 --- a/src/addons/block/timeline/components/events/addon-block-timeline-events.html +++ b/src/addons/block/timeline/components/events/addon-block-timeline-events.html @@ -20,7 +20,7 @@

- {{event.action.name}} {{event.action.itemcount}} @@ -28,19 +28,23 @@ - - +
+
{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }} - - - - {{event.action.name}} - {{event.action.itemcount}} - - - - +
+ + {{event.action.name}} + + {{event.action.itemcount}} + + +
@@ -54,4 +58,5 @@ + inline="true"> + diff --git a/src/addons/block/timeline/components/events/events.scss b/src/addons/block/timeline/components/events/events.scss new file mode 100644 index 000000000..c863dbb2a --- /dev/null +++ b/src/addons/block/timeline/components/events/events.scss @@ -0,0 +1,6 @@ +.events-info { + display: flex; + flex-direction: column; + text-align: end; + padding: 10px 0; +} diff --git a/src/addons/block/timeline/components/events/events.ts b/src/addons/block/timeline/components/events/events.ts index 0b29a7b80..f4266f50c 100644 --- a/src/addons/block/timeline/components/events/events.ts +++ b/src/addons/block/timeline/components/events/events.ts @@ -29,6 +29,7 @@ import { AddonCalendarEvent } from '@addons/calendar/services/calendar'; @Component({ selector: 'addon-block-timeline-events', templateUrl: 'addon-block-timeline-events.html', + styleUrls: ['events.scss'], }) export class AddonBlockTimelineEventsComponent implements OnChanges { diff --git a/src/addons/block/timeline/services/timeline.ts b/src/addons/block/timeline/services/timeline.ts index 2a4f7e4d0..c50c5adef 100644 --- a/src/addons/block/timeline/services/timeline.ts +++ b/src/addons/block/timeline/services/timeline.ts @@ -103,7 +103,7 @@ export class AddonBlockTimelineProvider { async getActionEventsByCourses( courseIds: number[], siteId?: string, - ): Promise<{[courseId: string]: { events: AddonCalendarEvent[]; canLoadMore: number } }> { + ): Promise<{[courseId: string]: { events: AddonCalendarEvent[]; canLoadMore?: number } }> { const site = await CoreSites.getSite(siteId); const time = moment().subtract(14, 'days').unix(); // Check two weeks ago. @@ -123,17 +123,13 @@ export class AddonBlockTimelineProvider { preSets, ); - if (events && events.groupedbycourse) { - const courseEvents = {}; + const courseEvents: {[courseId: string]: { events: AddonCalendarEvent[]; canLoadMore?: number } } = {}; - events.groupedbycourse.forEach((course) => { - courseEvents[course.courseid] = this.treatCourseEvents(course, time); - }); + events.groupedbycourse.forEach((course) => { + courseEvents[course.courseid] = this.treatCourseEvents(course, time); + }); - return courseEvents; - } - - throw new CoreError('No events returned on core_calendar_get_action_events_by_courses.'); + return courseEvents; } /** diff --git a/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html b/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html index eb47dffa2..bcc2d1949 100644 --- a/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html +++ b/src/addons/mod/wiki/components/index/addon-mod-wiki-index.html @@ -83,7 +83,7 @@ contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId"> + inline="true"> diff --git a/src/core/components/download-refresh/download-refresh.scss b/src/core/components/download-refresh/download-refresh.scss index b03f953f8..3ee2b9406 100644 --- a/src/core/components/download-refresh/download-refresh.scss +++ b/src/core/components/download-refresh/download-refresh.scss @@ -5,4 +5,6 @@ align-items: center; justify-content: space-around; align-content: center; + min-height: var(--a11y-min-target-size); + min-width: var(--a11y-min-target-size); } diff --git a/src/core/components/empty-box/empty-box.ts b/src/core/components/empty-box/empty-box.ts index f2d5ef172..dccd1df0c 100644 --- a/src/core/components/empty-box/empty-box.ts +++ b/src/core/components/empty-box/empty-box.ts @@ -37,7 +37,7 @@ export class CoreEmptyBoxComponent { * If this has to be shown inline instead of occupying whole page. * If image or icon is not supplied, it's true by default. */ - @Input() inline?: boolean; - @Input() flipIconRtl?: boolean; // Whether to flip the icon in RTL. Defaults to false. + @Input() inline = false; + @Input() flipIconRtl = false; // Whether to flip the icon in RTL. Defaults to false. } diff --git a/src/core/components/tabs/tabs.scss b/src/core/components/tabs/tabs.scss index 93ce49ca6..fb3837155 100644 --- a/src/core/components/tabs/tabs.scss +++ b/src/core/components/tabs/tabs.scss @@ -1,5 +1,5 @@ :host { - --tabs-background: var(--background); + --tabs-background: var(--core-tabs-background); --tabs-color: var(--color); height: 100%; display: block; diff --git a/src/core/features/block/components/block/block.scss b/src/core/features/block/components/block/block.scss index 43be2ef93..2d22d09be 100644 --- a/src/core/features/block/components/block/block.scss +++ b/src/core/features/block/components/block/block.scss @@ -1,6 +1,7 @@ :host { position: relative; display: block; + background: var(--background); ion-item-divider { min-height: 60px; diff --git a/src/core/features/course/components/format/core-course-format.html b/src/core/features/course/components/format/core-course-format.html index 0200201de..83df84652 100644 --- a/src/core/features/course/components/format/core-course-format.html +++ b/src/core/features/course/components/format/core-course-format.html @@ -17,7 +17,7 @@
@@ -122,8 +122,6 @@ - -

{{ 'core.course.hiddenfromstudents' | translate }} @@ -137,6 +135,8 @@

+ + @@ -155,7 +155,7 @@ -
+
diff --git a/src/core/features/course/components/format/format.scss b/src/core/features/course/components/format/format.scss index bd62cd001..027504d87 100644 --- a/src/core/features/course/components/format/format.scss +++ b/src/core/features/course/components/format/format.scss @@ -45,6 +45,13 @@ } } + .core-button-selector-row { + display: flex; + core-combobox { + flex-grow: 1; + } + } + // @todo // .item-divider { // .label { @@ -70,8 +77,6 @@ // @include padding(null, 0, null, null); // } -// .core-button-selector-row { -// @include safe-area-padding-start($content-padding !important, $content-padding); -// } +// } diff --git a/src/core/features/course/services/module-prefetch-delegate.ts b/src/core/features/course/services/module-prefetch-delegate.ts index aca8154ae..f315b6917 100644 --- a/src/core/features/course/services/module-prefetch-delegate.ts +++ b/src/core/features/course/services/module-prefetch-delegate.ts @@ -724,7 +724,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate { const handler = this.getPrefetchHandlerFor(module); - if (!handler || onlyToDisplay || handler.skipListStatus) { + if (!handler || (onlyToDisplay && handler.skipListStatus)) { return; } diff --git a/src/core/features/courses/components/course-options-menu/core-courses-course-options-menu.html b/src/core/features/courses/components/course-options-menu/core-courses-course-options-menu.html index e1ff79574..f18b47cbd 100644 --- a/src/core/features/courses/components/course-options-menu/core-courses-course-options-menu.html +++ b/src/core/features/courses/components/course-options-menu/core-courses-course-options-menu.html @@ -1,25 +1,26 @@ - +

{{ prefetch.statusTranslatable | translate }}

- +

{{ 'addon.storagemanager.deletecourse' | translate }}

- +

{{ 'core.courses.hidecourse' | translate }}

- +

{{ 'core.courses.show' | translate }}

- +

{{ 'core.courses.addtofavourites' | translate }}

- +

{{ 'core.courses.removefromfavourites' | translate }}

diff --git a/src/core/features/courses/components/course-progress/core-courses-course-progress.html b/src/core/features/courses/components/course-progress/core-courses-course-progress.html index 508bcf80f..1138065e7 100644 --- a/src/core/features/courses/components/course-progress/core-courses-course-progress.html +++ b/src/core/features/courses/components/course-progress/core-courses-course-progress.html @@ -5,7 +5,7 @@
+ [class.core-course-more-than-title]="course.progress! >= 0" detail="false">