Merge pull request #2761 from crazyserver/MOBILE-3320
MOBILE-3320 lang: Use AWS to update lang filesmain
commit
8c16e648c9
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
LANGPACKSFOLDER='../../moodle-langpacks'
|
||||
|
||||
function check_success_exit {
|
||||
if [ $? -ne 0 ]; then
|
||||
print_error "$1"
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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!'
|
||||
print_ok 'All done!'
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
</ion-searchbar>
|
||||
|
||||
<core-empty-box *ngIf="filteredCourses.length == 0" image="assets/img/icons/courses.svg"
|
||||
[message]="'addon.block_myoverview.nocourses' | translate" class="core-empty-inline">
|
||||
[message]="'addon.block_myoverview.nocourses' | translate" inline="true">
|
||||
</core-empty-box>
|
||||
|
||||
<!-- List of courses. -->
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</core-format-text>
|
||||
</p>
|
||||
|
||||
<ion-button fill="clear" class="ion-hide-md-up" (click)="action($event, event.action.url)"
|
||||
<ion-button fill="clear" class="ion-hide-md-up ion-text-wrap" (click)="action($event, event.action.url)"
|
||||
[title]="event.action.name" [disabled]="!event.action.actionable" *ngIf="event.action">
|
||||
{{event.action.name}}
|
||||
<ion-badge slot="end" class="ion-margin-start" *ngIf="event.action.showitemcount">{{event.action.itemcount}}
|
||||
|
@ -28,19 +28,23 @@
|
|||
</ion-button>
|
||||
</ion-label>
|
||||
|
||||
<ion-grid slot="end">
|
||||
<ion-row class="ion-justify-content-end">
|
||||
<div slot="end" class="events-info">
|
||||
<div>
|
||||
<ion-badge color="light">{{event.timesort * 1000 | coreFormatDate:"strftimetime24" }}</ion-badge>
|
||||
</ion-row>
|
||||
<ion-row class="ion-justify-content-end">
|
||||
<ion-button fill="clear" class="ion-hide-md-down" (click)="action($event, event.action.url)"
|
||||
[title]="event.action.name" [disabled]="!event.action.actionable" *ngIf="event.action">
|
||||
{{event.action.name}}
|
||||
<ion-badge slot="end" class="ion-margin-start" *ngIf="event.action.showitemcount">{{event.action.itemcount}}
|
||||
</ion-badge>
|
||||
</ion-button>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</div>
|
||||
<ion-button
|
||||
class="ion-hide-md-down"
|
||||
fill="clear"
|
||||
(click)="action($event, event.action.url)"
|
||||
[title]="event.action.name"
|
||||
[disabled]="!event.action.actionable" *ngIf="event.action"
|
||||
>
|
||||
{{event.action.name}}
|
||||
<ion-badge slot="end" class="ion-margin-start" *ngIf="event.action.showitemcount">
|
||||
{{event.action.itemcount}}
|
||||
</ion-badge>
|
||||
</ion-button>
|
||||
</div>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-item-group>
|
||||
|
@ -54,4 +58,5 @@
|
|||
</div>
|
||||
|
||||
<core-empty-box *ngIf="empty" image="assets/img/icons/activities.svg" [message]="'addon.block_timeline.noevents' | translate"
|
||||
[inline]="!showCourse"></core-empty-box>
|
||||
inline="true">
|
||||
</core-empty-box>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
.events-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: end;
|
||||
padding: 10px 0;
|
||||
}
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
contextLevel="module" [contextInstanceId]="module.id" [courseId]="courseId">
|
||||
</core-format-text>
|
||||
<core-empty-box *ngIf="!pageContent" icon="fas-file-alt" [message]="'addon.mod_wiki.nocontent' | translate"
|
||||
[inline]="true">
|
||||
inline="true">
|
||||
</core-empty-box>
|
||||
</article>
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
:host {
|
||||
--tabs-background: var(--background);
|
||||
--tabs-background: var(--core-tabs-background);
|
||||
--tabs-color: var(--color);
|
||||
height: 100%;
|
||||
display: block;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
:host {
|
||||
position: relative;
|
||||
display: block;
|
||||
background: var(--background);
|
||||
|
||||
ion-item-divider {
|
||||
min-height: 60px;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<core-dynamic-component [component]="sectionSelectorComponent" [data]="data">
|
||||
|
||||
<div *ngIf="displaySectionSelector && sections && hasSeveralSections"
|
||||
class="ion-text-wrap clearfix ion-justify-content-between core-button-selector-row"
|
||||
class="ion-text-wrap ion-justify-content-between ion-align-items-center core-button-selector-row"
|
||||
[class.core-section-download]="downloadEnabled">
|
||||
<core-combobox [modalOptions]="sectionSelectorModalOptions" interface="modal" listboxId="core-course-section-button"
|
||||
icon="fas-folder" [label]="'core.course.section' | translate" (onChange)="sectionChanged($event)">
|
||||
|
@ -122,8 +122,6 @@
|
|||
<core-format-text [text]="section.name" contextLevel="course" [contextInstanceId]="course?.id">
|
||||
</core-format-text>
|
||||
</h2>
|
||||
<!-- Section download. -->
|
||||
<ng-container *ngTemplateOutlet="sectionDownloadTemplate; context: {section: section}"></ng-container>
|
||||
<p *ngIf="section.visible === 0 || section.availabilityinfo">
|
||||
<ion-badge color="info" *ngIf="section.visible === 0 && section.uservisible !== false" class="ion-text-wrap">
|
||||
{{ 'core.course.hiddenfromstudents' | translate }}
|
||||
|
@ -137,6 +135,8 @@
|
|||
</ion-badge>
|
||||
</p>
|
||||
</ion-label>
|
||||
<!-- Section download. -->
|
||||
<ng-container *ngTemplateOutlet="sectionDownloadTemplate; context: {section: section}"></ng-container>
|
||||
</ion-item-divider>
|
||||
|
||||
<ion-item class="ion-text-wrap" *ngIf="section.summary">
|
||||
|
@ -155,7 +155,7 @@
|
|||
|
||||
<!-- Template to render a section download button/progress. -->
|
||||
<ng-template #sectionDownloadTemplate let-section="section">
|
||||
<div *ngIf="section && downloadEnabled" class="core-button-spinner ion-float-end">
|
||||
<div *ngIf="section && downloadEnabled" slot="end">
|
||||
<!-- Download progress. -->
|
||||
<ion-badge class="core-course-download-section-progress"
|
||||
*ngIf="section.isDownloading && section.total > 0 && section.count < section.total">
|
||||
|
|
|
@ -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);
|
||||
// }
|
||||
//
|
||||
|
||||
}
|
||||
|
|
|
@ -724,7 +724,7 @@ export class CoreCourseModulePrefetchDelegateService extends CoreDelegate<CoreCo
|
|||
|
||||
await Promise.all(modules.map(async (module) => {
|
||||
const handler = this.getPrefetchHandlerFor(module);
|
||||
if (!handler || onlyToDisplay || handler.skipListStatus) {
|
||||
if (!handler || (onlyToDisplay && handler.skipListStatus)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
<ion-item button class="ion-text-wrap" (click)="action('download')" *ngIf="downloadCourseEnabled">
|
||||
<ion-item button class="ion-text-wrap" (click)="action('download')" *ngIf="downloadCourseEnabled" detail="false">
|
||||
<ion-icon *ngIf="!prefetch.loading" [name]="prefetch.icon" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-spinner *ngIf="prefetch.loading" slot="start"></ion-spinner>
|
||||
<ion-label><h2>{{ prefetch.statusTranslatable | translate }}</h2></ion-label>
|
||||
</ion-item>
|
||||
<ion-item button class="ion-text-wrap" (click)="action('delete')" *ngIf="prefetch.status == 'downloaded' || prefetch.status == 'outdated'">
|
||||
<ion-item button class="ion-text-wrap" (click)="action('delete')" detail="false"
|
||||
*ngIf="prefetch.status == 'downloaded' || prefetch.status == 'outdated'">
|
||||
<ion-icon name="fas-trash" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label><h2>{{ 'addon.storagemanager.deletecourse' | translate }}</h2></ion-label>
|
||||
</ion-item>
|
||||
<ion-item button class="ion-text-wrap" (click)="action('hide')" *ngIf="!course.hidden">
|
||||
<ion-item button class="ion-text-wrap" (click)="action('hide')" *ngIf="!course.hidden" detail="false">
|
||||
<ion-icon name="fas-eye" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label><h2>{{ 'core.courses.hidecourse' | translate }}</h2></ion-label>
|
||||
</ion-item>
|
||||
<ion-item button class="ion-text-wrap" (click)="action('show')" *ngIf="course.hidden">
|
||||
<ion-item button class="ion-text-wrap" (click)="action('show')" *ngIf="course.hidden" detail="false">
|
||||
<ion-icon name="fas-eye-slash" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label><h2>{{ 'core.courses.show' | translate }}</h2></ion-label>
|
||||
</ion-item>
|
||||
<ion-item button class="ion-text-wrap" (click)="action('favourite')" *ngIf="!course.isfavourite">
|
||||
<ion-item button class="ion-text-wrap" (click)="action('favourite')" *ngIf="!course.isfavourite" detail="false">
|
||||
<ion-icon name="fas-star" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label><h2>{{ 'core.courses.addtofavourites' | translate }}</h2></ion-label>
|
||||
</ion-item>
|
||||
<ion-item button class="ion-text-wrap" (click)="action('unfavourite')" *ngIf="course.isfavourite">
|
||||
<ion-item button class="ion-text-wrap" (click)="action('unfavourite')" *ngIf="course.isfavourite" detail="false">
|
||||
<ion-icon name="far-star" slot="start" aria-hidden="true"></ion-icon>
|
||||
<ion-label><h2>{{ 'core.courses.removefromfavourites' | translate }}</h2></ion-label>
|
||||
</ion-item>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</div>
|
||||
<ion-item button lines="none" (click)="openCourse()" [attr.aria-label]="course.displayname || course.fullname"
|
||||
class="core-course-header" [class.item-disabled]="course.visible == 0"
|
||||
[class.core-course-more-than-title]="course.progress! >= 0">
|
||||
[class.core-course-more-than-title]="course.progress! >= 0" detail="false">
|
||||
<ion-label
|
||||
class="ion-text-wrap core-course-title"
|
||||
[class.core-course-with-buttons]="courseOptionMenuEnabled || (downloadCourseEnabled && showDownload)"
|
||||
|
|
|
@ -135,7 +135,6 @@
|
|||
--core-tab-border-color-active: #{$core-tab-border-color-active};
|
||||
|
||||
core-tabs, core-tabs-outlet {
|
||||
--background: var(--core-tabs-background);
|
||||
ion-slide {
|
||||
--background: var(--core-tab-background);
|
||||
--color: var(--core-tab-color);
|
||||
|
|
Loading…
Reference in New Issue