mirror of
https://github.com/nextcloud/integration_moodle.git
synced 2025-12-17 21:02:05 +01:00
refs #17 add admin option to globally disable search
Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
This commit is contained in:
parent
4e4e753df1
commit
163893a679
12 changed files with 290 additions and 5 deletions
|
|
@ -5,7 +5,7 @@
|
||||||
<summary>Integration of Moodle learning management system</summary>
|
<summary>Integration of Moodle learning management system</summary>
|
||||||
<description><![CDATA[Moodle integration provides a dashboard widget displaying information about your recent courses and upcoming events.
|
<description><![CDATA[Moodle integration provides a dashboard widget displaying information about your recent courses and upcoming events.
|
||||||
It also allows you to search for content in Moodle.]]></description>
|
It also allows you to search for content in Moodle.]]></description>
|
||||||
<version>0.0.6</version>
|
<version>0.0.7</version>
|
||||||
<licence>agpl</licence>
|
<licence>agpl</licence>
|
||||||
<author>Julien Veyssier</author>
|
<author>Julien Veyssier</author>
|
||||||
<namespace>Moodle</namespace>
|
<namespace>Moodle</namespace>
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
<nextcloud min-version="20" max-version="21"/>
|
<nextcloud min-version="20" max-version="21"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<settings>
|
<settings>
|
||||||
|
<admin>OCA\Moodle\Settings\Admin</admin>
|
||||||
|
<admin-section>OCA\Moodle\Settings\AdminSection</admin-section>
|
||||||
<personal>OCA\Moodle\Settings\Personal</personal>
|
<personal>OCA\Moodle\Settings\Personal</personal>
|
||||||
<personal-section>OCA\Moodle\Settings\PersonalSection</personal-section>
|
<personal-section>OCA\Moodle\Settings\PersonalSection</personal-section>
|
||||||
</settings>
|
</settings>
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
return [
|
return [
|
||||||
'routes' => [
|
'routes' => [
|
||||||
['name' => 'config#setConfig', 'url' => '/config', 'verb' => 'PUT'],
|
['name' => 'config#setConfig', 'url' => '/config', 'verb' => 'PUT'],
|
||||||
|
['name' => 'config#setAdminConfig', 'url' => '/admin-config', 'verb' => 'PUT'],
|
||||||
['name' => 'moodleAPI#getNotifications', 'url' => '/notifications', 'verb' => 'GET'],
|
['name' => 'moodleAPI#getNotifications', 'url' => '/notifications', 'verb' => 'GET'],
|
||||||
['name' => 'moodleAPI#getMoodleUrl', 'url' => '/url', 'verb' => 'GET'],
|
['name' => 'moodleAPI#getMoodleUrl', 'url' => '/url', 'verb' => 'GET'],
|
||||||
['name' => 'moodleAPI#getMoodleAvatar', 'url' => '/avatar', 'verb' => 'GET'],
|
['name' => 'moodleAPI#getMoodleAvatar', 'url' => '/avatar', 'verb' => 'GET'],
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ namespace OCA\Moodle\AppInfo;
|
||||||
|
|
||||||
use OCP\IContainer;
|
use OCP\IContainer;
|
||||||
|
|
||||||
|
use OCP\IConfig;
|
||||||
use OCP\AppFramework\App;
|
use OCP\AppFramework\App;
|
||||||
use OCP\AppFramework\IAppContainer;
|
use OCP\AppFramework\IAppContainer;
|
||||||
use OCP\AppFramework\Bootstrap\IRegistrationContext;
|
use OCP\AppFramework\Bootstrap\IRegistrationContext;
|
||||||
|
|
@ -41,13 +42,17 @@ class Application extends App implements IBootstrap {
|
||||||
parent::__construct(self::APP_ID, $urlParams);
|
parent::__construct(self::APP_ID, $urlParams);
|
||||||
|
|
||||||
$container = $this->getContainer();
|
$container = $this->getContainer();
|
||||||
|
$this->config = $container->query(IConfig::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function register(IRegistrationContext $context): void {
|
public function register(IRegistrationContext $context): void {
|
||||||
$context->registerDashboardWidget(MoodleWidget::class);
|
$context->registerDashboardWidget(MoodleWidget::class);
|
||||||
$context->registerSearchProvider(MoodleSearchCoursesProvider::class);
|
|
||||||
$context->registerSearchProvider(MoodleSearchModulesProvider::class);
|
if ($this->config->getAppValue(self::APP_ID, 'search_disabled', '0') === '0') {
|
||||||
$context->registerSearchProvider(MoodleSearchUpcomingProvider::class);
|
$context->registerSearchProvider(MoodleSearchCoursesProvider::class);
|
||||||
|
$context->registerSearchProvider(MoodleSearchModulesProvider::class);
|
||||||
|
$context->registerSearchProvider(MoodleSearchUpcomingProvider::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(IBootContext $context): void {
|
public function boot(IBootContext $context): void {
|
||||||
|
|
|
||||||
|
|
@ -84,4 +84,18 @@ class ConfigController extends Controller {
|
||||||
$response = new DataResponse(1);
|
$response = new DataResponse(1);
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set admin config values
|
||||||
|
*
|
||||||
|
* @param array $values
|
||||||
|
* @return DataResponse
|
||||||
|
*/
|
||||||
|
public function setAdminConfig(array $values): DataResponse {
|
||||||
|
foreach ($values as $key => $value) {
|
||||||
|
$this->config->setAppValue(Application::APP_ID, $key, $value);
|
||||||
|
}
|
||||||
|
$response = new DataResponse(1);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
59
lib/Settings/Admin.php
Normal file
59
lib/Settings/Admin.php
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
namespace OCA\Moodle\Settings;
|
||||||
|
|
||||||
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\IL10N;
|
||||||
|
use OCP\IConfig;
|
||||||
|
use OCP\Settings\ISettings;
|
||||||
|
use OCP\Util;
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
use OCP\IInitialStateService;
|
||||||
|
|
||||||
|
use OCA\Moodle\AppInfo\Application;
|
||||||
|
|
||||||
|
class Admin implements ISettings {
|
||||||
|
|
||||||
|
private $request;
|
||||||
|
private $config;
|
||||||
|
private $dataDirPath;
|
||||||
|
private $urlGenerator;
|
||||||
|
private $l;
|
||||||
|
|
||||||
|
public function __construct(string $appName,
|
||||||
|
IL10N $l,
|
||||||
|
IRequest $request,
|
||||||
|
IConfig $config,
|
||||||
|
IURLGenerator $urlGenerator,
|
||||||
|
IInitialStateService $initialStateService,
|
||||||
|
$userId) {
|
||||||
|
$this->appName = $appName;
|
||||||
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
$this->request = $request;
|
||||||
|
$this->l = $l;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->initialStateService = $initialStateService;
|
||||||
|
$this->userId = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return TemplateResponse
|
||||||
|
*/
|
||||||
|
public function getForm(): TemplateResponse {
|
||||||
|
$searchDisabled = $this->config->getAppValue(Application::APP_ID, 'search_disabled', '0') === '1';
|
||||||
|
|
||||||
|
$adminConfig = [
|
||||||
|
'search_disabled' => $searchDisabled,
|
||||||
|
];
|
||||||
|
$this->initialStateService->provideInitialState($this->appName, 'admin-config', $adminConfig);
|
||||||
|
return new TemplateResponse(Application::APP_ID, 'adminSettings');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSection(): string {
|
||||||
|
return 'connected-accounts';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority(): int {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
60
lib/Settings/AdminSection.php
Normal file
60
lib/Settings/AdminSection.php
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?php
|
||||||
|
namespace OCA\Moodle\Settings;
|
||||||
|
|
||||||
|
use OCP\IURLGenerator;
|
||||||
|
use OCP\IL10N;
|
||||||
|
use OCP\Settings\IIconSection;
|
||||||
|
|
||||||
|
class AdminSection implements IIconSection {
|
||||||
|
|
||||||
|
/** @var IL10N */
|
||||||
|
private $l;
|
||||||
|
|
||||||
|
/** @var IURLGenerator */
|
||||||
|
private $urlGenerator;
|
||||||
|
|
||||||
|
public function __construct(string $appName,
|
||||||
|
IURLGenerator $urlGenerator,
|
||||||
|
IL10N $l
|
||||||
|
) {
|
||||||
|
$this->appName = $appName;
|
||||||
|
$this->l = $l;
|
||||||
|
$this->urlGenerator = $urlGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the ID of the section. It is supposed to be a lower case string
|
||||||
|
*
|
||||||
|
* @returns string
|
||||||
|
*/
|
||||||
|
public function getID(): string {
|
||||||
|
return 'connected-accounts'; //or a generic id if feasible
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the translated name as it should be displayed, e.g. 'LDAP / AD
|
||||||
|
* integration'. Use the L10N service to translate it.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName(): string {
|
||||||
|
return $this->l->t('Connected accounts');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int whether the form should be rather on the top or bottom of
|
||||||
|
* the settings navigation. The sections are arranged in ascending order of
|
||||||
|
* the priority values. It is required to return a value between 0 and 99.
|
||||||
|
*/
|
||||||
|
public function getPriority(): int {
|
||||||
|
return 80;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ?string The relative path to a an icon describing the section
|
||||||
|
*/
|
||||||
|
public function getIcon(): ?string {
|
||||||
|
return $this->urlGenerator->imagePath('core', 'categories/integration.svg');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -49,6 +49,8 @@ class Personal implements ISettings {
|
||||||
$userName = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_name', '');
|
$userName = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_name', '');
|
||||||
$checkSsl = $this->config->getUserValue($this->userId, Application::APP_ID, 'check_ssl', '1') === '1';
|
$checkSsl = $this->config->getUserValue($this->userId, Application::APP_ID, 'check_ssl', '1') === '1';
|
||||||
|
|
||||||
|
$searchDisabled = $this->config->getAppValue(Application::APP_ID, 'search_disabled', '0') === '1';
|
||||||
|
|
||||||
$userConfig = [
|
$userConfig = [
|
||||||
'token' => $token,
|
'token' => $token,
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
|
|
@ -57,6 +59,7 @@ class Personal implements ISettings {
|
||||||
'search_upcoming_enabled' => ($searchUpcomingEnabled === '1'),
|
'search_upcoming_enabled' => ($searchUpcomingEnabled === '1'),
|
||||||
'user_name' => $userName,
|
'user_name' => $userName,
|
||||||
'check_ssl' => $checkSsl,
|
'check_ssl' => $checkSsl,
|
||||||
|
'search_disabled' => $searchDisabled,
|
||||||
];
|
];
|
||||||
$this->initialStateService->provideInitialState($this->appName, 'user-config', $userConfig);
|
$this->initialStateService->provideInitialState($this->appName, 'user-config', $userConfig);
|
||||||
return new TemplateResponse(Application::APP_ID, 'personalSettings');
|
return new TemplateResponse(Application::APP_ID, 'personalSettings');
|
||||||
|
|
|
||||||
25
src/adminSettings.js
Normal file
25
src/adminSettings.js
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* jshint esversion: 6 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - moodle
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Julien Veyssier <eneiluj@posteo.net>
|
||||||
|
* @copyright Julien Veyssier 2021
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Vue from 'vue'
|
||||||
|
import './bootstrap'
|
||||||
|
import AdminSettings from './components/AdminSettings'
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
new Vue({
|
||||||
|
el: '#moodle_prefs',
|
||||||
|
render: h => h(AdminSettings),
|
||||||
|
})
|
||||||
109
src/components/AdminSettings.vue
Normal file
109
src/components/AdminSettings.vue
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
<template>
|
||||||
|
<div id="moodle_prefs" class="section">
|
||||||
|
<h2>
|
||||||
|
<a class="icon icon-moodle" />
|
||||||
|
{{ t('integration_moodle', 'Moodle integration') }}
|
||||||
|
</h2>
|
||||||
|
<div class="grid-form">
|
||||||
|
<input
|
||||||
|
id="disable-search"
|
||||||
|
type="checkbox"
|
||||||
|
class="checkbox"
|
||||||
|
:checked="state.search_disabled"
|
||||||
|
@input="onCheckSearchChange">
|
||||||
|
<label for="disable-search">{{ t('integration_moodle', 'Disable search for all users') }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { loadState } from '@nextcloud/initial-state'
|
||||||
|
import { generateUrl } from '@nextcloud/router'
|
||||||
|
import axios from '@nextcloud/axios'
|
||||||
|
import { showSuccess, showError } from '@nextcloud/dialogs'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AdminSettings',
|
||||||
|
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
|
||||||
|
props: [],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
state: loadState('integration_moodle', 'admin-config'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onCheckSearchChange(e) {
|
||||||
|
this.state.search_disabled = e.target.checked
|
||||||
|
this.saveOptions({ search_disabled: this.state.search_disabled ? '1' : '0' })
|
||||||
|
},
|
||||||
|
saveOptions(values) {
|
||||||
|
const req = {
|
||||||
|
values,
|
||||||
|
}
|
||||||
|
const url = generateUrl('/apps/integration_moodle/admin-config')
|
||||||
|
axios.put(url, req)
|
||||||
|
.then((response) => {
|
||||||
|
showSuccess(t('integration_moodle', 'Moodle admin options saved'))
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
showError(
|
||||||
|
t('integration_moodle', 'Failed to save Moodle admin options')
|
||||||
|
+ ': ' + (error.response?.request?.responseText ?? '')
|
||||||
|
)
|
||||||
|
console.debug(error)
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.grid-form label {
|
||||||
|
line-height: 38px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-form input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-form {
|
||||||
|
max-width: 500px;
|
||||||
|
display: grid;
|
||||||
|
grid-template: 1fr / 1fr 1fr;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#moodle_prefs .icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#moodle_prefs .grid-form .icon {
|
||||||
|
margin-bottom: -3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-moodle {
|
||||||
|
background-image: url(./../../img/app-dark.svg);
|
||||||
|
background-size: 23px 23px;
|
||||||
|
height: 23px;
|
||||||
|
margin-bottom: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.theme--dark .icon-moodle {
|
||||||
|
background-image: url(./../../img/app.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
@input="onCheckSslChange">
|
@input="onCheckSslChange">
|
||||||
<label for="check-ssl-moodle">{{ t('integration_moodle', 'Check SSL certificate') }}</label>
|
<label for="check-ssl-moodle">{{ t('integration_moodle', 'Check SSL certificate') }}</label>
|
||||||
<br>
|
<br>
|
||||||
<div v-if="connected" id="moodle-search-block">
|
<div v-if="connected && !state.search_disabled" id="moodle-search-block">
|
||||||
<input
|
<input
|
||||||
id="search-moodle-courses"
|
id="search-moodle-courses"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
|
|
||||||
6
templates/adminSettings.php
Normal file
6
templates/adminSettings.php
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
$appId = OCA\Moodle\AppInfo\Application::APP_ID;
|
||||||
|
script($appId, $appId . '-adminSettings');
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div id="moodle_prefs"></div>
|
||||||
|
|
@ -12,6 +12,7 @@ webpackConfig.stats = {
|
||||||
|
|
||||||
webpackConfig.entry = {
|
webpackConfig.entry = {
|
||||||
personalSettings: { import: path.join(__dirname, 'src', 'personalSettings.js'), filename: 'integration_moodle-personalSettings.js' },
|
personalSettings: { import: path.join(__dirname, 'src', 'personalSettings.js'), filename: 'integration_moodle-personalSettings.js' },
|
||||||
|
adminSettings: { import: path.join(__dirname, 'src', 'adminSettings.js'), filename: 'integration_moodle-adminSettings.js' },
|
||||||
dashboard: { import: path.join(__dirname, 'src', 'dashboard.js'), filename: 'integration_moodle-dashboard.js' },
|
dashboard: { import: path.join(__dirname, 'src', 'dashboard.js'), filename: 'integration_moodle-dashboard.js' },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue