diff --git a/README.md b/README.md index 0e7177ca4..6a9b10cc1 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,7 @@ # slate-cbl -Provides extensions for Slate to implement Competency-Based Learning +A sub-distribution of [Slate](https://github.com/SlateFoundation/slate) that provides a toolkit for operating a Competency-based (CBL) school. -See the [slate-cbl-book](https://github.com/SlateFoundation/slate-cbl-book) repository -for full end-user and contributor documentation. +## Getting started with development -## In this repository - -- `sencha-workspace/packages/slate-cbl`: Sencha CMD package containing shared client-side code -- Client-side UI applications: - - `sencha-workspace/SlateDemonstrationsTeacher`: Demonstrations dashboard for teachers - - `sencha-workspace/SlateDemonstrationsStudent`: Demonstrations dashboard for students - - `sencha-workspace/SlateTasksTeacher`: Tasks dashboard for teachers - - `sencha-workspace/SlateTasksStudent`: Tasks dashboard for students - - `sencha-workspace/SlateTasksManager`: Tasks library for all staff -- Server-side extensions for slate: - - `event-handlers/Slate/CBL/` - - `html-templates/cbl/` - - `php-classes/Slate/CBL` - - `php-migrations/Slate/CBL` - - `site-root/cbl/` - - `site-root/img/cbl/` - -## Technologies used - -- [Emergence](http://emergence.sh): Open toolkit for building and running web applications -- [Slate](http://slate.is): Foundational web application for schools -- [Sencha Ext JS 6 Classic](http://docs.sencha.com/extjs/6.2.0/): Web-based UI framework with rich components library -- Sencha CMD 6.x: Build tools for web UI applications built with Sencha Ext JS -- [Habitat](http://habitat.sh): Provides portable and isolated environments for testing and building - -## Getting started with client-side UI application development - -See [Getting Started with Development](./books/slate-cbl/development/getting_started.md) - -## Installing to a `v2.slate.is` server - -1. Copy [sample `slate-cbl.php` git config script](https://github.com/SlateFoundation/slate-cbl/blob/releases/v2/php-config/Git.config.d/slate-cbl.php) into site -1. Visit `/site-admin/sources` and initialize the `slate-cbl` source -1. Return to `/site-admin/sources/slate-cbl` and click SyncUpdate emergence VFS for the `slate-cbl` layer -1. Build each app: - - `/sencha-cmd/app-build?name=SlateTasksTeacher` - - `/sencha-cmd/app-build?name=SlateTasksStudent` - - `/sencha-cmd/app-build?name=SlateTasksManager` - - `/sencha-cmd/app-build?name=SlateDemonstrationsTeacher` - - `/sencha-cmd/app-build?name=SlateDemonstrationsStudent` +See diff --git a/cypress/integration/cbl/tasks/student-dashboard.js b/cypress/integration/cbl/tasks/student-dashboard.js index 097e63bc2..fdd5d1612 100644 --- a/cypress/integration/cbl/tasks/student-dashboard.js +++ b/cypress/integration/cbl/tasks/student-dashboard.js @@ -245,6 +245,9 @@ describe('CBL / Tasks / Student Dashboard: Workflows', () => { _deselectAllFilters(); _selectFilter('Due Tasks', '.slate-tasktree-status-due, .slate-tasktree-status-late'); + // close filter menu to prevent interference with opening task + _clickFilterButton(); + // open recently created task cy.extGet('slate-tasks-student-tasktree') .find(`.slate-tasktree-item[data-id=${studentTaskId}]`) diff --git a/php-classes/Slate/CBL/Demonstrations/DemonstrationSkill.php b/php-classes/Slate/CBL/Demonstrations/DemonstrationSkill.php index 08f9a3ca6..b345040cc 100644 --- a/php-classes/Slate/CBL/Demonstrations/DemonstrationSkill.php +++ b/php-classes/Slate/CBL/Demonstrations/DemonstrationSkill.php @@ -2,12 +2,14 @@ namespace Slate\CBL\Demonstrations; +use Emergence\People\IPerson; + use Slate\CBL\Skill; use Slate\CBL\StudentCompetency; class DemonstrationSkill extends \VersionedRecord { - public static $allowTargetLevelChanges = false; + public static $allowTargetLevelChanges = 'Administrator'; // ActiveRecord configuration public static $tableName = 'cbl_demonstration_skills'; @@ -86,7 +88,7 @@ public function validate($deep = true) } // target level can only be set on new records - if (!static::$allowTargetLevelChanges && !$this->isPhantom && $this->isFieldDirty('TargetLevel')) { + if (!$this->isPhantom && $this->isFieldDirty('TargetLevel') && !$this->userCanChangeLevel()) { $this->_validator->addError('TargetLevel', 'TargetLevel cannot be changed on existing records'); } @@ -103,4 +105,31 @@ public function save($deep = true) return parent::save($deep); } -} \ No newline at end of file + + public function getAvailableActions(IPerson $User = null) + { + $User = $User ?: $this->getUserFromEnvironment(); + + $actions = parent::getAvailableActions($User); + + $actions['change-level'] = $this->userCanChangeLevel($User); + + return $actions; + } + + public function userCanChangeLevel(IPerson $User = null) + { + if (static::$allowTargetLevelChanges === true) { + return true; + } + + if (static::$allowTargetLevelChanges === false) { + return false; + } + + $User = $User ?: $this->getUserFromEnvironment(); + + return $User && $User->hasAccountLevel(static::$allowTargetLevelChanges); + } + +} diff --git a/sencha-workspace/SlateTasksStudent/app/controller/Tasks.js b/sencha-workspace/SlateTasksStudent/app/controller/Tasks.js index c6febb647..0d9dfae51 100644 --- a/sencha-workspace/SlateTasksStudent/app/controller/Tasks.js +++ b/sencha-workspace/SlateTasksStudent/app/controller/Tasks.js @@ -71,7 +71,8 @@ Ext.define('SlateTasksStudent.controller.Tasks', { minHeight: 200, mainView: { - xtype: 'slate-cbl-tasks-studenttaskform' + xtype: 'slate-cbl-tasks-studenttaskform', + displayRemovedTasks: false } }, formPanel: 'slate-cbl-tasks-studenttaskform', diff --git a/sencha-workspace/packages/slate-cbl/src/field/attachments/Field.js b/sencha-workspace/packages/slate-cbl/src/field/attachments/Field.js index 3e5bfd391..49e16fee2 100644 --- a/sencha-workspace/packages/slate-cbl/src/field/attachments/Field.js +++ b/sencha-workspace/packages/slate-cbl/src/field/attachments/Field.js @@ -24,7 +24,8 @@ Ext.define('Slate.cbl.field.attachments.Field', { ], toolbar: true, - fieldLabel: 'Attachments' + fieldLabel: 'Attachments', + displayRemoved: true }, @@ -174,12 +175,30 @@ Ext.define('Slate.cbl.field.attachments.Field', { return normalValue; }, + filterRemovedItems: function(value) { + var me = this, + displayRemoved = me.getDisplayRemoved(), + filteredValue = [], + length = value ? value.length : 0, + i = 0; + + for (; i < length; i++) { + if (displayRemoved || value[i].Status.toLowerCase() !== 'removed') { + filteredValue.push(value[i]); + } + } + + return filteredValue; + }, + setValue: function(value) { var me = this, listCt = me.listCt, valueItemsMap = me.valueItemsMap = {}, - length = value ? value.length : 0, - i = 0, itemValue, itemClass, Attachment, attachmentItem; + i = 0, length, itemValue, itemClass, Attachment, attachmentItem; + + // filter out items marked as 'removed' if applicable + value = me.filterRemovedItems(value); // clone value to normalized array value = me.normalizeValue(value); @@ -191,6 +210,8 @@ Ext.define('Slate.cbl.field.attachments.Field', { ++me.suspendCheckChange; listCt.removeAll(); + length = value ? value.length : 0; + for (; i < length; i++) { itemValue = value[i]; itemClass = itemValue.Class; diff --git a/sencha-workspace/packages/slate-cbl/src/view/tasks/StudentTaskForm.js b/sencha-workspace/packages/slate-cbl/src/view/tasks/StudentTaskForm.js index 093663b7f..f759b6a38 100644 --- a/sencha-workspace/packages/slate-cbl/src/view/tasks/StudentTaskForm.js +++ b/sencha-workspace/packages/slate-cbl/src/view/tasks/StudentTaskForm.js @@ -62,6 +62,7 @@ Ext.define('Slate.cbl.view.tasks.StudentTaskForm', function() { config: { studentTask: null, + displayRemovedTasks: true, statusField: { merge: mergeFn, @@ -521,6 +522,10 @@ Ext.define('Slate.cbl.view.tasks.StudentTaskForm', function() { applySaveBtn: applyFn, applySubmitBtn: applyFn, + updateDisplayRemovedTasks(displayRemovedTasks) { + this.getTaskAttachmentsField().setDisplayRemoved(displayRemovedTasks); + }, + // component lifecycle initItems: function() {