diff --git a/scripts/langindex.json b/scripts/langindex.json index d3cf2c75f..f0697bec7 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -2282,7 +2282,7 @@ "core.phone": "moodle", "core.pictureof": "moodle", "core.play": "local_moodlemobileapp", - "core.policy.policyaccept": "moodle", + "core.policy.havereadandagreepolicy": "local_moodlemobileapp", "core.policy.policyacceptmandatory": "local_moodlemobileapp", "core.policy.policyagree": "moodle", "core.policy.policyagreement": "moodle", diff --git a/src/core/features/policy/lang.json b/src/core/features/policy/lang.json index 66fdf8295..12b54abe9 100644 --- a/src/core/features/policy/lang.json +++ b/src/core/features/policy/lang.json @@ -1,5 +1,5 @@ { - "policyaccept": "I understand and agree", + "havereadandagreepolicy": "I have read and agree to the {{policyname}}", "policyacceptmandatory": "I understand and agree to the mandatory site policies", "policyagree": "You must agree to this policy to continue using this site. Do you agree?", "policyagreement": "Site policy agreement", diff --git a/src/core/features/policy/pages/site-policy/site-policy.html b/src/core/features/policy/pages/site-policy/site-policy.html index b17608f30..160a2b81b 100644 --- a/src/core/features/policy/pages/site-policy/site-policy.html +++ b/src/core/features/policy/pages/site-policy/site-policy.html @@ -4,35 +4,62 @@ - -

{{ 'core.policy.policyagreement' | translate }}

+ +

+ + + + + - + - +
-

{{ 'core.policy.policyagree' | translate }}

+

{{ 'core.policy.policyagreement' | translate }}

- - -

- {{ 'core.policy.policyagreementclick' | translate }} -

-
-
- - - - - {{ 'core.policy.policyacceptmandatory' | translate }} - - - {{ 'core.cancel' | translate }} - - +
+ + + + + + + +

+ + {{ 'core.policy.policyagreementclick' | translate }} +

+
+
+
+ +
+ + + + {{ 'core.policy.havereadandagreepolicy' | translate:{ policyname:'core.policy.policyagreement' | translate } }} + + + {{ 'core.policy.policyacceptmandatory' | translate }} + + + + + {{ 'core.continue' | translate }} + +
+
diff --git a/src/core/features/policy/pages/site-policy/site-policy.scss b/src/core/features/policy/pages/site-policy/site-policy.scss index fa7bca312..7192dca7b 100644 --- a/src/core/features/policy/pages/site-policy/site-policy.scss +++ b/src/core/features/policy/pages/site-policy/site-policy.scss @@ -1,20 +1,45 @@ +@use "theme/globals" as *; + :host { - ion-list { + hr { + background: var(--black); + margin: 0 16px; + } + + form { display: flex; flex-direction: column; + flex-grow: 1; height: 100%; - ion-item { + ion-item, .core-info-card { flex-shrink: 0; } - .core-site-policy-iframe-container { - height: 100%; + ion-item { + --inner-border-width: 0; + } - core-iframe { - height: 100%; - width: 100%; + .core-site-policy-link { + p { + text-decoration: underline; + font-size: 1rem; + + ion-icon { + font-size: 0.875rem; + @include margin-horizontal(4px, 0); + } } } + + .core-site-policy-iframe-container { + margin: 8px; + display: flex; + flex-grow: 1; + } + + ion-button[type="submit"] { + margin-bottom: 12px;; + } } } diff --git a/src/core/features/policy/pages/site-policy/site-policy.ts b/src/core/features/policy/pages/site-policy/site-policy.ts index 55997cbcc..55c057238 100644 --- a/src/core/features/policy/pages/site-policy/site-policy.ts +++ b/src/core/features/policy/pages/site-policy/site-policy.ts @@ -24,6 +24,7 @@ import { CoreEvents } from '@singletons/events'; import { CoreAnalytics, CoreAnalyticsEventType } from '@services/analytics'; import { Translate } from '@singletons'; import { CorePolicy } from '@features/policy/services/policy'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; /** * Page to accept a site policy. @@ -35,20 +36,26 @@ import { CorePolicy } from '@features/policy/services/policy'; }) export class CorePolicySitePolicyPage implements OnInit { - sitePolicy?: string; + siteName?: string; + isManageAcceptancesAvailable = false; + isPoliciesURL = false; + sitePoliciesURL?: string; showInline?: boolean; policyLoaded?: boolean; + policyForm?: FormGroup; + protected siteId?: string; protected currentSite!: CoreSite; /** * @inheritdoc */ - ngOnInit(): void { + async ngOnInit(): Promise { this.siteId = CoreNavigator.getRouteParam('siteId'); try { this.currentSite = CoreSites.getRequiredCurrentSite(); + this.siteName = (await CoreUtils.ignoreErrors(this.currentSite.getSiteName(), '')) || ''; } catch { // Not logged in, stop. this.cancel(); @@ -66,17 +73,36 @@ export class CorePolicySitePolicyPage implements OnInit { return; } - this.fetchSitePolicy(); + this.isManageAcceptancesAvailable = await CorePolicy.isManageAcceptancesAvailable(this.siteId); + this.isPoliciesURL = this.isManageAcceptancesAvailable ? + (await this.currentSite.getConfig('sitepolicyhandler')) !== 'tool_policy' : + true; // Site doesn't support managing acceptances, just display it as a URL. + + if (this.isPoliciesURL) { + this.initFormForPoliciesURL(); + + await this.fetchSitePoliciesURL(); + } else { + // TODO + } + + CoreAnalytics.logEvent({ + type: CoreAnalyticsEventType.VIEW_ITEM, + ws: 'auth_email_get_signup_settings', + name: Translate.instant('core.policy.policyagreement'), + data: { category: 'policy' }, + url: '/user/policy.php', + }); } /** - * Fetch the site policy URL. + * Fetch the site policies URL. * * @returns Promise resolved when done. */ - protected async fetchSitePolicy(): Promise { + protected async fetchSitePoliciesURL(): Promise { try { - this.sitePolicy = await CorePolicy.getSitePoliciesURL(this.siteId); + this.sitePoliciesURL = await CorePolicy.getSitePoliciesURL(this.siteId); } catch (error) { CoreDomUtils.showErrorModalDefault(error, 'Error getting site policy.'); this.cancel(); @@ -86,9 +112,9 @@ export class CorePolicySitePolicyPage implements OnInit { // Try to get the mime type. try { - const mimeType = await CoreUtils.getMimeTypeFromUrl(this.sitePolicy); + const mimeType = await CoreUtils.getMimeTypeFromUrl(this.sitePoliciesURL); - const extension = CoreMimetypeUtils.getExtension(mimeType, this.sitePolicy); + const extension = CoreMimetypeUtils.getExtension(mimeType, this.sitePoliciesURL); this.showInline = extension == 'html' || extension == 'htm'; } catch { // Unable to get mime type, assume it's not supported. @@ -96,13 +122,17 @@ export class CorePolicySitePolicyPage implements OnInit { } finally { this.policyLoaded = true; } + } - CoreAnalytics.logEvent({ - type: CoreAnalyticsEventType.VIEW_ITEM, - ws: 'auth_email_get_signup_settings', - name: Translate.instant('core.policy.policyagreement'), - data: { category: 'policy' }, - url: '/user/policy.php', + /** + * Init the form to accept the policies using a URL. + */ + protected initFormForPoliciesURL(): void { + this.policyForm = new FormGroup({ + agreepolicy: new FormControl(false, { + validators: Validators.requiredTrue, + nonNullable: true, + }), }); } @@ -118,11 +148,19 @@ export class CorePolicySitePolicyPage implements OnInit { } /** - * Accept the site policy. + * Submit the acceptances to one or several policies. * + * @param event Event. * @returns Promise resolved when done. */ - async accept(): Promise { + async submitAcceptances(event: Event): Promise { + event.preventDefault(); + event.stopPropagation(); + + if (!this.policyForm?.valid) { + return; + } + const modal = await CoreDomUtils.showModalLoading('core.sending', true); try { diff --git a/src/theme/theme.base.scss b/src/theme/theme.base.scss index 25b28b996..4ac4722f3 100644 --- a/src/theme/theme.base.scss +++ b/src/theme/theme.base.scss @@ -99,7 +99,9 @@ ion-item .in-item { // Correctly inherit ion-text-wrap onto labels. .item > ion-label, -.fake-ion-item { +.fake-ion-item, +.item.ion-text-wrap > ion-checkbox::part(label), +ion-checkbox.ion-text-wrap::part(label) { core-format-text, core-format-text > *:not(pre) { white-space: nowrap; @@ -110,7 +112,9 @@ ion-item .in-item { .item.ion-text-wrap > ion-label, ion-item > .in-item, -.fake-ion-item.ion-text-wrap { +.fake-ion-item.ion-text-wrap, +.item.ion-text-wrap > ion-checkbox::part(label), +ion-checkbox.ion-text-wrap::part(label) { core-format-text, core-format-text > *:not(pre) { white-space: normal; @@ -118,7 +122,9 @@ ion-item > .in-item, } } -.item.ion-text-wrap > ion-label { +.item.ion-text-wrap > ion-label, +.item.ion-text-wrap > ion-checkbox::part(label), +ion-checkbox.ion-text-wrap::part(label) { white-space: normal !important; }