Commit 6eed502e authored by mathieso's avatar mathieso

In RI GUI, only one response option editing form showing at a time.

parent 1c9a1630
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,8 +8,6 @@
"dev": "vue-cli-service build --mode development"
},
"dependencies": {
"@ckeditor/ckeditor5-build-classic": "^18.0.0",
"@ckeditor/ckeditor5-vue": "^1.0.1",
"axios": "^0.19.2",
"core-js": "^3.6.4",
"sortablejs": "^1.10.2",
......
......@@ -46,11 +46,14 @@
<view-add-edit-response-option
class="response-option-sortable"
v-for="responseOption in getResponseOptions()"
ref="responseOption"
:key="responseOption.responseOptionId"
:responseOption="responseOption"
:rubricItemId="rubricItem.rubricItemId"
v-on:delete-response-option="deleteResponseOption"
v-on:move-response-option="moveResponseOption"
v-on:disable-editing="disableResponseOptionEditing"
v-on:enable-editing="enableResponseOptionEditing"
></view-add-edit-response-option>
</div>
<div>
......@@ -63,12 +66,18 @@
<p class="container-label">
<label for="notes"><strong>Notes</strong></label>
</p>
<ckeditor
id="notes"
:editor="editor"
v-model="rubricItem.notes"
:config="editorConfig">
</ckeditor>
<p>
<textarea
id="notes"
v-model="rubricItem.notes"
></textarea>
</p>
<!-- <ckeditor-->
<!-- id="notes"-->
<!-- :editor="editor"-->
<!-- v-model="rubricItem.notes"-->
<!-- :config="editorConfig">-->
<!-- </ckeditor>-->
</div>
</div>
<div id="footer">
......@@ -80,7 +89,6 @@
<script>
import ViewAddEditResponseOption from "./ViewAddEditResponseOption.vue";
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
export default {
components: {
......@@ -89,10 +97,9 @@
data() {
return {
numNewResponseOptionsCreated: 0,
editor: ClassicEditor,
editorConfig: {
toolbar: [ 'bold', 'italic', '|', 'link' ]
}
// editorConfig: {
// toolbar: [ 'bold', 'italic', '|', 'link' ]
// }
}
},
props: {
......@@ -119,11 +126,29 @@
}
},
methods: {
disableResponseOptionEditing() {
// console.log("start disableResponseOptionEditing" );
for(const index in this.$refs.responseOption) {
const ro = this.$refs.responseOption[index];
// console.log("ro", ro);
ro.setEditable(false);
}
// console.log("end disableResponseOptionEditing");
},
enableResponseOptionEditing() {
// console.log("start enableResponseOptionEditing");
for(const index in this.$refs.responseOption) {
const ro = this.$refs.responseOption[index];
// console.log("ro", ro);
ro.setEditable(true);
}
// console.log("end enableResponseOptionEditing");
},
closeModal() {
this.$modal.hide('edit-form-modal');
},
moveResponseOption(params) {
console.log(" moveResponseOption params", params);
// console.log(" moveResponseOption params", params);
this.$store.dispatch("moveResponseOptionAction", params)
.then(window.eventBus.$emit(
"rubric-item-response-option-moved",
......@@ -160,7 +185,7 @@
* Delete a response option
*/
deleteResponseOption(responseOptionId) {
console.log("deleteResponseOption responseOptionId", responseOptionId);
// console.log("deleteResponseOption responseOptionId", responseOptionId);
let params = {
rubricItemId: this.rubricItem.rubricItemId,
responseOptionId: responseOptionId
......@@ -196,7 +221,7 @@
let newResponseOption = this.$store.getters.getNewResponseOptionTemplate();
// Set a unique id for the new option.
newResponseOption.responseOptionId = "new" + this.numNewResponseOptionsCreated;
console.log("addResponseOption newResponseOption", newResponseOption);
// console.log("addResponseOption newResponseOption", newResponseOption);
this.numNewResponseOptionsCreated ++;
// Ask store to make it.
this.$store.dispatch("addResponseOptionAction", newResponseOption);
......@@ -209,41 +234,7 @@
}
},
mounted() {
console.log("mounting add edit RI");
// let el = jQuery(".sortable-children").get(0);
// console.log("el", el);
// let sortableRIs = Sortable.create(el, {
// draggable: ".response-option-sortable"
// });
// let thing = this;
// // Prevent dragged element form receiving click event.
// jQuery(".sortable-children").sortable({
// start: function( event, ui ) {
// event.target.style.pointerEvents = 'none';
// },
// stop: function( event, ui ) {
// event.target.style.pointerEvents = 'auto';
// }
// });
// // When sorting stops, remember new order.
// jQuery( ".sortable-children" ).on( "sortstop", function( event, ui ) {
// // console.log("rosie");
// let ids = jQuery('.response-option-display').map(function(i) {
// return jQuery(this).data("response-option-id");
// }).get();
// // console.log("rosie done", ids);
// // console.log("RI", thing.rubricItem);
// let params = {
// rubricItemId: thing.rubricItem.rubricItemId,
// newList: ids
// };
// thing.$store.dispatch("replaceResponseOptionArrayAction", params);
// } );
// console.log("sortable-children", $(".sortable-children"));
// console.log("done mounting add edit RI");
// console.log("mounting add edit RI");
}
}
</script>
......
......@@ -21,7 +21,8 @@
<button class="button button--primary skilling-small" type="button" title="Move down"
@click.stop="moveDown">&#x2193;</button>
<button class="button button--primary skilling-small" type="button" title="Edit"
@click.stop="editMode">Edit</button>
@click.stop="editMode"
:disabled="!editEnabled">Edit</button>
<button class="button button--primary skilling-small" type="button" title="Delete"
@click.stop="deleteResponseOption">X</button>
</div>
......@@ -63,16 +64,22 @@
<!-- Edit the response option. -->
<div>
<label for="response-text">Response text</label><br>
<ckeditor
<textarea
id="response-text"
:editor="editor"
v-model="responseOption.name"
@change="changeName()"
aria-describedby="response-text-help"
:config="editorConfig">
</ckeditor>
></textarea><br>
<!-- <ckeditor-->
<!-- id="response-text"-->
<!-- :editor="editor"-->
<!-- v-model="responseOption.name"-->
<!-- @change="changeName()"-->
<!-- aria-describedby="response-text-help"-->
<!-- :config="editorConfig">-->
<!-- </ckeditor>-->
<small id="response-text-help" class="form-text text-muted">
E.g., Good indenting!
E.g., Good indenting! HTML, can have links.
</small>
</div>
<div id="completes-container">
......@@ -94,13 +101,20 @@
></applies-to-exercises-widget>
<div id="notes-container">
<label for="notes">Notes</label><br>
<ckeditor
<textarea
id="notes"
:editor="editor"
v-model="responseOption.notes"
:config="editorConfig">
</ckeditor>
aria-describedby="notes-help"
></textarea>
<small id="notes-help" class="form-text text-muted">
Use HTML.
</small>
<!-- <ckeditor-->
<!-- id="notes"-->
<!-- :editor="editor"-->
<!-- v-model="responseOption.notes"-->
<!-- :config="editorConfig">-->
<!-- </ckeditor>-->
</div>
<p class="done-button-container">
<button class="button button--primary" type="button" title="Done"
......@@ -112,7 +126,6 @@
<script>
import AppliesToExercisesWidget from "./AppliesToExercisesWidget.vue";
import ClassicEditor from "@ckeditor/ckeditor5-build-classic";
export default {
components: {
......@@ -121,20 +134,25 @@
data: function() {
return {
displayMode: "view",
editor: ClassicEditor,
editorConfig: {
toolbar: [ 'bold', 'italic', '|', 'link' ]
}
editEnabled: true
// editorConfig: {
// toolbar: [ 'bold', 'italic', '|', 'link' ]
// }
}
},
props: [
"responseOption",
"rubricItemId",
"exerciseId"
"exerciseId",
// "editEnabled"
],
computed: {
},
methods: {
setEditable(isEditable) {
// console.log("setEditable", isEditable, this.responseOption.name);
this.editEnabled = isEditable;
},
moveUp() {
let params = {
rubricItemId: this.rubricItemId,
......@@ -154,8 +172,8 @@
this.$emit("move-response-option", params);
},
isResponseOptionAppliesToExercise() {
console.log("isResponseOptionAppliesToExercise this.exerciseId", this.exerciseId);
let currentExerciseId = this.$store.getters.getCurrentExerciseId();
// console.log("isResponseOptionAppliesToExercise this.exerciseId", this.exerciseId);
// If applies to list is MT, then it applies.
if (this.responseOption.appliesToExerciseIds.length === 0) {
return true;
......@@ -163,11 +181,11 @@
//Is current exercise in the applies to array?
let foundIt = this.responseOption.appliesToExerciseIds.find(
function (exerciseIdAppliesTo) {
console.log("exerciseIdAppliesTo", exerciseIdAppliesTo);
// console.log("exerciseIdAppliesTo", exerciseIdAppliesTo);
return exerciseIdAppliesTo == currentExerciseId;
}
);
console.log("foundIt", foundIt);
// console.log("foundIt", foundIt);
return foundIt ? true : false;
},
listAppliesToExercises() {
......@@ -181,10 +199,16 @@
return exercises;
},
editMode() {
// console.log("component edit mode");
// console.log("this.editEnabled", this.editEnabled);
this.$emit("disable-editing");
this.displayMode = "form";
},
viewMode() {
this.displayMode = "view";
// console.log("component view mode");
// console.log("this.editEnabled", this.editEnabled);
this.$emit("enable-editing");
},
deleteResponseOption() {
let name = this.responseOption.name;
......
......@@ -3,7 +3,6 @@ import Vue from 'vue';
import App from './App.vue';
import store from './store/index.js';
import VModal from 'vue-js-modal';
import CKEditor from '@ckeditor/ckeditor5-vue';
(function ($, Drupal) {
"use strict";
......@@ -31,20 +30,32 @@ import CKEditor from '@ckeditor/ckeditor5-vue';
// Adapted from https://vegibit.com/vue-sibling-component-communication/
window.eventBus = new Vue();
Vue.config.productionTip = false;
Vue.use(CKEditor);
// Vue.use(CKEditor);
Vue.use(VModal);
let vueInstance = new Vue({
store,
render: h => h(App)
}).$mount('#app');
jQuery("form.node-exercise-edit-form").on("submit", function(e) {
// Which form?
// Look for add node form first.
let insertForms = jQuery("form.node-exercise-form");
let editForms = jQuery("form.node-exercise-edit-form");
let theForm = null;
if (insertForms.length === 0) {
theForm = $(editForms).get(0);
}
else {
theForm = $(insertForms).get(0);
}
console.log("theForm", theForm);
// jQuery("form.node-exercise-edit-form").on("submit", function(e) {
$(theForm).on("submit", function(e) {
// Cancel download, if running.
window.axiosCanceler.cancel();
// Get the data to send.
let allTheThings = window.vueInstance.$store.getters.getAllTheThings();
jQuery("input[name='rubric_item_chooser_return']").val(JSON.stringify(allTheThings));
console.log("allTheThings", allTheThings);
// e.preventDefault();
});
window.vueInstance = vueInstance;
// console.log("leave doc ready");
......
......@@ -690,13 +690,16 @@ export default new Vuex.Store({
},
getNewRubricItemTemplate(state) {
return function() {
let clone = Object.assign({}, state.newRubricItemTemplate);
let clone = JSON.parse(JSON.stringify(state.newRubricItemTemplate));
console.log("", );
return clone;
}
},
getNewResponseOptionTemplate(state) {
return function() {
let clone = Object.assign({}, state.newResponseOptionTemplate);
console.log("state.newResponseOptionTemplate", state.newResponseOptionTemplate);
let clone = JSON.parse(JSON.stringify(state.newResponseOptionTemplate));
console.log("clone", clone);
return clone;
}
},
......@@ -705,6 +708,7 @@ export default new Vuex.Store({
*/
getAllTheThings(state) {
return function() {
console.log("start getAllTheThings" );
let allTheThings = {
rubricItems: state.rubricItems,
responseOptions: state.responseOptions
......@@ -713,6 +717,7 @@ export default new Vuex.Store({
let rubricItemOrder = [];
jQuery("#rubric-item-list").find(".rubric-item").each(
function(index, element) {
console.log("element", element);
let rubricItemId = jQuery(element).data("rubric-item-id");
if (!rubricItemId) {
alert("getAllTheThings: rubricItemId missing");
......
......@@ -29,7 +29,7 @@ Students can see own history
# Exercises and f/b
Add multifield for exercies on due, even if just use first one.
Add multifield for exercises on due, even if just use first one.
# Testing
......
......@@ -275,7 +275,6 @@ rubric-item-chooser:
- skilling/skilling-utils
- skilling/vue-js
- skilling/vuex
- skilling/ckeditor-vue
- skilling/sortablejs
vue-js:
remote: https://github.com/vuejs/vue
......@@ -304,13 +303,6 @@ sortablejs:
gpl-compatible: true
js:
https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.10.1/Sortable.min.js: { type: external, minified: true }
ckeditor-vue:
version: 4.1.4
js:
libraries/ckeditor-vue/ckeditor.js: {minified: true}
libraries/ckeditor-vue/config.js: {minified: true}
libraries/ckeditor-vue/styles.js: {minified: true}
libraries/ckeditor-vue/ckeditor-vue.js: {minified: true}
progress-score-base-change:
version: 1.x
css:
......
......@@ -235,7 +235,7 @@ function skilling_alter_exercise_edit_form(&$form, FormStateInterface $form_stat
// $form['#attached']['library'][] = 'skilling/rubric-item-chooser';
$form['rubric_item_chooser'] = [
'#markup' => '<div id="app"></div>',
'#weight' => 100,
'#weight' => 5,
'#attached' => [
'library' => [
'skilling/rubric-item-chooser',
......@@ -421,6 +421,7 @@ function _skilling_save_rubric_item_gui_data(FormStateInterface $formState, $rub
SkillingConstants::FIELD_CATEGORIES => $taxTerms
]);
// Remember the mapping between GUI id and actual.
$node->save();
$newRubricItemsMapping[$guiRubricItemId] = $node->id();
$newRubricItems[] = $node;
}
......@@ -1169,7 +1170,14 @@ function skilling_check_clear_menu_cache(Drupal\node\NodeInterface $node) {
$utilities = Drupal::service('skilling.utilities');
$count = $utilities->countNodesOfBundle($bundle);
if ($count == 0 || $count == 1) {
drupal_flush_all_caches();
// Schedule cache clear.
/** @var \Drupal\Core\Config\ConfigFactoryInterface $configFactory */
$configFactory = Drupal::service('config.factory');
$settings = $configFactory->getEditable(SkillingConstants::SETTINGS_MAIN_KEY);
$settings->set(
SkillingConstants::SETTING_KEY_SCHEDULE_CLEAR_CACHE, TRUE);
$settings->save();
// drupal_flush_all_caches();
}
}
}
......@@ -1431,6 +1439,8 @@ function skilling_node_delete(Node $node) {
}
}
}
// Check bundles where having any nodes influences menu item visibility
// in Lists menu.
skilling_check_clear_menu_cache($node);
}
......
......@@ -188,6 +188,7 @@ class RubricItemGuiController extends ControllerBase {
->loadMultiple($allRubricItemIds);
// Remember response options across all items.
$allResponseOptionsIds = [];
$result['rubricItems'] = [];
/** @var \Drupal\node\NodeInterface $rubricItem */
foreach ($allRubricItems as $rubricItem) {
// Does it exist?
......
......@@ -925,7 +925,7 @@ class Utilities {
$count = $this->entityTypeManager->getStorage('node')
->getQuery()
->condition('type', $bundle)
->condition('status', TRUE)
// ->condition('status', TRUE)
->count()
->execute();
return $count;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment