@vue-skuilder/common-ui 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index.css +2 -2
- package/dist/common-ui.es.js +1471 -295
- package/dist/common-ui.es.js.map +1 -1
- package/dist/common-ui.umd.js +2 -2
- package/dist/common-ui.umd.js.map +1 -1
- package/dist/components/HeatMap.types.d.ts +1 -0
- package/dist/components/HeatMap.types.d.ts.map +1 -0
- package/dist/components/PaginatingToolbar.types.d.ts +1 -0
- package/dist/components/PaginatingToolbar.types.d.ts.map +1 -0
- package/dist/components/SkMouseTrap.types.d.ts +1 -0
- package/dist/components/SkMouseTrap.types.d.ts.map +1 -0
- package/dist/components/SkMouseTrapToolTip.types.d.ts +1 -0
- package/dist/components/SkMouseTrapToolTip.types.d.ts.map +1 -0
- package/dist/components/SnackbarService.d.ts +1 -0
- package/dist/components/SnackbarService.d.ts.map +1 -0
- package/dist/components/StudySession.types.d.ts +1 -0
- package/dist/components/StudySession.types.d.ts.map +1 -0
- package/dist/components/auth/index.d.ts +1 -0
- package/dist/components/auth/index.d.ts.map +1 -0
- package/dist/components/cardRendering/MarkdownRendererHelpers.d.ts +1 -0
- package/dist/components/cardRendering/MarkdownRendererHelpers.d.ts.map +1 -0
- package/dist/components/studentInputs/BaseUserInput.d.ts +1 -0
- package/dist/components/studentInputs/BaseUserInput.d.ts.map +1 -0
- package/dist/components/studentInputs/RadioMultipleChoice.types.d.ts +1 -0
- package/dist/components/studentInputs/RadioMultipleChoice.types.d.ts.map +1 -0
- package/dist/composables/CompositionViewable.d.ts +1 -0
- package/dist/composables/CompositionViewable.d.ts.map +1 -0
- package/dist/composables/Displayable.d.ts +1 -0
- package/dist/composables/Displayable.d.ts.map +1 -0
- package/dist/composables/__tests__/useAuthUI.test.d.ts +2 -0
- package/dist/composables/__tests__/useAuthUI.test.d.ts.map +1 -0
- package/dist/composables/index.d.ts +2 -0
- package/dist/composables/index.d.ts.map +1 -0
- package/dist/composables/useAuthUI.d.ts +15 -0
- package/dist/composables/useAuthUI.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/plugins/pinia.d.ts +1 -0
- package/dist/plugins/pinia.d.ts.map +1 -0
- package/dist/stores/useAuthStore.d.ts +21 -0
- package/dist/stores/useAuthStore.d.ts.map +1 -0
- package/dist/stores/useCardPreviewModeStore.d.ts +1 -0
- package/dist/stores/useCardPreviewModeStore.d.ts.map +1 -0
- package/dist/stores/useConfigStore.d.ts +1 -0
- package/dist/stores/useConfigStore.d.ts.map +1 -0
- package/dist/utils/SkldrMouseTrap.d.ts +1 -0
- package/dist/utils/SkldrMouseTrap.d.ts.map +1 -0
- package/package.json +8 -3
- package/src/components/CardBrowser.vue +81 -0
- package/src/components/CourseCardBrowser.vue +384 -0
- package/src/components/CourseInformation.vue +194 -0
- package/src/components/PaginatingToolbar.vue +1 -1
- package/src/components/SnackbarService.vue +1 -3
- package/src/components/StudySession.vue +52 -23
- package/src/components/TagsInput.vue +247 -0
- package/src/components/auth/UserChip.vue +146 -58
- package/src/components/auth/UserLoginAndRegistrationContainer.vue +17 -2
- package/src/components/cardRendering/MarkdownRendererHelpers.ts +2 -2
- package/src/components/studentInputs/BaseUserInput.ts +0 -1
- package/src/composables/__tests__/useAuthUI.test.ts +103 -0
- package/src/composables/index.ts +1 -0
- package/src/composables/useAuthUI.ts +67 -0
- package/src/index.ts +8 -0
- package/src/plugins/pinia.ts +1 -1
- package/src/stores/useAuthStore.ts +19 -0
package/dist/common-ui.es.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { defineComponent, createElementBlock, openBlock, createCommentVNode, Fragment, renderList, normalizeStyle, toDisplayString, resolveComponent, createBlock, withCtx, createVNode, createTextVNode, createElementVNode, mergeProps, ref, computed, watch, onMounted, onBeforeUnmount, normalizeClass, renderSlot, Transition, resolveDynamicComponent, defineAsyncComponent, withKeys, withDirectives, vModelText, getCurrentInstance, h,
|
|
4
|
+
import { defineComponent, createElementBlock, openBlock, createCommentVNode, Fragment, renderList, normalizeStyle, toDisplayString, resolveComponent, createBlock, withCtx, createVNode, createTextVNode, createElementVNode, mergeProps, ref, computed, watch, onMounted, onBeforeUnmount, normalizeClass, renderSlot, Transition, resolveDynamicComponent, markRaw, defineAsyncComponent, withKeys, withDirectives, vModelText, getCurrentInstance, h, withModifiers, vShow } from "vue";
|
|
5
5
|
import { Status, FieldType, isCourseElo, toCourseElo, displayableDataToViewData, adjustCourseScores, log } from "@vue-skuilder/common";
|
|
6
6
|
import { docIsDeleted, isReview, newInterval, isQuestionRecord, getStudySource, SessionController, getDataLayer, GuestUsername } from "@vue-skuilder/db";
|
|
7
7
|
import { defineStore, setActivePinia } from "pinia";
|
|
8
8
|
import { useRouter, useRoute } from "vue-router";
|
|
9
|
+
import { VueTagsInput } from "@vojtechlanka/vue-tags-input";
|
|
9
10
|
//! moment.js
|
|
10
11
|
//! version : 2.30.1
|
|
11
12
|
//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
|
|
@@ -4000,7 +4001,7 @@ hooks.HTML5_FMT = {
|
|
|
4000
4001
|
MONTH: "YYYY-MM"
|
|
4001
4002
|
// <input type="month" />
|
|
4002
4003
|
};
|
|
4003
|
-
const _sfc_main$
|
|
4004
|
+
const _sfc_main$q = defineComponent({
|
|
4004
4005
|
name: "HeatMap",
|
|
4005
4006
|
props: {
|
|
4006
4007
|
// Accept activity records directly as a prop
|
|
@@ -4245,10 +4246,10 @@ const _export_sfc = (sfc, props) => {
|
|
|
4245
4246
|
}
|
|
4246
4247
|
return target;
|
|
4247
4248
|
};
|
|
4248
|
-
const _hoisted_1$
|
|
4249
|
-
const _hoisted_2$
|
|
4250
|
-
const _hoisted_3$
|
|
4251
|
-
function _sfc_render$
|
|
4249
|
+
const _hoisted_1$f = ["width", "height"];
|
|
4250
|
+
const _hoisted_2$7 = ["transform"];
|
|
4251
|
+
const _hoisted_3$5 = ["y", "width", "height", "fill", "onMouseover"];
|
|
4252
|
+
function _sfc_render$k(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4252
4253
|
return openBlock(), createElementBlock("div", null, [
|
|
4253
4254
|
(openBlock(), createElementBlock("svg", {
|
|
4254
4255
|
width: _ctx.width,
|
|
@@ -4269,11 +4270,11 @@ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4269
4270
|
fill: _ctx.getColor(day.count),
|
|
4270
4271
|
onMouseover: ($event) => _ctx.showTooltip(day, $event),
|
|
4271
4272
|
onMouseout: _cache[0] || (_cache[0] = (...args) => _ctx.hideTooltip && _ctx.hideTooltip(...args))
|
|
4272
|
-
}, null, 40, _hoisted_3$
|
|
4273
|
+
}, null, 40, _hoisted_3$5);
|
|
4273
4274
|
}), 128))
|
|
4274
|
-
], 8, _hoisted_2$
|
|
4275
|
+
], 8, _hoisted_2$7);
|
|
4275
4276
|
}), 128))
|
|
4276
|
-
], 8, _hoisted_1$
|
|
4277
|
+
], 8, _hoisted_1$f)),
|
|
4277
4278
|
_ctx.tooltipData ? (openBlock(), createElementBlock("div", {
|
|
4278
4279
|
key: 0,
|
|
4279
4280
|
class: "tooltip",
|
|
@@ -4281,7 +4282,7 @@ function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4281
4282
|
}, toDisplayString(_ctx.tooltipData.count) + " review" + toDisplayString(_ctx.tooltipData.count !== 1 ? "s" : "") + " on " + toDisplayString(_ctx.toDateString(_ctx.tooltipData.date)), 5)) : createCommentVNode("", true)
|
|
4282
4283
|
]);
|
|
4283
4284
|
}
|
|
4284
|
-
const HeatMap = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
4285
|
+
const HeatMap = /* @__PURE__ */ _export_sfc(_sfc_main$q, [["render", _sfc_render$k], ["__scopeId", "data-v-ca46239a"]]);
|
|
4285
4286
|
function getDefaultExportFromCjs(x) {
|
|
4286
4287
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
4287
4288
|
}
|
|
@@ -4861,7 +4862,7 @@ const _SkldrMouseTrap = class _SkldrMouseTrap {
|
|
|
4861
4862
|
};
|
|
4862
4863
|
__publicField(_SkldrMouseTrap, "_instance");
|
|
4863
4864
|
let SkldrMouseTrap = _SkldrMouseTrap;
|
|
4864
|
-
const _sfc_main$
|
|
4865
|
+
const _sfc_main$p = defineComponent({
|
|
4865
4866
|
name: "SkMouseTrap",
|
|
4866
4867
|
props: {
|
|
4867
4868
|
refreshInterval: {
|
|
@@ -4891,8 +4892,8 @@ const _sfc_main$k = defineComponent({
|
|
|
4891
4892
|
}
|
|
4892
4893
|
}
|
|
4893
4894
|
});
|
|
4894
|
-
const _hoisted_1$
|
|
4895
|
-
function _sfc_render$
|
|
4895
|
+
const _hoisted_1$e = { class: "text-caption ml-2" };
|
|
4896
|
+
function _sfc_render$j(_ctx, _cache, $props, $setup, $data, $options) {
|
|
4896
4897
|
const _component_v_icon = resolveComponent("v-icon");
|
|
4897
4898
|
const _component_v_btn = resolveComponent("v-btn");
|
|
4898
4899
|
const _component_v_toolbar_title = resolveComponent("v-toolbar-title");
|
|
@@ -4961,7 +4962,7 @@ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4961
4962
|
_: 2
|
|
4962
4963
|
}, 1024),
|
|
4963
4964
|
createVNode(_component_v_spacer),
|
|
4964
|
-
createElementVNode("span", _hoisted_1$
|
|
4965
|
+
createElementVNode("span", _hoisted_1$e, toDisplayString(hk.command), 1)
|
|
4965
4966
|
]),
|
|
4966
4967
|
_: 2
|
|
4967
4968
|
}, 1024);
|
|
@@ -4976,8 +4977,8 @@ function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
4976
4977
|
_: 1
|
|
4977
4978
|
})) : createCommentVNode("", true);
|
|
4978
4979
|
}
|
|
4979
|
-
const SkMouseTrap = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
4980
|
-
const _sfc_main$
|
|
4980
|
+
const SkMouseTrap = /* @__PURE__ */ _export_sfc(_sfc_main$p, [["render", _sfc_render$j]]);
|
|
4981
|
+
const _sfc_main$o = defineComponent({
|
|
4981
4982
|
name: "SkMouseTrapToolTip",
|
|
4982
4983
|
props: {
|
|
4983
4984
|
hotkey: {
|
|
@@ -5126,7 +5127,7 @@ const _sfc_main$j = defineComponent({
|
|
|
5126
5127
|
};
|
|
5127
5128
|
}
|
|
5128
5129
|
});
|
|
5129
|
-
function _sfc_render$
|
|
5130
|
+
function _sfc_render$i(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5130
5131
|
return openBlock(), createElementBlock("div", {
|
|
5131
5132
|
class: normalizeClass(["sk-mousetrap-tooltip-wrapper", [
|
|
5132
5133
|
_ctx.isControlKeyPressed && !_ctx.disabled && _ctx.highlightEffect !== "none" ? `sk-mousetrap-highlight-${_ctx.highlightEffect}` : ""
|
|
@@ -5150,7 +5151,7 @@ function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5150
5151
|
})
|
|
5151
5152
|
], 2);
|
|
5152
5153
|
}
|
|
5153
|
-
const SkMouseTrapToolTip = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5154
|
+
const SkMouseTrapToolTip = /* @__PURE__ */ _export_sfc(_sfc_main$o, [["render", _sfc_render$i], ["__scopeId", "data-v-5d6fb09c"]]);
|
|
5154
5155
|
const SnackbarServiceModule = /* @__PURE__ */ (() => {
|
|
5155
5156
|
let _instance = null;
|
|
5156
5157
|
return {
|
|
@@ -5174,7 +5175,7 @@ const SnackbarServiceModule = /* @__PURE__ */ (() => {
|
|
|
5174
5175
|
};
|
|
5175
5176
|
})();
|
|
5176
5177
|
const { setInstance, alertUser } = SnackbarServiceModule;
|
|
5177
|
-
const
|
|
5178
|
+
const _sfc_main$n = defineComponent({
|
|
5178
5179
|
name: "SnackbarService",
|
|
5179
5180
|
data() {
|
|
5180
5181
|
return {
|
|
@@ -5212,8 +5213,8 @@ const SnackbarService$1 = defineComponent({
|
|
|
5212
5213
|
}
|
|
5213
5214
|
}
|
|
5214
5215
|
});
|
|
5215
|
-
const _hoisted_1$
|
|
5216
|
-
function _sfc_render$
|
|
5216
|
+
const _hoisted_1$d = { class: "d-flex align-center justify-space-between w-100" };
|
|
5217
|
+
function _sfc_render$h(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5217
5218
|
const _component_v_icon = resolveComponent("v-icon");
|
|
5218
5219
|
const _component_v_btn = resolveComponent("v-btn");
|
|
5219
5220
|
const _component_v_snackbar = resolveComponent("v-snackbar");
|
|
@@ -5228,7 +5229,7 @@ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5228
5229
|
color: _ctx.getColor(snack)
|
|
5229
5230
|
}, {
|
|
5230
5231
|
default: withCtx(() => [
|
|
5231
|
-
createElementVNode("div", _hoisted_1$
|
|
5232
|
+
createElementVNode("div", _hoisted_1$d, [
|
|
5232
5233
|
createElementVNode("span", null, toDisplayString(snack.text), 1),
|
|
5233
5234
|
createVNode(_component_v_btn, {
|
|
5234
5235
|
icon: "",
|
|
@@ -5252,8 +5253,8 @@ function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5252
5253
|
}), 128))
|
|
5253
5254
|
]);
|
|
5254
5255
|
}
|
|
5255
|
-
const SnackbarService = /* @__PURE__ */ _export_sfc(
|
|
5256
|
-
const _sfc_main$
|
|
5256
|
+
const SnackbarService = /* @__PURE__ */ _export_sfc(_sfc_main$n, [["render", _sfc_render$h]]);
|
|
5257
|
+
const _sfc_main$m = defineComponent({
|
|
5257
5258
|
name: "PaginatingToolbar",
|
|
5258
5259
|
props: {
|
|
5259
5260
|
pages: {
|
|
@@ -5277,11 +5278,12 @@ const _sfc_main$i = defineComponent({
|
|
|
5277
5278
|
},
|
|
5278
5279
|
emits: ["first", "prev", "next", "last", "set-page"]
|
|
5279
5280
|
});
|
|
5280
|
-
const _hoisted_1$
|
|
5281
|
+
const _hoisted_1$c = {
|
|
5281
5282
|
key: 0,
|
|
5282
|
-
class: "ms-2 text-subtitle-2"
|
|
5283
|
+
class: "ms-2 text-subtitle-2",
|
|
5284
|
+
"data-cy": "paginating-toolbar-subtitle"
|
|
5283
5285
|
};
|
|
5284
|
-
function _sfc_render$
|
|
5286
|
+
function _sfc_render$g(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5285
5287
|
const _component_v_toolbar_title = resolveComponent("v-toolbar-title");
|
|
5286
5288
|
const _component_v_spacer = resolveComponent("v-spacer");
|
|
5287
5289
|
const _component_v_icon = resolveComponent("v-icon");
|
|
@@ -5293,7 +5295,7 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5293
5295
|
createVNode(_component_v_toolbar_title, null, {
|
|
5294
5296
|
default: withCtx(() => [
|
|
5295
5297
|
createElementVNode("span", null, toDisplayString(_ctx.title), 1),
|
|
5296
|
-
_ctx.subtitle ? (openBlock(), createElementBlock("span", _hoisted_1$
|
|
5298
|
+
_ctx.subtitle ? (openBlock(), createElementBlock("span", _hoisted_1$c, toDisplayString(_ctx.subtitle), 1)) : createCommentVNode("", true)
|
|
5297
5299
|
]),
|
|
5298
5300
|
_: 1
|
|
5299
5301
|
}),
|
|
@@ -5385,7 +5387,7 @@ function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5385
5387
|
_: 1
|
|
5386
5388
|
});
|
|
5387
5389
|
}
|
|
5388
|
-
const PaginatingToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5390
|
+
const PaginatingToolbar = /* @__PURE__ */ _export_sfc(_sfc_main$m, [["render", _sfc_render$g], ["__scopeId", "data-v-a75fea7e"]]);
|
|
5389
5391
|
function useViewable(props, emit, componentName) {
|
|
5390
5392
|
const startTime = ref(hooks.utc());
|
|
5391
5393
|
const hotKeys = ref([]);
|
|
@@ -5554,7 +5556,7 @@ class Question extends Displayable {
|
|
|
5554
5556
|
with 7 * 4 = 21
|
|
5555
5557
|
*/
|
|
5556
5558
|
}
|
|
5557
|
-
const _sfc_main$
|
|
5559
|
+
const _sfc_main$l = defineComponent({
|
|
5558
5560
|
name: "StudySessionTimer",
|
|
5559
5561
|
props: {
|
|
5560
5562
|
/**
|
|
@@ -5608,7 +5610,7 @@ const _sfc_main$h = defineComponent({
|
|
|
5608
5610
|
};
|
|
5609
5611
|
}
|
|
5610
5612
|
});
|
|
5611
|
-
function _sfc_render$
|
|
5613
|
+
function _sfc_render$f(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5612
5614
|
const _component_v_icon = resolveComponent("v-icon");
|
|
5613
5615
|
const _component_v_btn = resolveComponent("v-btn");
|
|
5614
5616
|
const _component_v_progress_circular = resolveComponent("v-progress-circular");
|
|
@@ -5662,8 +5664,8 @@ function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5662
5664
|
_: 1
|
|
5663
5665
|
});
|
|
5664
5666
|
}
|
|
5665
|
-
const StudySessionTimer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5666
|
-
const _sfc_main$
|
|
5667
|
+
const StudySessionTimer = /* @__PURE__ */ _export_sfc(_sfc_main$l, [["render", _sfc_render$f], ["__scopeId", "data-v-5960940a"]]);
|
|
5668
|
+
const _sfc_main$k = defineComponent({
|
|
5667
5669
|
name: "CardViewer",
|
|
5668
5670
|
ref: {},
|
|
5669
5671
|
props: {
|
|
@@ -5717,7 +5719,7 @@ const _sfc_main$g = defineComponent({
|
|
|
5717
5719
|
}
|
|
5718
5720
|
}
|
|
5719
5721
|
});
|
|
5720
|
-
function _sfc_render$
|
|
5722
|
+
function _sfc_render$e(_ctx, _cache, $props, $setup, $data, $options) {
|
|
5721
5723
|
const _component_v_card = resolveComponent("v-card");
|
|
5722
5724
|
return openBlock(), createBlock(_component_v_card, { elevation: "12" }, {
|
|
5723
5725
|
default: withCtx(() => [
|
|
@@ -5741,7 +5743,7 @@ function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
5741
5743
|
_: 1
|
|
5742
5744
|
});
|
|
5743
5745
|
}
|
|
5744
|
-
const CardViewer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
5746
|
+
const CardViewer = /* @__PURE__ */ _export_sfc(_sfc_main$k, [["render", _sfc_render$e], ["__scopeId", "data-v-a180fe1c"]]);
|
|
5745
5747
|
var module$1 = {};
|
|
5746
5748
|
(function main(global, module2, isWorker, workerSize) {
|
|
5747
5749
|
var canUseWorker = !!(global.Worker && global.Blob && global.Promise && global.OffscreenCanvas && global.OffscreenCanvasRenderingContext2D && global.HTMLCanvasElement && global.HTMLCanvasElement.prototype.transferControlToOffscreen && global.URL && global.URL.createObjectURL);
|
|
@@ -6438,7 +6440,7 @@ var module$1 = {};
|
|
|
6438
6440
|
}(), module$1, false);
|
|
6439
6441
|
const confetti = module$1.exports;
|
|
6440
6442
|
module$1.exports.create;
|
|
6441
|
-
const _sfc_main$
|
|
6443
|
+
const _sfc_main$j = defineComponent({
|
|
6442
6444
|
name: "StudySession",
|
|
6443
6445
|
ref: {},
|
|
6444
6446
|
components: {
|
|
@@ -6582,23 +6584,25 @@ const _sfc_main$f = defineComponent({
|
|
|
6582
6584
|
try {
|
|
6583
6585
|
console.log(`[StudySession] starting study session w/ sources: ${JSON.stringify(this.contentSources)}`);
|
|
6584
6586
|
console.log("[StudySession] Beginning preparation process");
|
|
6585
|
-
this.sessionContentSources = (
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6589
|
-
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6587
|
+
this.sessionContentSources = markRaw(
|
|
6588
|
+
(await Promise.all(
|
|
6589
|
+
this.contentSources.map(async (s) => {
|
|
6590
|
+
try {
|
|
6591
|
+
return await getStudySource(s, this.user);
|
|
6592
|
+
} catch (e) {
|
|
6593
|
+
console.error(`Failed to load study source: ${s.type}/${s.id}`, e);
|
|
6594
|
+
return null;
|
|
6595
|
+
}
|
|
6596
|
+
})
|
|
6597
|
+
)).filter((s) => s !== null)
|
|
6598
|
+
);
|
|
6595
6599
|
this.timeRemaining = this.sessionTimeLimit * 60;
|
|
6596
6600
|
sessionClassroomDBs = await Promise.all(
|
|
6597
6601
|
this.contentSources.filter((s) => s.type === "classroom").map(async (c) => await this.dataLayer.getClassroomDB(c.id, "student"))
|
|
6598
6602
|
);
|
|
6599
|
-
sessionClassroomDBs.forEach((
|
|
6603
|
+
sessionClassroomDBs.forEach((_db) => {
|
|
6600
6604
|
});
|
|
6601
|
-
this.sessionController = new SessionController(this.sessionContentSources, 60 * this.sessionTimeLimit);
|
|
6605
|
+
this.sessionController = markRaw(new SessionController(this.sessionContentSources, 60 * this.sessionTimeLimit));
|
|
6602
6606
|
this.sessionController.sessionRecord = this.sessionRecord;
|
|
6603
6607
|
await this.sessionController.prepareSession();
|
|
6604
6608
|
this.intervalHandler = setInterval(this.tick, 1e3);
|
|
@@ -6728,12 +6732,15 @@ const _sfc_main$f = defineComponent({
|
|
|
6728
6732
|
if (cardElo && userElo) {
|
|
6729
6733
|
const eloUpdate = adjustCourseScores(userElo, cardElo, userScore);
|
|
6730
6734
|
this.userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo = eloUpdate.userElo;
|
|
6731
|
-
Promise.
|
|
6735
|
+
const results = await Promise.allSettled([
|
|
6732
6736
|
this.user.updateUserElo(course_id, eloUpdate.userElo),
|
|
6733
6737
|
courseDB.updateCardElo(card_id, eloUpdate.cardElo)
|
|
6734
|
-
])
|
|
6735
|
-
|
|
6736
|
-
|
|
6738
|
+
]);
|
|
6739
|
+
const userEloStatus = results[0].status === "fulfilled";
|
|
6740
|
+
const cardEloStatus = results[1].status === "fulfilled";
|
|
6741
|
+
if (userEloStatus && cardEloStatus) {
|
|
6742
|
+
const user = results[0].value;
|
|
6743
|
+
const card = results[1].value;
|
|
6737
6744
|
if (user.ok && card && card.ok) {
|
|
6738
6745
|
console.log(
|
|
6739
6746
|
`[StudySession] Updated ELOS:
|
|
@@ -6742,7 +6749,19 @@ const _sfc_main$f = defineComponent({
|
|
|
6742
6749
|
`
|
|
6743
6750
|
);
|
|
6744
6751
|
}
|
|
6745
|
-
}
|
|
6752
|
+
} else {
|
|
6753
|
+
console.log(
|
|
6754
|
+
`[StudySession] Partial ELO update:
|
|
6755
|
+
User ELO update: ${userEloStatus ? "SUCCESS" : "FAILED"}
|
|
6756
|
+
Card ELO update: ${cardEloStatus ? "SUCCESS" : "FAILED"}`
|
|
6757
|
+
);
|
|
6758
|
+
if (!userEloStatus && results[0].status === "rejected") {
|
|
6759
|
+
console.error("[StudySession] User ELO update error:", results[0].reason);
|
|
6760
|
+
}
|
|
6761
|
+
if (!cardEloStatus && results[1].status === "rejected") {
|
|
6762
|
+
console.error("[StudySession] Card ELO update error:", results[1].reason);
|
|
6763
|
+
}
|
|
6764
|
+
}
|
|
6746
6765
|
}
|
|
6747
6766
|
},
|
|
6748
6767
|
clearFeedbackShadow() {
|
|
@@ -6844,22 +6863,22 @@ const _sfc_main$f = defineComponent({
|
|
|
6844
6863
|
}
|
|
6845
6864
|
}
|
|
6846
6865
|
});
|
|
6847
|
-
const _hoisted_1$
|
|
6866
|
+
const _hoisted_1$b = {
|
|
6848
6867
|
key: 0,
|
|
6849
6868
|
class: "StudySession"
|
|
6850
6869
|
};
|
|
6851
|
-
const _hoisted_2$
|
|
6852
|
-
const _hoisted_3$
|
|
6870
|
+
const _hoisted_2$6 = { class: "text-h3" };
|
|
6871
|
+
const _hoisted_3$4 = {
|
|
6853
6872
|
key: 0,
|
|
6854
6873
|
class: "text-h4"
|
|
6855
6874
|
};
|
|
6856
|
-
const _hoisted_4$
|
|
6857
|
-
const _hoisted_5$
|
|
6875
|
+
const _hoisted_4$3 = { key: 0 };
|
|
6876
|
+
const _hoisted_5$3 = {
|
|
6858
6877
|
key: 1,
|
|
6859
6878
|
ref: "shadowWrapper"
|
|
6860
6879
|
};
|
|
6861
6880
|
const _hoisted_6$1 = { key: 2 };
|
|
6862
|
-
function _sfc_render$
|
|
6881
|
+
function _sfc_render$d(_ctx, _cache, $props, $setup, $data, $options) {
|
|
6863
6882
|
const _component_v_progress_circular = resolveComponent("v-progress-circular");
|
|
6864
6883
|
const _component_v_spacer = resolveComponent("v-spacer");
|
|
6865
6884
|
const _component_v_col = resolveComponent("v-col");
|
|
@@ -6869,12 +6888,12 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6869
6888
|
const _component_card_viewer = resolveComponent("card-viewer");
|
|
6870
6889
|
const _component_StudySessionTimer = resolveComponent("StudySessionTimer");
|
|
6871
6890
|
const _component_SkMouseTrap = resolveComponent("SkMouseTrap");
|
|
6872
|
-
return _ctx.sessionPrepared ? (openBlock(), createElementBlock("div", _hoisted_1$
|
|
6891
|
+
return _ctx.sessionPrepared ? (openBlock(), createElementBlock("div", _hoisted_1$b, [
|
|
6873
6892
|
createVNode(_component_v_row, { align: "center" }, {
|
|
6874
6893
|
default: withCtx(() => [
|
|
6875
6894
|
createVNode(_component_v_col, null, {
|
|
6876
6895
|
default: withCtx(() => [
|
|
6877
|
-
createElementVNode("h1", _hoisted_2$
|
|
6896
|
+
createElementVNode("h1", _hoisted_2$6, [
|
|
6878
6897
|
createTextVNode(toDisplayString(_ctx.courseNames[_ctx.courseID]) + ": ", 1),
|
|
6879
6898
|
_ctx.loading ? (openBlock(), createBlock(_component_v_progress_circular, {
|
|
6880
6899
|
key: 0,
|
|
@@ -6892,9 +6911,9 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6892
6911
|
_: 1
|
|
6893
6912
|
}),
|
|
6894
6913
|
_cache[7] || (_cache[7] = createElementVNode("br", null, null, -1)),
|
|
6895
|
-
_ctx.sessionFinished ? (openBlock(), createElementBlock("div", _hoisted_3$
|
|
6914
|
+
_ctx.sessionFinished ? (openBlock(), createElementBlock("div", _hoisted_3$4, [
|
|
6896
6915
|
_cache[6] || (_cache[6] = createElementVNode("p", null, "Study session finished! Great job!", -1)),
|
|
6897
|
-
_ctx.sessionController ? (openBlock(), createElementBlock("p", _hoisted_4$
|
|
6916
|
+
_ctx.sessionController ? (openBlock(), createElementBlock("p", _hoisted_4$3, toDisplayString(_ctx.sessionController.report), 1)) : createCommentVNode("", true),
|
|
6898
6917
|
createElementVNode("p", null, [
|
|
6899
6918
|
_cache[3] || (_cache[3] = createTextVNode(" Start ")),
|
|
6900
6919
|
createElementVNode("a", {
|
|
@@ -6914,7 +6933,7 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6914
6933
|
createVNode(_component_heat_map, {
|
|
6915
6934
|
"activity-records-getter": () => _ctx.user.getActivityRecords()
|
|
6916
6935
|
}, null, 8, ["activity-records-getter"])
|
|
6917
|
-
])) : (openBlock(), createElementBlock("div", _hoisted_5$
|
|
6936
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_5$3, [
|
|
6918
6937
|
createVNode(_component_card_viewer, {
|
|
6919
6938
|
ref: "cardViewer",
|
|
6920
6939
|
class: normalizeClass(_ctx.loading ? "muted" : ""),
|
|
@@ -6970,7 +6989,7 @@ function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
6970
6989
|
})
|
|
6971
6990
|
])) : createCommentVNode("", true);
|
|
6972
6991
|
}
|
|
6973
|
-
const StudySession = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
6992
|
+
const StudySession = /* @__PURE__ */ _export_sfc(_sfc_main$j, [["render", _sfc_render$d], ["__scopeId", "data-v-37cad857"]]);
|
|
6974
6993
|
let _pinia = null;
|
|
6975
6994
|
const setPinia = (pinia) => {
|
|
6976
6995
|
_pinia = pinia;
|
|
@@ -6979,7 +6998,7 @@ const getPinia = () => {
|
|
|
6979
6998
|
return _pinia;
|
|
6980
6999
|
};
|
|
6981
7000
|
const piniaPlugin = {
|
|
6982
|
-
install(
|
|
7001
|
+
install(_app, options) {
|
|
6983
7002
|
const pinia = options?.pinia;
|
|
6984
7003
|
if (pinia) {
|
|
6985
7004
|
setPinia(pinia);
|
|
@@ -7065,7 +7084,7 @@ Exceeded maximum ancestor lookup depth.`;
|
|
|
7065
7084
|
}
|
|
7066
7085
|
}
|
|
7067
7086
|
});
|
|
7068
|
-
const _sfc_main$
|
|
7087
|
+
const _sfc_main$i = defineComponent({
|
|
7069
7088
|
name: "MultipleChoiceOption",
|
|
7070
7089
|
components: {
|
|
7071
7090
|
MarkdownRenderer: defineAsyncComponent(() => Promise.resolve().then(() => MarkdownRenderer$1))
|
|
@@ -7151,7 +7170,7 @@ const _sfc_main$e = defineComponent({
|
|
|
7151
7170
|
}
|
|
7152
7171
|
}
|
|
7153
7172
|
});
|
|
7154
|
-
function _sfc_render$
|
|
7173
|
+
function _sfc_render$c(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7155
7174
|
const _component_markdown_renderer = resolveComponent("markdown-renderer");
|
|
7156
7175
|
const _component_v_card = resolveComponent("v-card");
|
|
7157
7176
|
return openBlock(), createBlock(_component_v_card, {
|
|
@@ -7165,8 +7184,8 @@ function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7165
7184
|
_: 1
|
|
7166
7185
|
}, 8, ["class", "onMouseover", "onClick"]);
|
|
7167
7186
|
}
|
|
7168
|
-
const MultipleChoiceOption = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7169
|
-
const _sfc_main$
|
|
7187
|
+
const MultipleChoiceOption = /* @__PURE__ */ _export_sfc(_sfc_main$i, [["render", _sfc_render$c], ["__scopeId", "data-v-96de7172"]]);
|
|
7188
|
+
const _sfc_main$h = defineComponent({
|
|
7170
7189
|
name: "RadioMultipleChoice",
|
|
7171
7190
|
components: {
|
|
7172
7191
|
MultipleChoiceOption
|
|
@@ -7305,13 +7324,13 @@ const _sfc_main$d = defineComponent({
|
|
|
7305
7324
|
// },
|
|
7306
7325
|
}
|
|
7307
7326
|
});
|
|
7308
|
-
const _hoisted_1$
|
|
7327
|
+
const _hoisted_1$a = {
|
|
7309
7328
|
ref: "containerRef",
|
|
7310
7329
|
class: "multipleChoice"
|
|
7311
7330
|
};
|
|
7312
|
-
function _sfc_render$
|
|
7331
|
+
function _sfc_render$b(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7313
7332
|
const _component_MultipleChoiceOption = resolveComponent("MultipleChoiceOption");
|
|
7314
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
7333
|
+
return openBlock(), createElementBlock("div", _hoisted_1$a, [
|
|
7315
7334
|
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.choiceList, (choice, i) => {
|
|
7316
7335
|
return openBlock(), createBlock(_component_MultipleChoiceOption, {
|
|
7317
7336
|
key: i,
|
|
@@ -7325,8 +7344,8 @@ function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7325
7344
|
}), 128))
|
|
7326
7345
|
], 512);
|
|
7327
7346
|
}
|
|
7328
|
-
const RadioMultipleChoice = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7329
|
-
const _sfc_main$
|
|
7347
|
+
const RadioMultipleChoice = /* @__PURE__ */ _export_sfc(_sfc_main$h, [["render", _sfc_render$b]]);
|
|
7348
|
+
const _sfc_main$g = defineComponent({
|
|
7330
7349
|
name: "TrueFalse",
|
|
7331
7350
|
components: {
|
|
7332
7351
|
RadioMultipleChoice
|
|
@@ -7342,10 +7361,10 @@ const _sfc_main$c = defineComponent({
|
|
|
7342
7361
|
}
|
|
7343
7362
|
}
|
|
7344
7363
|
});
|
|
7345
|
-
const _hoisted_1$
|
|
7346
|
-
function _sfc_render$
|
|
7364
|
+
const _hoisted_1$9 = { "data-viewable": "TrueFalse" };
|
|
7365
|
+
function _sfc_render$a(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7347
7366
|
const _component_RadioMultipleChoice = resolveComponent("RadioMultipleChoice");
|
|
7348
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
7367
|
+
return openBlock(), createElementBlock("div", _hoisted_1$9, [
|
|
7349
7368
|
createVNode(_component_RadioMultipleChoice, {
|
|
7350
7369
|
"choice-list": ["True", "False"],
|
|
7351
7370
|
MouseTrap: _ctx.MouseTrap,
|
|
@@ -7353,8 +7372,8 @@ function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7353
7372
|
}, null, 8, ["MouseTrap", "submit"])
|
|
7354
7373
|
]);
|
|
7355
7374
|
}
|
|
7356
|
-
const TrueFalse = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7357
|
-
const _sfc_main$
|
|
7375
|
+
const TrueFalse = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["render", _sfc_render$a]]);
|
|
7376
|
+
const _sfc_main$f = defineComponent({
|
|
7358
7377
|
name: "UserInputNumber",
|
|
7359
7378
|
ref: {},
|
|
7360
7379
|
extends: UserInput,
|
|
@@ -7374,7 +7393,7 @@ const _sfc_main$b = defineComponent({
|
|
|
7374
7393
|
}
|
|
7375
7394
|
}
|
|
7376
7395
|
});
|
|
7377
|
-
function _sfc_render$
|
|
7396
|
+
function _sfc_render$9(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7378
7397
|
const _component_v_text_field = resolveComponent("v-text-field");
|
|
7379
7398
|
const _component_v_container = resolveComponent("v-container");
|
|
7380
7399
|
return openBlock(), createBlock(_component_v_container, { class: "pa-0" }, {
|
|
@@ -7395,8 +7414,8 @@ function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7395
7414
|
_: 1
|
|
7396
7415
|
});
|
|
7397
7416
|
}
|
|
7398
|
-
const UserInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7399
|
-
const _sfc_main$
|
|
7417
|
+
const UserInputNumber = /* @__PURE__ */ _export_sfc(_sfc_main$f, [["render", _sfc_render$9], ["__scopeId", "data-v-a56dcd1c"]]);
|
|
7418
|
+
const _sfc_main$e = defineComponent({
|
|
7400
7419
|
name: "UserInputString",
|
|
7401
7420
|
extends: UserInput,
|
|
7402
7421
|
props: {
|
|
@@ -7433,10 +7452,10 @@ const _sfc_main$a = defineComponent({
|
|
|
7433
7452
|
// },
|
|
7434
7453
|
}
|
|
7435
7454
|
});
|
|
7436
|
-
const _hoisted_1$
|
|
7437
|
-
const _hoisted_2$
|
|
7438
|
-
function _sfc_render$
|
|
7439
|
-
return openBlock(), createElementBlock("span", _hoisted_1$
|
|
7455
|
+
const _hoisted_1$8 = { class: "user-input-container" };
|
|
7456
|
+
const _hoisted_2$5 = ["autofocus"];
|
|
7457
|
+
function _sfc_render$8(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7458
|
+
return openBlock(), createElementBlock("span", _hoisted_1$8, [
|
|
7440
7459
|
withDirectives(createElementVNode("input", {
|
|
7441
7460
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.answer = $event),
|
|
7442
7461
|
autofocus: _ctx.autofocus,
|
|
@@ -7444,13 +7463,13 @@ function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7444
7463
|
class: "user-input-string",
|
|
7445
7464
|
ref: "input",
|
|
7446
7465
|
onKeyup: _cache[1] || (_cache[1] = withKeys(($event) => _ctx.submitAnswer(_ctx.answer), ["enter"]))
|
|
7447
|
-
}, null, 40, _hoisted_2$
|
|
7466
|
+
}, null, 40, _hoisted_2$5), [
|
|
7448
7467
|
[vModelText, _ctx.answer]
|
|
7449
7468
|
])
|
|
7450
7469
|
]);
|
|
7451
7470
|
}
|
|
7452
|
-
const UserInputString = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7453
|
-
const _sfc_main$
|
|
7471
|
+
const UserInputString = /* @__PURE__ */ _export_sfc(_sfc_main$e, [["render", _sfc_render$8], ["__scopeId", "data-v-aa14961f"]]);
|
|
7472
|
+
const _sfc_main$d = defineComponent({
|
|
7454
7473
|
name: "FillInInput",
|
|
7455
7474
|
components: {
|
|
7456
7475
|
UserInputString
|
|
@@ -7483,13 +7502,13 @@ const _sfc_main$9 = defineComponent({
|
|
|
7483
7502
|
};
|
|
7484
7503
|
}
|
|
7485
7504
|
});
|
|
7486
|
-
const _hoisted_1$
|
|
7505
|
+
const _hoisted_1$7 = {
|
|
7487
7506
|
key: 0,
|
|
7488
7507
|
class: "text-h5 underline"
|
|
7489
7508
|
};
|
|
7490
|
-
function _sfc_render$
|
|
7509
|
+
function _sfc_render$7(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7491
7510
|
const _component_user_input_string = resolveComponent("user-input-string");
|
|
7492
|
-
return _ctx.radioType ? (openBlock(), createElementBlock("span", _hoisted_1$
|
|
7511
|
+
return _ctx.radioType ? (openBlock(), createElementBlock("span", _hoisted_1$7, " ")) : (openBlock(), createBlock(_component_user_input_string, {
|
|
7493
7512
|
key: 1,
|
|
7494
7513
|
id: "input",
|
|
7495
7514
|
icon: false,
|
|
@@ -7497,8 +7516,8 @@ function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7497
7516
|
value: _ctx.processedText
|
|
7498
7517
|
}, null, 8, ["value"]));
|
|
7499
7518
|
}
|
|
7500
|
-
const FillInInput = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7501
|
-
const _sfc_main$
|
|
7519
|
+
const FillInInput = /* @__PURE__ */ _export_sfc(_sfc_main$d, [["render", _sfc_render$7], ["__scopeId", "data-v-486ac035"]]);
|
|
7520
|
+
const _sfc_main$c = defineComponent({
|
|
7502
7521
|
name: "CardLoader",
|
|
7503
7522
|
components: {
|
|
7504
7523
|
CardViewer
|
|
@@ -7572,7 +7591,7 @@ const _sfc_main$8 = defineComponent({
|
|
|
7572
7591
|
}
|
|
7573
7592
|
}
|
|
7574
7593
|
});
|
|
7575
|
-
function _sfc_render$
|
|
7594
|
+
function _sfc_render$6(_ctx, _cache, $props, $setup, $data, $options) {
|
|
7576
7595
|
const _component_card_viewer = resolveComponent("card-viewer");
|
|
7577
7596
|
return !_ctx.loading ? (openBlock(), createBlock(_component_card_viewer, {
|
|
7578
7597
|
key: 0,
|
|
@@ -7585,7 +7604,7 @@ function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
7585
7604
|
onEmitResponse: _cache[0] || (_cache[0] = ($event) => _ctx.processResponse($event))
|
|
7586
7605
|
}, null, 8, ["class", "view", "data", "card_id", "course_id", "session-order"])) : createCommentVNode("", true);
|
|
7587
7606
|
}
|
|
7588
|
-
const CardLoader = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
7607
|
+
const CardLoader = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render$6], ["__scopeId", "data-v-9ca53bc4"]]);
|
|
7589
7608
|
function _getDefaults() {
|
|
7590
7609
|
return {
|
|
7591
7610
|
async: false,
|
|
@@ -9732,7 +9751,7 @@ function splitTextToken(token2) {
|
|
|
9732
9751
|
const textChunks = splitByDelimiters(token2.text, "{{", "}}");
|
|
9733
9752
|
const rawChunks = splitByDelimiters(token2.raw, "{{", "}}");
|
|
9734
9753
|
if (textChunks.length === rawChunks.length) {
|
|
9735
|
-
return textChunks.map((
|
|
9754
|
+
return textChunks.map((_c, i) => {
|
|
9736
9755
|
return {
|
|
9737
9756
|
type: "text",
|
|
9738
9757
|
text: textChunks[i],
|
|
@@ -9796,7 +9815,7 @@ function isComponent(token2) {
|
|
|
9796
9815
|
return token2.type === "text" && token2.text.startsWith("{{") && token2.text.endsWith("}}");
|
|
9797
9816
|
}
|
|
9798
9817
|
const playbackGap = 500;
|
|
9799
|
-
const _sfc_main$
|
|
9818
|
+
const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
9800
9819
|
__name: "AudioAutoPlayer",
|
|
9801
9820
|
props: {
|
|
9802
9821
|
src: {}
|
|
@@ -9907,7 +9926,7 @@ const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
|
9907
9926
|
};
|
|
9908
9927
|
}
|
|
9909
9928
|
});
|
|
9910
|
-
const AudioAutoPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
9929
|
+
const AudioAutoPlayer = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-e1a0f62c"]]);
|
|
9911
9930
|
var core;
|
|
9912
9931
|
var hasRequiredCore;
|
|
9913
9932
|
function requireCore() {
|
|
@@ -15140,12 +15159,12 @@ function python(hljs) {
|
|
|
15140
15159
|
]
|
|
15141
15160
|
};
|
|
15142
15161
|
}
|
|
15143
|
-
const _hoisted_1$
|
|
15144
|
-
const _hoisted_2$
|
|
15162
|
+
const _hoisted_1$6 = { class: "code-block-wrapper pa-2" };
|
|
15163
|
+
const _hoisted_2$4 = {
|
|
15145
15164
|
key: 0,
|
|
15146
15165
|
class: "language-indicator"
|
|
15147
15166
|
};
|
|
15148
|
-
const _sfc_main$
|
|
15167
|
+
const _sfc_main$a = /* @__PURE__ */ defineComponent({
|
|
15149
15168
|
__name: "CodeBlockRenderer",
|
|
15150
15169
|
props: {
|
|
15151
15170
|
code: {
|
|
@@ -15176,8 +15195,8 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
15176
15195
|
}
|
|
15177
15196
|
return (_ctx, _cache) => {
|
|
15178
15197
|
const _component_highlightjs = resolveComponent("highlightjs");
|
|
15179
|
-
return openBlock(), createElementBlock("div", _hoisted_1$
|
|
15180
|
-
__props.language ? (openBlock(), createElementBlock("div", _hoisted_2$
|
|
15198
|
+
return openBlock(), createElementBlock("div", _hoisted_1$6, [
|
|
15199
|
+
__props.language ? (openBlock(), createElementBlock("div", _hoisted_2$4, toDisplayString(__props.language), 1)) : createCommentVNode("", true),
|
|
15181
15200
|
createVNode(_component_highlightjs, {
|
|
15182
15201
|
language: __props.language,
|
|
15183
15202
|
code: __props.code
|
|
@@ -15186,11 +15205,11 @@ const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
|
15186
15205
|
};
|
|
15187
15206
|
}
|
|
15188
15207
|
});
|
|
15189
|
-
const _hoisted_1$
|
|
15190
|
-
const _hoisted_2 = { key: 0 };
|
|
15191
|
-
const _hoisted_3 = { key: 0 };
|
|
15192
|
-
const _hoisted_4 = { key: 1 };
|
|
15193
|
-
const _hoisted_5 = { key: 2 };
|
|
15208
|
+
const _hoisted_1$5 = { key: 0 };
|
|
15209
|
+
const _hoisted_2$3 = { key: 0 };
|
|
15210
|
+
const _hoisted_3$3 = { key: 0 };
|
|
15211
|
+
const _hoisted_4$2 = { key: 1 };
|
|
15212
|
+
const _hoisted_5$2 = { key: 2 };
|
|
15194
15213
|
const _hoisted_6 = { key: 1 };
|
|
15195
15214
|
const _hoisted_7 = { key: 1 };
|
|
15196
15215
|
const _hoisted_8 = {
|
|
@@ -15228,7 +15247,7 @@ const _hoisted_27 = ["innerHTML"];
|
|
|
15228
15247
|
const _hoisted_28 = { key: 16 };
|
|
15229
15248
|
const _hoisted_29 = { key: 17 };
|
|
15230
15249
|
const _hoisted_30 = { key: 18 };
|
|
15231
|
-
const _sfc_main$
|
|
15250
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
15232
15251
|
__name: "MdTokenRenderer",
|
|
15233
15252
|
props: {
|
|
15234
15253
|
token: {
|
|
@@ -15295,21 +15314,21 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
15295
15314
|
});
|
|
15296
15315
|
return (_ctx, _cache) => {
|
|
15297
15316
|
const _component_md_token_renderer = resolveComponent("md-token-renderer", true);
|
|
15298
|
-
return isText(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_1$
|
|
15299
|
-
!__props.token.tokens || __props.token.tokens.length === 0 ? (openBlock(), createElementBlock("span", _hoisted_2, [
|
|
15300
|
-
isComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_3, [
|
|
15317
|
+
return isText(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_1$5, [
|
|
15318
|
+
!__props.token.tokens || __props.token.tokens.length === 0 ? (openBlock(), createElementBlock("span", _hoisted_2$3, [
|
|
15319
|
+
isComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_3$3, [
|
|
15301
15320
|
!__props.last ? (openBlock(), createBlock(resolveDynamicComponent(getComponent(parsedComponent(__props.token).is)), {
|
|
15302
15321
|
key: 0,
|
|
15303
15322
|
text: parsedComponent(__props.token).text
|
|
15304
15323
|
}, null, 8, ["text"])) : createCommentVNode("", true)
|
|
15305
|
-
])) : containsComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_4, [
|
|
15324
|
+
])) : containsComponent$1(__props.token) ? (openBlock(), createElementBlock("span", _hoisted_4$2, [
|
|
15306
15325
|
(openBlock(true), createElementBlock(Fragment, null, renderList(splitTextToken$1(__props.token), (subTok, j) => {
|
|
15307
15326
|
return openBlock(), createBlock(_component_md_token_renderer, {
|
|
15308
15327
|
key: j,
|
|
15309
15328
|
token: subTok
|
|
15310
15329
|
}, null, 8, ["token"]);
|
|
15311
15330
|
}), 128))
|
|
15312
|
-
])) : (openBlock(), createElementBlock("span", _hoisted_5, toDisplayString(decodeBasicEntities(__props.token.text)), 1))
|
|
15331
|
+
])) : (openBlock(), createElementBlock("span", _hoisted_5$2, toDisplayString(decodeBasicEntities(__props.token.text)), 1))
|
|
15313
15332
|
])) : __props.token.tokens && __props.token.tokens.length !== 0 ? (openBlock(), createElementBlock("span", _hoisted_6, [
|
|
15314
15333
|
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.token.tokens, (subTok, j) => {
|
|
15315
15334
|
return openBlock(), createBlock(_component_md_token_renderer, {
|
|
@@ -15442,7 +15461,7 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
15442
15461
|
], 8, _hoisted_25)) : __props.token.type === "html" ? (openBlock(), createElementBlock("span", {
|
|
15443
15462
|
key: 13,
|
|
15444
15463
|
innerHTML: __props.token.raw
|
|
15445
|
-
}, null, 8, _hoisted_26)) : __props.token.type === "code" ? (openBlock(), createBlock(_sfc_main$
|
|
15464
|
+
}, null, 8, _hoisted_26)) : __props.token.type === "code" ? (openBlock(), createBlock(_sfc_main$a, {
|
|
15446
15465
|
key: 14,
|
|
15447
15466
|
code: __props.token.text,
|
|
15448
15467
|
language: __props.token.lang
|
|
@@ -15468,8 +15487,8 @@ const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
|
15468
15487
|
};
|
|
15469
15488
|
}
|
|
15470
15489
|
});
|
|
15471
|
-
const MdTokenRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15472
|
-
const _sfc_main$
|
|
15490
|
+
const MdTokenRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-047d0fa4"]]);
|
|
15491
|
+
const _sfc_main$8 = defineComponent({
|
|
15473
15492
|
name: "MarkdownRenderer",
|
|
15474
15493
|
components: {
|
|
15475
15494
|
MdTokenRenderer,
|
|
@@ -15487,7 +15506,7 @@ const _sfc_main$4 = defineComponent({
|
|
|
15487
15506
|
}
|
|
15488
15507
|
}
|
|
15489
15508
|
});
|
|
15490
|
-
function _sfc_render$
|
|
15509
|
+
function _sfc_render$5(_ctx, _cache, $props, $setup, $data, $options) {
|
|
15491
15510
|
const _component_md_token_renderer = resolveComponent("md-token-renderer");
|
|
15492
15511
|
const _component_audio_auto_player = resolveComponent("audio-auto-player");
|
|
15493
15512
|
return openBlock(), createElementBlock("div", null, [
|
|
@@ -15505,7 +15524,7 @@ function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
15505
15524
|
}), 128))
|
|
15506
15525
|
]);
|
|
15507
15526
|
}
|
|
15508
|
-
const MarkdownRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15527
|
+
const MarkdownRenderer = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["render", _sfc_render$5]]);
|
|
15509
15528
|
const MarkdownRenderer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
15510
15529
|
__proto__: null,
|
|
15511
15530
|
default: MarkdownRenderer
|
|
@@ -15557,6 +15576,22 @@ const useAuthStore = () => {
|
|
|
15557
15576
|
},
|
|
15558
15577
|
setRegDialog(open) {
|
|
15559
15578
|
this.loginAndRegistration.regDialogOpen = open;
|
|
15579
|
+
},
|
|
15580
|
+
async resetUserData() {
|
|
15581
|
+
try {
|
|
15582
|
+
if (!this._user) {
|
|
15583
|
+
throw new Error("No user available for data reset");
|
|
15584
|
+
}
|
|
15585
|
+
const result = await this._user.resetUserData();
|
|
15586
|
+
if (result.status !== "ok") {
|
|
15587
|
+
throw new Error(result.error || "Reset failed");
|
|
15588
|
+
}
|
|
15589
|
+
console.log("User data reset successfully");
|
|
15590
|
+
return result;
|
|
15591
|
+
} catch (error) {
|
|
15592
|
+
console.error("Failed to reset user data:", error);
|
|
15593
|
+
throw error;
|
|
15594
|
+
}
|
|
15560
15595
|
}
|
|
15561
15596
|
},
|
|
15562
15597
|
getters: {
|
|
@@ -15621,185 +15656,364 @@ const useConfigStore = () => {
|
|
|
15621
15656
|
}
|
|
15622
15657
|
})();
|
|
15623
15658
|
};
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
|
|
15635
|
-
|
|
15636
|
-
|
|
15637
|
-
|
|
15659
|
+
function useAuthUI() {
|
|
15660
|
+
const isLoading = ref(true);
|
|
15661
|
+
const syncStrategyDetected = ref(false);
|
|
15662
|
+
const isLocalOnlyMode = ref(false);
|
|
15663
|
+
const config = computed(() => {
|
|
15664
|
+
if (isLocalOnlyMode.value) {
|
|
15665
|
+
return {
|
|
15666
|
+
showLoginRegistration: false,
|
|
15667
|
+
showLogout: false,
|
|
15668
|
+
showResetData: true,
|
|
15669
|
+
logoutLabel: "",
|
|
15670
|
+
resetLabel: "Reset User Data"
|
|
15671
|
+
};
|
|
15672
|
+
} else {
|
|
15673
|
+
return {
|
|
15674
|
+
showLoginRegistration: true,
|
|
15675
|
+
showLogout: true,
|
|
15676
|
+
showResetData: false,
|
|
15677
|
+
logoutLabel: "Log out",
|
|
15678
|
+
resetLabel: ""
|
|
15679
|
+
};
|
|
15638
15680
|
}
|
|
15639
|
-
}
|
|
15640
|
-
|
|
15641
|
-
|
|
15642
|
-
|
|
15681
|
+
});
|
|
15682
|
+
const detectSyncStrategy = async () => {
|
|
15683
|
+
try {
|
|
15684
|
+
isLoading.value = true;
|
|
15685
|
+
const user = await getCurrentUser();
|
|
15686
|
+
const userInternal = user;
|
|
15687
|
+
const canCreateAccount = userInternal.syncStrategy?.canCreateAccount?.();
|
|
15688
|
+
isLocalOnlyMode.value = !canCreateAccount;
|
|
15689
|
+
syncStrategyDetected.value = true;
|
|
15690
|
+
} catch (error) {
|
|
15691
|
+
console.error("Failed to detect sync strategy:", error);
|
|
15692
|
+
isLocalOnlyMode.value = false;
|
|
15693
|
+
syncStrategyDetected.value = true;
|
|
15694
|
+
} finally {
|
|
15695
|
+
isLoading.value = false;
|
|
15696
|
+
}
|
|
15697
|
+
};
|
|
15698
|
+
return {
|
|
15699
|
+
config,
|
|
15700
|
+
isLoading,
|
|
15701
|
+
syncStrategyDetected,
|
|
15702
|
+
isLocalOnlyMode,
|
|
15703
|
+
detectSyncStrategy
|
|
15704
|
+
};
|
|
15705
|
+
}
|
|
15706
|
+
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
15707
|
+
__name: "UserChip",
|
|
15708
|
+
setup(__props) {
|
|
15709
|
+
const router = useRouter();
|
|
15710
|
+
const authStore = useAuthStore();
|
|
15711
|
+
const configStore = useConfigStore();
|
|
15712
|
+
const authUI = useAuthUI();
|
|
15713
|
+
const username = ref("");
|
|
15714
|
+
const items = ref([]);
|
|
15715
|
+
const showResetDialog = ref(false);
|
|
15716
|
+
const confirmationText = ref("");
|
|
15717
|
+
const isConfirmationValid = computed(() => confirmationText.value === "reset");
|
|
15718
|
+
const resetDialogState = () => {
|
|
15719
|
+
confirmationText.value = "";
|
|
15720
|
+
showResetDialog.value = false;
|
|
15721
|
+
};
|
|
15722
|
+
const hasNewItems = computed(() => items.value.length > 0);
|
|
15723
|
+
const authUIConfig = computed(() => {
|
|
15724
|
+
const configValue = authUI.config.value;
|
|
15725
|
+
const fallback = {
|
|
15726
|
+
showLoginRegistration: true,
|
|
15727
|
+
showLogout: true,
|
|
15728
|
+
showResetData: false,
|
|
15729
|
+
logoutLabel: "Log out",
|
|
15730
|
+
resetLabel: ""
|
|
15731
|
+
};
|
|
15732
|
+
return configValue || fallback;
|
|
15643
15733
|
});
|
|
15644
|
-
|
|
15645
|
-
|
|
15646
|
-
|
|
15647
|
-
|
|
15648
|
-
}
|
|
15649
|
-
async
|
|
15650
|
-
|
|
15651
|
-
}
|
|
15652
|
-
|
|
15653
|
-
|
|
15654
|
-
|
|
15655
|
-
|
|
15656
|
-
|
|
15657
|
-
|
|
15734
|
+
onMounted(async () => {
|
|
15735
|
+
const user = await getCurrentUser();
|
|
15736
|
+
username.value = user.getUsername();
|
|
15737
|
+
await authUI.detectSyncStrategy();
|
|
15738
|
+
});
|
|
15739
|
+
const gotoSettings = async () => {
|
|
15740
|
+
router.push(`/u/${(await getCurrentUser()).getUsername()}`);
|
|
15741
|
+
};
|
|
15742
|
+
const gotoStats = async () => {
|
|
15743
|
+
router.push(`/u/${(await getCurrentUser()).getUsername()}/stats`);
|
|
15744
|
+
};
|
|
15745
|
+
const dismiss = (item) => {
|
|
15746
|
+
const index = items.value.indexOf(item);
|
|
15747
|
+
items.value.splice(index, 1);
|
|
15748
|
+
};
|
|
15749
|
+
const logout = async () => {
|
|
15750
|
+
const res = await authStore._user.logout();
|
|
15658
15751
|
if (res.ok) {
|
|
15659
|
-
|
|
15752
|
+
authStore.loginAndRegistration = {
|
|
15660
15753
|
init: true,
|
|
15661
15754
|
loggedIn: false,
|
|
15662
15755
|
regDialogOpen: false,
|
|
15663
15756
|
loginDialogOpen: false
|
|
15664
15757
|
};
|
|
15665
|
-
|
|
15666
|
-
|
|
15758
|
+
configStore.resetDefaults();
|
|
15759
|
+
router.push("/home");
|
|
15667
15760
|
}
|
|
15668
|
-
}
|
|
15669
|
-
|
|
15670
|
-
|
|
15671
|
-
|
|
15672
|
-
|
|
15673
|
-
|
|
15674
|
-
|
|
15675
|
-
|
|
15676
|
-
|
|
15677
|
-
|
|
15678
|
-
|
|
15679
|
-
|
|
15680
|
-
|
|
15681
|
-
|
|
15682
|
-
|
|
15683
|
-
|
|
15684
|
-
|
|
15685
|
-
|
|
15686
|
-
|
|
15687
|
-
|
|
15688
|
-
|
|
15689
|
-
|
|
15690
|
-
|
|
15691
|
-
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
15699
|
-
|
|
15700
|
-
|
|
15701
|
-
|
|
15702
|
-
|
|
15703
|
-
|
|
15704
|
-
|
|
15705
|
-
|
|
15706
|
-
|
|
15707
|
-
|
|
15708
|
-
|
|
15709
|
-
|
|
15710
|
-
|
|
15711
|
-
_: 2
|
|
15712
|
-
}, 1040)
|
|
15713
|
-
]),
|
|
15714
|
-
default: withCtx(() => [
|
|
15715
|
-
createVNode(_component_v_list, null, {
|
|
15716
|
-
default: withCtx(() => [
|
|
15717
|
-
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.items, (item) => {
|
|
15718
|
-
return openBlock(), createBlock(_component_v_list_item, {
|
|
15719
|
-
key: item,
|
|
15720
|
-
onClick: ($event) => _ctx.dismiss(item)
|
|
15721
|
-
}, {
|
|
15761
|
+
};
|
|
15762
|
+
const executeReset = async () => {
|
|
15763
|
+
try {
|
|
15764
|
+
await authStore.resetUserData();
|
|
15765
|
+
configStore.resetDefaults();
|
|
15766
|
+
resetDialogState();
|
|
15767
|
+
router.push("/home");
|
|
15768
|
+
} catch (error) {
|
|
15769
|
+
console.error("Failed to reset user data:", error);
|
|
15770
|
+
}
|
|
15771
|
+
};
|
|
15772
|
+
return (_ctx, _cache) => {
|
|
15773
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
15774
|
+
const _component_v_avatar = resolveComponent("v-avatar");
|
|
15775
|
+
const _component_v_chip = resolveComponent("v-chip");
|
|
15776
|
+
const _component_v_list_item_title = resolveComponent("v-list-item-title");
|
|
15777
|
+
const _component_v_list_item = resolveComponent("v-list-item");
|
|
15778
|
+
const _component_v_divider = resolveComponent("v-divider");
|
|
15779
|
+
const _component_v_list = resolveComponent("v-list");
|
|
15780
|
+
const _component_v_menu = resolveComponent("v-menu");
|
|
15781
|
+
const _component_v_badge = resolveComponent("v-badge");
|
|
15782
|
+
const _component_v_card_title = resolveComponent("v-card-title");
|
|
15783
|
+
const _component_v_text_field = resolveComponent("v-text-field");
|
|
15784
|
+
const _component_v_card_text = resolveComponent("v-card-text");
|
|
15785
|
+
const _component_v_spacer = resolveComponent("v-spacer");
|
|
15786
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
15787
|
+
const _component_v_card_actions = resolveComponent("v-card-actions");
|
|
15788
|
+
const _component_v_card = resolveComponent("v-card");
|
|
15789
|
+
const _component_v_dialog = resolveComponent("v-dialog");
|
|
15790
|
+
return openBlock(), createElementBlock(Fragment, null, [
|
|
15791
|
+
createVNode(_component_v_badge, {
|
|
15792
|
+
content: items.value.length,
|
|
15793
|
+
"model-value": hasNewItems.value,
|
|
15794
|
+
color: "accent",
|
|
15795
|
+
location: "end top"
|
|
15796
|
+
}, {
|
|
15797
|
+
default: withCtx(() => [
|
|
15798
|
+
createVNode(_component_v_menu, {
|
|
15799
|
+
location: "bottom end",
|
|
15800
|
+
transition: "scale-transition"
|
|
15801
|
+
}, {
|
|
15802
|
+
activator: withCtx(({ props }) => [
|
|
15803
|
+
createVNode(_component_v_chip, mergeProps(props, { class: "ma-2" }), {
|
|
15722
15804
|
default: withCtx(() => [
|
|
15723
|
-
createVNode(
|
|
15805
|
+
createVNode(_component_v_avatar, {
|
|
15806
|
+
start: "",
|
|
15807
|
+
class: "bg-primary"
|
|
15808
|
+
}, {
|
|
15724
15809
|
default: withCtx(() => [
|
|
15725
|
-
|
|
15810
|
+
createVNode(_component_v_icon, null, {
|
|
15811
|
+
default: withCtx(() => _cache[4] || (_cache[4] = [
|
|
15812
|
+
createTextVNode("mdi-school")
|
|
15813
|
+
])),
|
|
15814
|
+
_: 1
|
|
15815
|
+
})
|
|
15726
15816
|
]),
|
|
15727
|
-
_:
|
|
15728
|
-
},
|
|
15817
|
+
_: 1
|
|
15818
|
+
}),
|
|
15819
|
+
createTextVNode(" " + toDisplayString(username.value), 1)
|
|
15729
15820
|
]),
|
|
15730
15821
|
_: 2
|
|
15731
|
-
},
|
|
15732
|
-
|
|
15733
|
-
|
|
15734
|
-
|
|
15735
|
-
|
|
15736
|
-
|
|
15737
|
-
|
|
15738
|
-
|
|
15739
|
-
|
|
15740
|
-
|
|
15741
|
-
|
|
15742
|
-
|
|
15743
|
-
|
|
15744
|
-
|
|
15745
|
-
|
|
15746
|
-
|
|
15747
|
-
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
15752
|
-
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
15757
|
-
|
|
15758
|
-
|
|
15759
|
-
|
|
15760
|
-
|
|
15761
|
-
|
|
15762
|
-
|
|
15763
|
-
|
|
15764
|
-
|
|
15765
|
-
|
|
15766
|
-
|
|
15767
|
-
|
|
15768
|
-
|
|
15769
|
-
|
|
15770
|
-
|
|
15771
|
-
|
|
15772
|
-
|
|
15773
|
-
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
|
|
15777
|
-
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
|
|
15784
|
-
|
|
15785
|
-
|
|
15786
|
-
|
|
15787
|
-
|
|
15788
|
-
|
|
15789
|
-
|
|
15790
|
-
|
|
15791
|
-
|
|
15792
|
-
|
|
15793
|
-
|
|
15794
|
-
|
|
15795
|
-
|
|
15796
|
-
|
|
15797
|
-
|
|
15798
|
-
|
|
15799
|
-
|
|
15800
|
-
|
|
15801
|
-
|
|
15802
|
-
|
|
15822
|
+
}, 1040)
|
|
15823
|
+
]),
|
|
15824
|
+
default: withCtx(() => [
|
|
15825
|
+
createVNode(_component_v_list, null, {
|
|
15826
|
+
default: withCtx(() => [
|
|
15827
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(items.value, (item) => {
|
|
15828
|
+
return openBlock(), createBlock(_component_v_list_item, {
|
|
15829
|
+
key: item,
|
|
15830
|
+
onClick: ($event) => dismiss(item)
|
|
15831
|
+
}, {
|
|
15832
|
+
default: withCtx(() => [
|
|
15833
|
+
createVNode(_component_v_list_item_title, null, {
|
|
15834
|
+
default: withCtx(() => [
|
|
15835
|
+
createTextVNode(toDisplayString(item), 1)
|
|
15836
|
+
]),
|
|
15837
|
+
_: 2
|
|
15838
|
+
}, 1024)
|
|
15839
|
+
]),
|
|
15840
|
+
_: 2
|
|
15841
|
+
}, 1032, ["onClick"]);
|
|
15842
|
+
}), 128)),
|
|
15843
|
+
items.value.length ? (openBlock(), createBlock(_component_v_divider, { key: 0 })) : createCommentVNode("", true),
|
|
15844
|
+
createVNode(_component_v_list_item, { onClick: gotoStats }, {
|
|
15845
|
+
prepend: withCtx(() => [
|
|
15846
|
+
createVNode(_component_v_icon, null, {
|
|
15847
|
+
default: withCtx(() => _cache[5] || (_cache[5] = [
|
|
15848
|
+
createTextVNode("mdi-trending-up")
|
|
15849
|
+
])),
|
|
15850
|
+
_: 1
|
|
15851
|
+
})
|
|
15852
|
+
]),
|
|
15853
|
+
default: withCtx(() => [
|
|
15854
|
+
createVNode(_component_v_list_item_title, null, {
|
|
15855
|
+
default: withCtx(() => _cache[6] || (_cache[6] = [
|
|
15856
|
+
createTextVNode("Stats")
|
|
15857
|
+
])),
|
|
15858
|
+
_: 1
|
|
15859
|
+
})
|
|
15860
|
+
]),
|
|
15861
|
+
_: 1
|
|
15862
|
+
}),
|
|
15863
|
+
createVNode(_component_v_list_item, { onClick: gotoSettings }, {
|
|
15864
|
+
prepend: withCtx(() => [
|
|
15865
|
+
createVNode(_component_v_icon, null, {
|
|
15866
|
+
default: withCtx(() => _cache[7] || (_cache[7] = [
|
|
15867
|
+
createTextVNode("mdi-cog")
|
|
15868
|
+
])),
|
|
15869
|
+
_: 1
|
|
15870
|
+
})
|
|
15871
|
+
]),
|
|
15872
|
+
default: withCtx(() => [
|
|
15873
|
+
createVNode(_component_v_list_item_title, null, {
|
|
15874
|
+
default: withCtx(() => _cache[8] || (_cache[8] = [
|
|
15875
|
+
createTextVNode("Settings")
|
|
15876
|
+
])),
|
|
15877
|
+
_: 1
|
|
15878
|
+
})
|
|
15879
|
+
]),
|
|
15880
|
+
_: 1
|
|
15881
|
+
}),
|
|
15882
|
+
authUIConfig.value.showLogout ? (openBlock(), createBlock(_component_v_list_item, {
|
|
15883
|
+
key: 1,
|
|
15884
|
+
onClick: logout
|
|
15885
|
+
}, {
|
|
15886
|
+
prepend: withCtx(() => [
|
|
15887
|
+
createVNode(_component_v_icon, null, {
|
|
15888
|
+
default: withCtx(() => _cache[9] || (_cache[9] = [
|
|
15889
|
+
createTextVNode("mdi-logout")
|
|
15890
|
+
])),
|
|
15891
|
+
_: 1
|
|
15892
|
+
})
|
|
15893
|
+
]),
|
|
15894
|
+
default: withCtx(() => [
|
|
15895
|
+
createVNode(_component_v_list_item_title, null, {
|
|
15896
|
+
default: withCtx(() => [
|
|
15897
|
+
createTextVNode(toDisplayString(authUIConfig.value.logoutLabel), 1)
|
|
15898
|
+
]),
|
|
15899
|
+
_: 1
|
|
15900
|
+
})
|
|
15901
|
+
]),
|
|
15902
|
+
_: 1
|
|
15903
|
+
})) : createCommentVNode("", true),
|
|
15904
|
+
authUIConfig.value.showResetData ? (openBlock(), createBlock(_component_v_list_item, {
|
|
15905
|
+
key: 2,
|
|
15906
|
+
onClick: _cache[0] || (_cache[0] = ($event) => showResetDialog.value = true)
|
|
15907
|
+
}, {
|
|
15908
|
+
prepend: withCtx(() => [
|
|
15909
|
+
createVNode(_component_v_icon, null, {
|
|
15910
|
+
default: withCtx(() => _cache[10] || (_cache[10] = [
|
|
15911
|
+
createTextVNode("mdi-delete-sweep")
|
|
15912
|
+
])),
|
|
15913
|
+
_: 1
|
|
15914
|
+
})
|
|
15915
|
+
]),
|
|
15916
|
+
default: withCtx(() => [
|
|
15917
|
+
createVNode(_component_v_list_item_title, null, {
|
|
15918
|
+
default: withCtx(() => [
|
|
15919
|
+
createTextVNode(toDisplayString(authUIConfig.value.resetLabel), 1)
|
|
15920
|
+
]),
|
|
15921
|
+
_: 1
|
|
15922
|
+
})
|
|
15923
|
+
]),
|
|
15924
|
+
_: 1
|
|
15925
|
+
})) : createCommentVNode("", true)
|
|
15926
|
+
]),
|
|
15927
|
+
_: 1
|
|
15928
|
+
})
|
|
15929
|
+
]),
|
|
15930
|
+
_: 1
|
|
15931
|
+
})
|
|
15932
|
+
]),
|
|
15933
|
+
_: 1
|
|
15934
|
+
}, 8, ["content", "model-value"]),
|
|
15935
|
+
createVNode(_component_v_dialog, {
|
|
15936
|
+
modelValue: showResetDialog.value,
|
|
15937
|
+
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => showResetDialog.value = $event),
|
|
15938
|
+
"max-width": "500px",
|
|
15939
|
+
persistent: ""
|
|
15940
|
+
}, {
|
|
15941
|
+
default: withCtx(() => [
|
|
15942
|
+
createVNode(_component_v_card, null, {
|
|
15943
|
+
default: withCtx(() => [
|
|
15944
|
+
createVNode(_component_v_card_title, { class: "text-h5 d-flex align-center" }, {
|
|
15945
|
+
default: withCtx(() => [
|
|
15946
|
+
createVNode(_component_v_icon, {
|
|
15947
|
+
color: "warning",
|
|
15948
|
+
class: "mr-3"
|
|
15949
|
+
}, {
|
|
15950
|
+
default: withCtx(() => _cache[11] || (_cache[11] = [
|
|
15951
|
+
createTextVNode("mdi-alert-circle")
|
|
15952
|
+
])),
|
|
15953
|
+
_: 1
|
|
15954
|
+
}),
|
|
15955
|
+
_cache[12] || (_cache[12] = createTextVNode(" Reset All User Data "))
|
|
15956
|
+
]),
|
|
15957
|
+
_: 1
|
|
15958
|
+
}),
|
|
15959
|
+
createVNode(_component_v_card_text, null, {
|
|
15960
|
+
default: withCtx(() => [
|
|
15961
|
+
_cache[13] || (_cache[13] = createElementVNode("p", { class: "mb-4" }, "This will permanently delete:", -1)),
|
|
15962
|
+
_cache[14] || (_cache[14] = createElementVNode("ul", { class: "mb-4" }, [
|
|
15963
|
+
createElementVNode("li", null, "All course progress and history"),
|
|
15964
|
+
createElementVNode("li", null, "Scheduled card reviews"),
|
|
15965
|
+
createElementVNode("li", null, "Course registrations"),
|
|
15966
|
+
createElementVNode("li", null, "User preferences")
|
|
15967
|
+
], -1)),
|
|
15968
|
+
_cache[15] || (_cache[15] = createElementVNode("p", { class: "mb-4 text-error font-weight-bold" }, "This cannot be undone.", -1)),
|
|
15969
|
+
createVNode(_component_v_text_field, {
|
|
15970
|
+
modelValue: confirmationText.value,
|
|
15971
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => confirmationText.value = $event),
|
|
15972
|
+
label: 'Type "reset" to confirm',
|
|
15973
|
+
outlined: "",
|
|
15974
|
+
dense: "",
|
|
15975
|
+
onKeyup: _cache[2] || (_cache[2] = withKeys(($event) => isConfirmationValid.value && executeReset(), ["enter"]))
|
|
15976
|
+
}, null, 8, ["modelValue"])
|
|
15977
|
+
]),
|
|
15978
|
+
_: 1
|
|
15979
|
+
}),
|
|
15980
|
+
createVNode(_component_v_card_actions, null, {
|
|
15981
|
+
default: withCtx(() => [
|
|
15982
|
+
createVNode(_component_v_spacer),
|
|
15983
|
+
createVNode(_component_v_btn, {
|
|
15984
|
+
text: "",
|
|
15985
|
+
onClick: resetDialogState
|
|
15986
|
+
}, {
|
|
15987
|
+
default: withCtx(() => _cache[16] || (_cache[16] = [
|
|
15988
|
+
createTextVNode("Cancel")
|
|
15989
|
+
])),
|
|
15990
|
+
_: 1
|
|
15991
|
+
}),
|
|
15992
|
+
createVNode(_component_v_btn, {
|
|
15993
|
+
color: "error",
|
|
15994
|
+
disabled: !isConfirmationValid.value,
|
|
15995
|
+
onClick: executeReset
|
|
15996
|
+
}, {
|
|
15997
|
+
default: withCtx(() => _cache[17] || (_cache[17] = [
|
|
15998
|
+
createTextVNode(" Reset All Data ")
|
|
15999
|
+
])),
|
|
16000
|
+
_: 1
|
|
16001
|
+
}, 8, ["disabled"])
|
|
16002
|
+
]),
|
|
16003
|
+
_: 1
|
|
16004
|
+
})
|
|
16005
|
+
]),
|
|
16006
|
+
_: 1
|
|
16007
|
+
})
|
|
16008
|
+
]),
|
|
16009
|
+
_: 1
|
|
16010
|
+
}, 8, ["modelValue"])
|
|
16011
|
+
], 64);
|
|
16012
|
+
};
|
|
16013
|
+
}
|
|
16014
|
+
});
|
|
16015
|
+
const UserChip = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-53f0aa4d"]]);
|
|
16016
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
15803
16017
|
__name: "UserLogin",
|
|
15804
16018
|
emits: ["toggle"],
|
|
15805
16019
|
setup(__props, { emit: __emit }) {
|
|
@@ -15986,8 +16200,8 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
|
15986
16200
|
};
|
|
15987
16201
|
}
|
|
15988
16202
|
});
|
|
15989
|
-
const UserLogin = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
15990
|
-
const _sfc_main$
|
|
16203
|
+
const UserLogin = /* @__PURE__ */ _export_sfc(_sfc_main$6, [["__scopeId", "data-v-acfaa2d0"]]);
|
|
16204
|
+
const _sfc_main$5 = defineComponent({
|
|
15991
16205
|
name: "UserRegistration",
|
|
15992
16206
|
emits: ["toggle"],
|
|
15993
16207
|
data() {
|
|
@@ -16086,7 +16300,7 @@ Author: ${this.author}
|
|
|
16086
16300
|
}
|
|
16087
16301
|
}
|
|
16088
16302
|
});
|
|
16089
|
-
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
16303
|
+
function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) {
|
|
16090
16304
|
const _component_v_card_title = resolveComponent("v-card-title");
|
|
16091
16305
|
const _component_v_text_field = resolveComponent("v-text-field");
|
|
16092
16306
|
const _component_v_btn = resolveComponent("v-btn");
|
|
@@ -16221,13 +16435,17 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
16221
16435
|
_: 1
|
|
16222
16436
|
});
|
|
16223
16437
|
}
|
|
16224
|
-
const UserRegistration = /* @__PURE__ */ _export_sfc(_sfc_main$
|
|
16225
|
-
const _hoisted_1 = { key: 0 };
|
|
16226
|
-
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
16438
|
+
const UserRegistration = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["render", _sfc_render$4]]);
|
|
16439
|
+
const _hoisted_1$4 = { key: 0 };
|
|
16440
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
16227
16441
|
__name: "UserLoginAndRegistrationContainer",
|
|
16228
16442
|
setup(__props) {
|
|
16229
16443
|
const route = useRoute();
|
|
16230
16444
|
const authStore = useAuthStore();
|
|
16445
|
+
const authUI = useAuthUI();
|
|
16446
|
+
onMounted(async () => {
|
|
16447
|
+
await authUI.detectSyncStrategy();
|
|
16448
|
+
});
|
|
16231
16449
|
const display = computed(() => {
|
|
16232
16450
|
if (!route.name || typeof route.name !== "string") {
|
|
16233
16451
|
return true;
|
|
@@ -16242,6 +16460,13 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
16242
16460
|
}
|
|
16243
16461
|
return !authStore.loginAndRegistration.loggedIn;
|
|
16244
16462
|
});
|
|
16463
|
+
const authUIConfig = computed(() => authUI.config.value || {
|
|
16464
|
+
showLoginRegistration: true,
|
|
16465
|
+
showLogout: true,
|
|
16466
|
+
showResetData: false,
|
|
16467
|
+
logoutLabel: "Log out",
|
|
16468
|
+
resetLabel: ""
|
|
16469
|
+
});
|
|
16245
16470
|
const regDialog = computed({
|
|
16246
16471
|
get: () => authStore.loginAndRegistration.regDialogOpen,
|
|
16247
16472
|
set: (value) => {
|
|
@@ -16273,7 +16498,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
16273
16498
|
mode: "out-in"
|
|
16274
16499
|
}, {
|
|
16275
16500
|
default: withCtx(() => [
|
|
16276
|
-
guestMode.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
16501
|
+
guestMode.value && authUIConfig.value.showLoginRegistration ? (openBlock(), createElementBlock("div", _hoisted_1$4, [
|
|
16277
16502
|
createVNode(_component_v_dialog, {
|
|
16278
16503
|
modelValue: regDialog.value,
|
|
16279
16504
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => regDialog.value = $event),
|
|
@@ -16324,12 +16549,962 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
16324
16549
|
};
|
|
16325
16550
|
}
|
|
16326
16551
|
});
|
|
16327
|
-
const UserLoginAndRegistrationContainer = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-
|
|
16552
|
+
const UserLoginAndRegistrationContainer = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-6091ae05"]]);
|
|
16553
|
+
const _sfc_main$3 = defineComponent({
|
|
16554
|
+
name: "SkTagsInput",
|
|
16555
|
+
components: {
|
|
16556
|
+
VueTagsInput
|
|
16557
|
+
},
|
|
16558
|
+
props: {
|
|
16559
|
+
courseID: {
|
|
16560
|
+
type: String,
|
|
16561
|
+
required: true,
|
|
16562
|
+
default: ""
|
|
16563
|
+
},
|
|
16564
|
+
cardID: {
|
|
16565
|
+
type: String,
|
|
16566
|
+
required: false,
|
|
16567
|
+
default: ""
|
|
16568
|
+
},
|
|
16569
|
+
hideSubmit: {
|
|
16570
|
+
type: Boolean,
|
|
16571
|
+
required: false,
|
|
16572
|
+
default: false
|
|
16573
|
+
}
|
|
16574
|
+
},
|
|
16575
|
+
data() {
|
|
16576
|
+
return {
|
|
16577
|
+
loading: true,
|
|
16578
|
+
tag: "",
|
|
16579
|
+
tags: [],
|
|
16580
|
+
initialTags: [],
|
|
16581
|
+
availableCourseTags: [],
|
|
16582
|
+
separators: [";", ",", " "],
|
|
16583
|
+
courseDB: null
|
|
16584
|
+
};
|
|
16585
|
+
},
|
|
16586
|
+
computed: {
|
|
16587
|
+
autoCompleteSuggestions() {
|
|
16588
|
+
return this.availableCourseTags.filter((availableTag) => {
|
|
16589
|
+
return availableTag.name.toLowerCase().indexOf(this.tag.toLowerCase()) !== -1;
|
|
16590
|
+
}).map((availableTag) => {
|
|
16591
|
+
return {
|
|
16592
|
+
text: availableTag.name,
|
|
16593
|
+
data: {
|
|
16594
|
+
snippet: availableTag.snippet
|
|
16595
|
+
}
|
|
16596
|
+
};
|
|
16597
|
+
});
|
|
16598
|
+
}
|
|
16599
|
+
},
|
|
16600
|
+
watch: {
|
|
16601
|
+
async cardID() {
|
|
16602
|
+
await this.getAppliedTags();
|
|
16603
|
+
},
|
|
16604
|
+
async courseID() {
|
|
16605
|
+
this.courseDB = getDataLayer().getCourseDB(this.courseID);
|
|
16606
|
+
await this.updateAvailableCourseTags();
|
|
16607
|
+
}
|
|
16608
|
+
},
|
|
16609
|
+
async created() {
|
|
16610
|
+
this.courseDB = getDataLayer().getCourseDB(this.courseID);
|
|
16611
|
+
await this.updateAvailableCourseTags();
|
|
16612
|
+
await this.getAppliedTags();
|
|
16613
|
+
},
|
|
16614
|
+
methods: {
|
|
16615
|
+
tagsChanged(newTags) {
|
|
16616
|
+
console.log(`[TagsInput] Tags changing: ${JSON.stringify(newTags)}`);
|
|
16617
|
+
this.tags = newTags;
|
|
16618
|
+
},
|
|
16619
|
+
async getAppliedTags() {
|
|
16620
|
+
this.initialTags = [];
|
|
16621
|
+
this.tags = [];
|
|
16622
|
+
try {
|
|
16623
|
+
const appliedDocsFindResult = await this.courseDB.getAppliedTags(this.cardID);
|
|
16624
|
+
appliedDocsFindResult.rows.forEach((row) => {
|
|
16625
|
+
console.log(`[TagsInput] The following tag is applied:
|
|
16626
|
+
${JSON.stringify(row)}`);
|
|
16627
|
+
this.tags.push({
|
|
16628
|
+
text: row.value.name,
|
|
16629
|
+
style: "",
|
|
16630
|
+
classes: ""
|
|
16631
|
+
});
|
|
16632
|
+
});
|
|
16633
|
+
this.initialTags = this.tags.map((tag2) => tag2.text);
|
|
16634
|
+
} catch (e) {
|
|
16635
|
+
console.error(`Error in init-getAppliedTags: ${JSON.stringify(e)}, ${e}`);
|
|
16636
|
+
} finally {
|
|
16637
|
+
this.loading = false;
|
|
16638
|
+
}
|
|
16639
|
+
},
|
|
16640
|
+
async updateAvailableCourseTags() {
|
|
16641
|
+
try {
|
|
16642
|
+
this.availableCourseTags = (await this.courseDB.getCourseTagStubs()).rows.map((row) => {
|
|
16643
|
+
console.log(`[TagsInput] available tag: ${JSON.stringify(row)}`);
|
|
16644
|
+
return row.doc;
|
|
16645
|
+
});
|
|
16646
|
+
} catch (e) {
|
|
16647
|
+
console.error(`Error in init-availableCourseTags: ${JSON.stringify(e)}`);
|
|
16648
|
+
}
|
|
16649
|
+
},
|
|
16650
|
+
async submit() {
|
|
16651
|
+
console.log(`[TagsInput] tagsInput is submitting...`);
|
|
16652
|
+
this.loading = true;
|
|
16653
|
+
try {
|
|
16654
|
+
await Promise.all(
|
|
16655
|
+
this.tags.map(async (currentTag) => {
|
|
16656
|
+
if (!this.initialTags.includes(currentTag.text)) {
|
|
16657
|
+
try {
|
|
16658
|
+
await this.courseDB.addTagToCard(this.cardID, currentTag.text);
|
|
16659
|
+
console.log(`[TagsInput] Successfully added tag: ${currentTag.text}`);
|
|
16660
|
+
} catch (error) {
|
|
16661
|
+
console.error(`Failed to add tag ${currentTag.text}:`, error);
|
|
16662
|
+
}
|
|
16663
|
+
}
|
|
16664
|
+
})
|
|
16665
|
+
);
|
|
16666
|
+
} catch (e) {
|
|
16667
|
+
console.error(`Exception adding tags: ${JSON.stringify(e)}`);
|
|
16668
|
+
}
|
|
16669
|
+
try {
|
|
16670
|
+
await Promise.all(
|
|
16671
|
+
this.initialTags.map(async (initialTag) => {
|
|
16672
|
+
if (this.tags.filter((tag2) => {
|
|
16673
|
+
return tag2.text === initialTag;
|
|
16674
|
+
}).length === 0) {
|
|
16675
|
+
try {
|
|
16676
|
+
await this.courseDB.removeTagFromCard(this.cardID, initialTag);
|
|
16677
|
+
console.log(`[TagsInput] Successfully removed tag: ${initialTag}`);
|
|
16678
|
+
} catch (error) {
|
|
16679
|
+
console.error(`Failed to remove tag ${initialTag}:`, error);
|
|
16680
|
+
}
|
|
16681
|
+
}
|
|
16682
|
+
})
|
|
16683
|
+
);
|
|
16684
|
+
} catch (e) {
|
|
16685
|
+
console.error(`Exception removing tags: ${JSON.stringify(e)}`);
|
|
16686
|
+
}
|
|
16687
|
+
this.loading = false;
|
|
16688
|
+
}
|
|
16689
|
+
}
|
|
16690
|
+
});
|
|
16691
|
+
const _hoisted_1$3 = { "data-cy": "tags-input" };
|
|
16692
|
+
const _hoisted_2$2 = { class: "tag-name" };
|
|
16693
|
+
const _hoisted_3$2 = {
|
|
16694
|
+
key: 0,
|
|
16695
|
+
class: "tag-snippet"
|
|
16696
|
+
};
|
|
16697
|
+
function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) {
|
|
16698
|
+
const _component_vue_tags_input = resolveComponent("vue-tags-input");
|
|
16699
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
16700
|
+
return openBlock(), createElementBlock("div", _hoisted_1$3, [
|
|
16701
|
+
createVNode(_component_vue_tags_input, {
|
|
16702
|
+
modelValue: _ctx.tag,
|
|
16703
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.tag = $event),
|
|
16704
|
+
tags: _ctx.tags,
|
|
16705
|
+
"autocomplete-items": _ctx.autoCompleteSuggestions,
|
|
16706
|
+
separators: _ctx.separators,
|
|
16707
|
+
"add-on-key": _ctx.separators,
|
|
16708
|
+
onTagsChanged: _ctx.tagsChanged
|
|
16709
|
+
}, {
|
|
16710
|
+
"autocomplete-item": withCtx((props) => [
|
|
16711
|
+
createElementVNode("div", {
|
|
16712
|
+
class: normalizeClass(["autocomplete-item", { "is-active": props.selected }])
|
|
16713
|
+
}, [
|
|
16714
|
+
createElementVNode("span", _hoisted_2$2, toDisplayString(props.item.text), 1),
|
|
16715
|
+
props.item.data && props.item.data.snippet ? (openBlock(), createElementBlock("span", _hoisted_3$2, " - " + toDisplayString(props.item.data.snippet), 1)) : createCommentVNode("", true)
|
|
16716
|
+
], 2)
|
|
16717
|
+
]),
|
|
16718
|
+
_: 1
|
|
16719
|
+
}, 8, ["modelValue", "tags", "autocomplete-items", "separators", "add-on-key", "onTagsChanged"]),
|
|
16720
|
+
!_ctx.hideSubmit ? (openBlock(), createBlock(_component_v_btn, {
|
|
16721
|
+
key: 0,
|
|
16722
|
+
color: "success",
|
|
16723
|
+
loading: _ctx.loading,
|
|
16724
|
+
onClick: _ctx.submit
|
|
16725
|
+
}, {
|
|
16726
|
+
default: withCtx(() => _cache[1] || (_cache[1] = [
|
|
16727
|
+
createTextVNode("Save Changes")
|
|
16728
|
+
])),
|
|
16729
|
+
_: 1
|
|
16730
|
+
}, 8, ["loading", "onClick"])) : createCommentVNode("", true)
|
|
16731
|
+
]);
|
|
16732
|
+
}
|
|
16733
|
+
const TagsInput = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3], ["__scopeId", "data-v-dec3b5c8"]]);
|
|
16734
|
+
function isConstructor(obj) {
|
|
16735
|
+
try {
|
|
16736
|
+
new obj();
|
|
16737
|
+
return true;
|
|
16738
|
+
} catch (e) {
|
|
16739
|
+
console.warn(`not a constructor: ${obj}, err: ${e}`);
|
|
16740
|
+
return false;
|
|
16741
|
+
}
|
|
16742
|
+
}
|
|
16743
|
+
const _sfc_main$2 = defineComponent({
|
|
16744
|
+
name: "CourseCardBrowser",
|
|
16745
|
+
components: {
|
|
16746
|
+
CardLoader,
|
|
16747
|
+
TagsInput,
|
|
16748
|
+
PaginatingToolbar
|
|
16749
|
+
},
|
|
16750
|
+
props: {
|
|
16751
|
+
courseId: {
|
|
16752
|
+
type: String,
|
|
16753
|
+
required: true
|
|
16754
|
+
},
|
|
16755
|
+
tagId: {
|
|
16756
|
+
type: String,
|
|
16757
|
+
required: false,
|
|
16758
|
+
default: ""
|
|
16759
|
+
},
|
|
16760
|
+
viewLookupFunction: {
|
|
16761
|
+
type: Function,
|
|
16762
|
+
required: true,
|
|
16763
|
+
default: (x) => {
|
|
16764
|
+
console.warn("No viewLookupFunction provided to CourseCardBrowser");
|
|
16765
|
+
return null;
|
|
16766
|
+
}
|
|
16767
|
+
},
|
|
16768
|
+
editMode: {
|
|
16769
|
+
type: String,
|
|
16770
|
+
required: false,
|
|
16771
|
+
default: "full"
|
|
16772
|
+
}
|
|
16773
|
+
},
|
|
16774
|
+
data() {
|
|
16775
|
+
return {
|
|
16776
|
+
courseDB: null,
|
|
16777
|
+
page: 1,
|
|
16778
|
+
pages: [],
|
|
16779
|
+
cards: [],
|
|
16780
|
+
cardData: {},
|
|
16781
|
+
cardPreview: {},
|
|
16782
|
+
internalEditMode: "none",
|
|
16783
|
+
delBtn: false,
|
|
16784
|
+
updatePending: true,
|
|
16785
|
+
userIsRegistered: false,
|
|
16786
|
+
questionCount: 0,
|
|
16787
|
+
tags: [],
|
|
16788
|
+
viewLookup: this.viewLookupFunction
|
|
16789
|
+
};
|
|
16790
|
+
},
|
|
16791
|
+
async created() {
|
|
16792
|
+
try {
|
|
16793
|
+
this.courseDB = getDataLayer().getCourseDB(this.courseId);
|
|
16794
|
+
if (this.tagId) {
|
|
16795
|
+
this.questionCount = (await this.courseDB.getTag(this.tagId)).taggedCards.length;
|
|
16796
|
+
} else {
|
|
16797
|
+
this.questionCount = (await this.courseDB.getCourseInfo()).cardCount;
|
|
16798
|
+
}
|
|
16799
|
+
for (let i = 1; (i - 1) * 25 < this.questionCount; i++) {
|
|
16800
|
+
this.pages.push(i);
|
|
16801
|
+
}
|
|
16802
|
+
await this.populateTableData();
|
|
16803
|
+
} catch (error) {
|
|
16804
|
+
console.error("Error initializing CourseCardBrowser:", error);
|
|
16805
|
+
} finally {
|
|
16806
|
+
this.updatePending = false;
|
|
16807
|
+
}
|
|
16808
|
+
},
|
|
16809
|
+
methods: {
|
|
16810
|
+
first() {
|
|
16811
|
+
this.page = 1;
|
|
16812
|
+
this.populateTableData();
|
|
16813
|
+
},
|
|
16814
|
+
prev() {
|
|
16815
|
+
this.page--;
|
|
16816
|
+
this.populateTableData();
|
|
16817
|
+
},
|
|
16818
|
+
next() {
|
|
16819
|
+
this.page++;
|
|
16820
|
+
this.populateTableData();
|
|
16821
|
+
},
|
|
16822
|
+
last() {
|
|
16823
|
+
this.page = this.pages.length;
|
|
16824
|
+
this.populateTableData();
|
|
16825
|
+
},
|
|
16826
|
+
setPage(n) {
|
|
16827
|
+
this.page = n;
|
|
16828
|
+
this.populateTableData();
|
|
16829
|
+
},
|
|
16830
|
+
clearSelections(exception = "") {
|
|
16831
|
+
this.cards.forEach((card) => {
|
|
16832
|
+
if (card.id !== exception) {
|
|
16833
|
+
card.isOpen = false;
|
|
16834
|
+
}
|
|
16835
|
+
});
|
|
16836
|
+
this.internalEditMode = "none";
|
|
16837
|
+
this.delBtn = false;
|
|
16838
|
+
},
|
|
16839
|
+
async deleteCard(c) {
|
|
16840
|
+
console.log(`Deleting card ${c}`);
|
|
16841
|
+
const res = await this.courseDB.removeCard(c.split("-")[1]);
|
|
16842
|
+
if (res.ok) {
|
|
16843
|
+
this.cards = this.cards.filter((card) => card.id != c);
|
|
16844
|
+
this.clearSelections();
|
|
16845
|
+
} else {
|
|
16846
|
+
console.error(`Failed to delete card:
|
|
16847
|
+
|
|
16848
|
+
${JSON.stringify(res)}`);
|
|
16849
|
+
alertUser({
|
|
16850
|
+
text: "Failed to delete card",
|
|
16851
|
+
status: Status.error
|
|
16852
|
+
});
|
|
16853
|
+
}
|
|
16854
|
+
},
|
|
16855
|
+
async populateTableData() {
|
|
16856
|
+
this.updatePending = true;
|
|
16857
|
+
if (this.tagId) {
|
|
16858
|
+
const tag2 = await this.courseDB.getTag(this.tagId);
|
|
16859
|
+
this.cards = tag2.taggedCards.map((c) => {
|
|
16860
|
+
return { id: `${this.courseId}-${c}`, isOpen: false, delBtn: false };
|
|
16861
|
+
});
|
|
16862
|
+
} else {
|
|
16863
|
+
this.cards = (await this.courseDB.getCardsByELO(0, 25)).map((c) => {
|
|
16864
|
+
return {
|
|
16865
|
+
id: c,
|
|
16866
|
+
isOpen: false,
|
|
16867
|
+
delBtn: false
|
|
16868
|
+
};
|
|
16869
|
+
});
|
|
16870
|
+
}
|
|
16871
|
+
const toRemove = [];
|
|
16872
|
+
const hydratedCardData = (await this.courseDB.getCourseDocs(
|
|
16873
|
+
this.cards.map((c) => c.id.split("-")[1]),
|
|
16874
|
+
{
|
|
16875
|
+
include_docs: true
|
|
16876
|
+
}
|
|
16877
|
+
)).rows.filter((r2) => {
|
|
16878
|
+
if (r2.doc) {
|
|
16879
|
+
return true;
|
|
16880
|
+
} else {
|
|
16881
|
+
console.error(`Card ${r2.id}.doc not found.
|
|
16882
|
+
card: ${JSON.stringify(r2)}`);
|
|
16883
|
+
return false;
|
|
16884
|
+
}
|
|
16885
|
+
}).map((r2) => r2.doc);
|
|
16886
|
+
this.cards = this.cards.filter((c) => !toRemove.includes(c.id.split("-")[1]));
|
|
16887
|
+
hydratedCardData.forEach((c) => {
|
|
16888
|
+
if (c && c.id_displayable_data) {
|
|
16889
|
+
this.cardData[c._id] = c.id_displayable_data;
|
|
16890
|
+
}
|
|
16891
|
+
});
|
|
16892
|
+
try {
|
|
16893
|
+
await Promise.all(
|
|
16894
|
+
this.cards.map(async (c) => {
|
|
16895
|
+
const _cardID = c.id.split("-")[1];
|
|
16896
|
+
const tmpCardData = hydratedCardData.find((c2) => c2._id == _cardID);
|
|
16897
|
+
if (!tmpCardData || !tmpCardData.id_displayable_data) {
|
|
16898
|
+
console.error(`No valid data found for card ${_cardID}`);
|
|
16899
|
+
return;
|
|
16900
|
+
}
|
|
16901
|
+
const tmpView = this.viewLookupFunction(
|
|
16902
|
+
tmpCardData.id_view || "default.question.BlanksCard.FillInView"
|
|
16903
|
+
);
|
|
16904
|
+
const tmpDataDocs = tmpCardData.id_displayable_data.map((id) => {
|
|
16905
|
+
return this.courseDB.getCourseDoc(id, {
|
|
16906
|
+
attachments: false,
|
|
16907
|
+
binary: true
|
|
16908
|
+
});
|
|
16909
|
+
});
|
|
16910
|
+
const allDocs = await Promise.all(tmpDataDocs);
|
|
16911
|
+
await Promise.all(
|
|
16912
|
+
allDocs.map((doc) => {
|
|
16913
|
+
const tmpData = [];
|
|
16914
|
+
tmpData.unshift(displayableDataToViewData(doc));
|
|
16915
|
+
if (isConstructor(tmpView)) {
|
|
16916
|
+
const view = new tmpView();
|
|
16917
|
+
view.data = tmpData;
|
|
16918
|
+
this.cardPreview[c.id] = view.toString();
|
|
16919
|
+
} else {
|
|
16920
|
+
this.cardPreview[c.id] = tmpView.name ? tmpView.name : "Unknown";
|
|
16921
|
+
}
|
|
16922
|
+
})
|
|
16923
|
+
);
|
|
16924
|
+
})
|
|
16925
|
+
);
|
|
16926
|
+
} catch (error) {
|
|
16927
|
+
console.error("Error populating table data:", error);
|
|
16928
|
+
} finally {
|
|
16929
|
+
this.updatePending = false;
|
|
16930
|
+
this.$forceUpdate();
|
|
16931
|
+
}
|
|
16932
|
+
}
|
|
16933
|
+
}
|
|
16934
|
+
});
|
|
16935
|
+
const _hoisted_1$2 = {
|
|
16936
|
+
key: 0,
|
|
16937
|
+
class: "d-flex justify-center align-center pa-6"
|
|
16938
|
+
};
|
|
16939
|
+
const _hoisted_2$1 = { key: 1 };
|
|
16940
|
+
const _hoisted_3$1 = {
|
|
16941
|
+
key: 0,
|
|
16942
|
+
class: "px-4 py-2 bg-blue-grey-lighten-5"
|
|
16943
|
+
};
|
|
16944
|
+
const _hoisted_4$1 = { class: "mt-4" };
|
|
16945
|
+
const _hoisted_5$1 = {
|
|
16946
|
+
key: 0,
|
|
16947
|
+
class: "ml-4"
|
|
16948
|
+
};
|
|
16949
|
+
function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) {
|
|
16950
|
+
const _component_v_progress_circular = resolveComponent("v-progress-circular");
|
|
16951
|
+
const _component_paginating_toolbar = resolveComponent("paginating-toolbar");
|
|
16952
|
+
const _component_v_list_item_title = resolveComponent("v-list-item-title");
|
|
16953
|
+
const _component_v_list_item_subtitle = resolveComponent("v-list-item-subtitle");
|
|
16954
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
16955
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
16956
|
+
const _component_v_speed_dial = resolveComponent("v-speed-dial");
|
|
16957
|
+
const _component_v_list_item = resolveComponent("v-list-item");
|
|
16958
|
+
const _component_card_loader = resolveComponent("card-loader");
|
|
16959
|
+
const _component_tags_input = resolveComponent("tags-input");
|
|
16960
|
+
const _component_v_list = resolveComponent("v-list");
|
|
16961
|
+
const _component_v_card = resolveComponent("v-card");
|
|
16962
|
+
return openBlock(), createBlock(_component_v_card, null, {
|
|
16963
|
+
default: withCtx(() => [
|
|
16964
|
+
_ctx.updatePending ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
|
|
16965
|
+
createVNode(_component_v_progress_circular, {
|
|
16966
|
+
indeterminate: "",
|
|
16967
|
+
color: "primary"
|
|
16968
|
+
})
|
|
16969
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_2$1, [
|
|
16970
|
+
createVNode(_component_paginating_toolbar, {
|
|
16971
|
+
title: "Exercises",
|
|
16972
|
+
page: _ctx.page,
|
|
16973
|
+
pages: _ctx.pages,
|
|
16974
|
+
subtitle: `(${_ctx.questionCount})`,
|
|
16975
|
+
onFirst: _ctx.first,
|
|
16976
|
+
onPrev: _ctx.prev,
|
|
16977
|
+
onNext: _ctx.next,
|
|
16978
|
+
onLast: _ctx.last,
|
|
16979
|
+
onSetPage: _cache[0] || (_cache[0] = (n) => _ctx.setPage(n))
|
|
16980
|
+
}, null, 8, ["page", "pages", "subtitle", "onFirst", "onPrev", "onNext", "onLast"]),
|
|
16981
|
+
createVNode(_component_v_list, null, {
|
|
16982
|
+
default: withCtx(() => [
|
|
16983
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.cards, (c) => {
|
|
16984
|
+
return openBlock(), createElementBlock(Fragment, {
|
|
16985
|
+
key: c.id
|
|
16986
|
+
}, [
|
|
16987
|
+
createVNode(_component_v_list_item, {
|
|
16988
|
+
class: normalizeClass({
|
|
16989
|
+
"bg-blue-grey-lighten-5": c.isOpen,
|
|
16990
|
+
"elevation-4": c.isOpen
|
|
16991
|
+
}),
|
|
16992
|
+
density: "compact",
|
|
16993
|
+
"data-cy": "course-card"
|
|
16994
|
+
}, {
|
|
16995
|
+
prepend: withCtx(() => [
|
|
16996
|
+
createElementVNode("div", null, [
|
|
16997
|
+
createVNode(_component_v_list_item_title, {
|
|
16998
|
+
class: normalizeClass([{ "text-blue-grey-darken-1": c.isOpen }, "font-weight-medium"])
|
|
16999
|
+
}, {
|
|
17000
|
+
default: withCtx(() => [
|
|
17001
|
+
createTextVNode(toDisplayString(_ctx.cardPreview[c.id]), 1)
|
|
17002
|
+
]),
|
|
17003
|
+
_: 2
|
|
17004
|
+
}, 1032, ["class"]),
|
|
17005
|
+
createVNode(_component_v_list_item_subtitle, null, {
|
|
17006
|
+
default: withCtx(() => [
|
|
17007
|
+
createTextVNode(toDisplayString(c.id.split("-").length === 3 ? c.id.split("-")[2] : ""), 1)
|
|
17008
|
+
]),
|
|
17009
|
+
_: 2
|
|
17010
|
+
}, 1024)
|
|
17011
|
+
])
|
|
17012
|
+
]),
|
|
17013
|
+
append: withCtx(() => [
|
|
17014
|
+
_ctx.editMode === "full" ? (openBlock(), createBlock(_component_v_speed_dial, {
|
|
17015
|
+
key: 0,
|
|
17016
|
+
modelValue: c.isOpen,
|
|
17017
|
+
"onUpdate:modelValue": ($event) => c.isOpen = $event,
|
|
17018
|
+
location: "left center",
|
|
17019
|
+
transition: "slide-x-transition",
|
|
17020
|
+
style: { "display": "flex", "flex-direction": "row-reverse" },
|
|
17021
|
+
persistent: ""
|
|
17022
|
+
}, {
|
|
17023
|
+
activator: withCtx(({ props }) => [
|
|
17024
|
+
createVNode(_component_v_btn, mergeProps({ ref_for: true }, props, {
|
|
17025
|
+
icon: c.isOpen ? "mdi-close" : "mdi-plus",
|
|
17026
|
+
size: "small",
|
|
17027
|
+
variant: "text",
|
|
17028
|
+
onClick: ($event) => _ctx.clearSelections(c.id)
|
|
17029
|
+
}), null, 16, ["icon", "onClick"])
|
|
17030
|
+
]),
|
|
17031
|
+
default: withCtx(() => [
|
|
17032
|
+
createVNode(_component_v_btn, {
|
|
17033
|
+
key: "tags",
|
|
17034
|
+
icon: "",
|
|
17035
|
+
size: "small",
|
|
17036
|
+
variant: _ctx.internalEditMode !== "tags" ? "outlined" : "elevated",
|
|
17037
|
+
color: _ctx.internalEditMode === "tags" ? "teal" : "teal-darken-3",
|
|
17038
|
+
onClick: _cache[1] || (_cache[1] = withModifiers(($event) => _ctx.internalEditMode = "tags", ["stop"]))
|
|
17039
|
+
}, {
|
|
17040
|
+
default: withCtx(() => [
|
|
17041
|
+
createVNode(_component_v_icon, null, {
|
|
17042
|
+
default: withCtx(() => _cache[4] || (_cache[4] = [
|
|
17043
|
+
createTextVNode("mdi-bookmark")
|
|
17044
|
+
])),
|
|
17045
|
+
_: 1
|
|
17046
|
+
})
|
|
17047
|
+
]),
|
|
17048
|
+
_: 1
|
|
17049
|
+
}, 8, ["variant", "color"]),
|
|
17050
|
+
createVNode(_component_v_btn, {
|
|
17051
|
+
key: "flag",
|
|
17052
|
+
icon: "",
|
|
17053
|
+
size: "small",
|
|
17054
|
+
variant: _ctx.internalEditMode !== "flag" ? "outlined" : "elevated",
|
|
17055
|
+
color: _ctx.internalEditMode === "flag" ? "error" : "error-darken-3",
|
|
17056
|
+
onClick: _cache[2] || (_cache[2] = withModifiers(($event) => _ctx.internalEditMode = "flag", ["stop"]))
|
|
17057
|
+
}, {
|
|
17058
|
+
default: withCtx(() => [
|
|
17059
|
+
createVNode(_component_v_icon, null, {
|
|
17060
|
+
default: withCtx(() => _cache[5] || (_cache[5] = [
|
|
17061
|
+
createTextVNode("mdi-flag")
|
|
17062
|
+
])),
|
|
17063
|
+
_: 1
|
|
17064
|
+
})
|
|
17065
|
+
]),
|
|
17066
|
+
_: 1
|
|
17067
|
+
}, 8, ["variant", "color"])
|
|
17068
|
+
]),
|
|
17069
|
+
_: 2
|
|
17070
|
+
}, 1032, ["modelValue", "onUpdate:modelValue"])) : createCommentVNode("", true)
|
|
17071
|
+
]),
|
|
17072
|
+
_: 2
|
|
17073
|
+
}, 1032, ["class"]),
|
|
17074
|
+
c.isOpen ? (openBlock(), createElementBlock("div", _hoisted_3$1, [
|
|
17075
|
+
createVNode(_component_card_loader, {
|
|
17076
|
+
qualified_id: c.id,
|
|
17077
|
+
"view-lookup": _ctx.viewLookup,
|
|
17078
|
+
class: "elevation-1"
|
|
17079
|
+
}, null, 8, ["qualified_id", "view-lookup"]),
|
|
17080
|
+
withDirectives(createVNode(_component_tags_input, {
|
|
17081
|
+
"course-i-d": _ctx.courseId,
|
|
17082
|
+
"card-i-d": c.id.split("-")[1],
|
|
17083
|
+
class: "mt-4"
|
|
17084
|
+
}, null, 8, ["course-i-d", "card-i-d"]), [
|
|
17085
|
+
[vShow, _ctx.internalEditMode === "tags"]
|
|
17086
|
+
]),
|
|
17087
|
+
withDirectives(createElementVNode("div", _hoisted_4$1, [
|
|
17088
|
+
createVNode(_component_v_btn, {
|
|
17089
|
+
color: "error",
|
|
17090
|
+
variant: "outlined",
|
|
17091
|
+
onClick: ($event) => c.delBtn = true
|
|
17092
|
+
}, {
|
|
17093
|
+
default: withCtx(() => _cache[6] || (_cache[6] = [
|
|
17094
|
+
createTextVNode(" Delete this card ")
|
|
17095
|
+
])),
|
|
17096
|
+
_: 2
|
|
17097
|
+
}, 1032, ["onClick"]),
|
|
17098
|
+
c.delBtn ? (openBlock(), createElementBlock("span", _hoisted_5$1, [
|
|
17099
|
+
_cache[8] || (_cache[8] = createElementVNode("span", { class: "mr-2" }, "Are you sure?", -1)),
|
|
17100
|
+
createVNode(_component_v_btn, {
|
|
17101
|
+
color: "error",
|
|
17102
|
+
variant: "elevated",
|
|
17103
|
+
onClick: ($event) => _ctx.deleteCard(c.id)
|
|
17104
|
+
}, {
|
|
17105
|
+
default: withCtx(() => _cache[7] || (_cache[7] = [
|
|
17106
|
+
createTextVNode(" Confirm ")
|
|
17107
|
+
])),
|
|
17108
|
+
_: 2
|
|
17109
|
+
}, 1032, ["onClick"])
|
|
17110
|
+
])) : createCommentVNode("", true)
|
|
17111
|
+
], 512), [
|
|
17112
|
+
[vShow, _ctx.internalEditMode === "flag"]
|
|
17113
|
+
])
|
|
17114
|
+
])) : createCommentVNode("", true)
|
|
17115
|
+
], 64);
|
|
17116
|
+
}), 128))
|
|
17117
|
+
]),
|
|
17118
|
+
_: 1
|
|
17119
|
+
}),
|
|
17120
|
+
createVNode(_component_paginating_toolbar, {
|
|
17121
|
+
class: "elevation-0",
|
|
17122
|
+
page: _ctx.page,
|
|
17123
|
+
pages: _ctx.pages,
|
|
17124
|
+
onFirst: _ctx.first,
|
|
17125
|
+
onPrev: _ctx.prev,
|
|
17126
|
+
onNext: _ctx.next,
|
|
17127
|
+
onLast: _ctx.last,
|
|
17128
|
+
onSetPage: _cache[3] || (_cache[3] = (n) => _ctx.setPage(n))
|
|
17129
|
+
}, null, 8, ["page", "pages", "onFirst", "onPrev", "onNext", "onLast"])
|
|
17130
|
+
]))
|
|
17131
|
+
]),
|
|
17132
|
+
_: 1
|
|
17133
|
+
});
|
|
17134
|
+
}
|
|
17135
|
+
const CourseCardBrowser = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2], ["__scopeId", "data-v-0beef6a4"]]);
|
|
17136
|
+
const _sfc_main$1 = defineComponent({
|
|
17137
|
+
name: "CourseInformation",
|
|
17138
|
+
components: {
|
|
17139
|
+
// MidiConfig, // Removed to break circular dependency
|
|
17140
|
+
CourseCardBrowser
|
|
17141
|
+
},
|
|
17142
|
+
props: {
|
|
17143
|
+
courseId: {
|
|
17144
|
+
type: String,
|
|
17145
|
+
required: true
|
|
17146
|
+
},
|
|
17147
|
+
viewLookupFunction: {
|
|
17148
|
+
type: Function,
|
|
17149
|
+
required: false,
|
|
17150
|
+
default: (x) => {
|
|
17151
|
+
console.warn("No viewLookupFunction provided to CourseInformation");
|
|
17152
|
+
return null;
|
|
17153
|
+
}
|
|
17154
|
+
},
|
|
17155
|
+
editMode: {
|
|
17156
|
+
type: String,
|
|
17157
|
+
required: false,
|
|
17158
|
+
default: "full"
|
|
17159
|
+
}
|
|
17160
|
+
},
|
|
17161
|
+
data() {
|
|
17162
|
+
return {
|
|
17163
|
+
courseDB: null,
|
|
17164
|
+
nameRules: [
|
|
17165
|
+
(value) => {
|
|
17166
|
+
const max2 = 30;
|
|
17167
|
+
return value.length > max2 ? `Course name must be ${max2} characters or less` : true;
|
|
17168
|
+
}
|
|
17169
|
+
],
|
|
17170
|
+
updatePending: true,
|
|
17171
|
+
courseConfig: {},
|
|
17172
|
+
userIsRegistered: false,
|
|
17173
|
+
tags: [],
|
|
17174
|
+
user: null
|
|
17175
|
+
};
|
|
17176
|
+
},
|
|
17177
|
+
computed: {
|
|
17178
|
+
// isPianoCourse removed - piano-specific logic should be in wrapper component
|
|
17179
|
+
},
|
|
17180
|
+
async created() {
|
|
17181
|
+
this.courseDB = getDataLayer().getCourseDB(this.courseId);
|
|
17182
|
+
this.user = await getCurrentUser();
|
|
17183
|
+
const userCourses = await this.user.getCourseRegistrationsDoc();
|
|
17184
|
+
this.userIsRegistered = userCourses.courses.filter((c) => {
|
|
17185
|
+
return c.courseID === this.courseId && (c.status === "active" || c.status === void 0);
|
|
17186
|
+
}).length === 1;
|
|
17187
|
+
this.courseConfig = await this.courseDB.getCourseConfig();
|
|
17188
|
+
this.tags = (await this.courseDB.getCourseTagStubs()).rows.map((r2) => r2.doc);
|
|
17189
|
+
this.updatePending = false;
|
|
17190
|
+
},
|
|
17191
|
+
methods: {
|
|
17192
|
+
async register() {
|
|
17193
|
+
log(`Registering for ${this.courseId}`);
|
|
17194
|
+
const res = await this.user.registerForCourse(this.courseId);
|
|
17195
|
+
if (res.ok) {
|
|
17196
|
+
this.userIsRegistered = true;
|
|
17197
|
+
}
|
|
17198
|
+
},
|
|
17199
|
+
async drop() {
|
|
17200
|
+
log(`Dropping course ${this.courseId}`);
|
|
17201
|
+
const res = await this.user.dropCourse(this.courseId);
|
|
17202
|
+
if (res.ok) {
|
|
17203
|
+
this.userIsRegistered = false;
|
|
17204
|
+
}
|
|
17205
|
+
}
|
|
17206
|
+
}
|
|
17207
|
+
});
|
|
17208
|
+
const _hoisted_1$1 = { key: 0 };
|
|
17209
|
+
const _hoisted_2 = { class: "text-h4 mb-2" };
|
|
17210
|
+
const _hoisted_3 = { class: "text-body-2" };
|
|
17211
|
+
const _hoisted_4 = { key: 0 };
|
|
17212
|
+
const _hoisted_5 = { key: 1 };
|
|
17213
|
+
function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) {
|
|
17214
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
17215
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
17216
|
+
const _component_v_toolbar_title = resolveComponent("v-toolbar-title");
|
|
17217
|
+
const _component_v_toolbar_items = resolveComponent("v-toolbar-items");
|
|
17218
|
+
const _component_v_toolbar = resolveComponent("v-toolbar");
|
|
17219
|
+
const _component_v_chip = resolveComponent("v-chip");
|
|
17220
|
+
const _component_v_card_text = resolveComponent("v-card-text");
|
|
17221
|
+
const _component_v_card = resolveComponent("v-card");
|
|
17222
|
+
const _component_course_card_browser = resolveComponent("course-card-browser");
|
|
17223
|
+
return !_ctx.updatePending ? (openBlock(), createElementBlock("div", _hoisted_1$1, [
|
|
17224
|
+
renderSlot(_ctx.$slots, "header", {
|
|
17225
|
+
courseConfig: _ctx.courseConfig,
|
|
17226
|
+
courseId: _ctx.courseId
|
|
17227
|
+
}, () => [
|
|
17228
|
+
createElementVNode("h1", _hoisted_2, toDisplayString(_ctx.courseConfig.name), 1)
|
|
17229
|
+
], true),
|
|
17230
|
+
createElementVNode("p", _hoisted_3, toDisplayString(_ctx.courseConfig.description), 1),
|
|
17231
|
+
renderSlot(_ctx.$slots, "actions", {
|
|
17232
|
+
userIsRegistered: _ctx.userIsRegistered,
|
|
17233
|
+
courseId: _ctx.courseId,
|
|
17234
|
+
editMode: _ctx.editMode,
|
|
17235
|
+
register: _ctx.register,
|
|
17236
|
+
drop: _ctx.drop
|
|
17237
|
+
}, () => [
|
|
17238
|
+
createVNode(Transition, {
|
|
17239
|
+
name: "component-fade",
|
|
17240
|
+
mode: "out-in"
|
|
17241
|
+
}, {
|
|
17242
|
+
default: withCtx(() => [
|
|
17243
|
+
_ctx.userIsRegistered ? (openBlock(), createElementBlock("div", _hoisted_4, [
|
|
17244
|
+
createVNode(_component_v_btn, {
|
|
17245
|
+
color: "success",
|
|
17246
|
+
class: "me-2"
|
|
17247
|
+
}, {
|
|
17248
|
+
default: withCtx(() => _cache[0] || (_cache[0] = [
|
|
17249
|
+
createTextVNode("Start a study session")
|
|
17250
|
+
])),
|
|
17251
|
+
_: 1
|
|
17252
|
+
}),
|
|
17253
|
+
_ctx.editMode === "full" ? (openBlock(), createBlock(_component_v_btn, {
|
|
17254
|
+
key: 0,
|
|
17255
|
+
"data-cy": "add-content-btn",
|
|
17256
|
+
color: "indigo-lighten-1",
|
|
17257
|
+
class: "me-2"
|
|
17258
|
+
}, {
|
|
17259
|
+
default: withCtx(() => [
|
|
17260
|
+
createVNode(_component_v_icon, { start: "" }, {
|
|
17261
|
+
default: withCtx(() => _cache[1] || (_cache[1] = [
|
|
17262
|
+
createTextVNode("mdi-plus")
|
|
17263
|
+
])),
|
|
17264
|
+
_: 1
|
|
17265
|
+
}),
|
|
17266
|
+
_cache[2] || (_cache[2] = createTextVNode(" Add content "))
|
|
17267
|
+
]),
|
|
17268
|
+
_: 1
|
|
17269
|
+
})) : createCommentVNode("", true),
|
|
17270
|
+
_ctx.editMode === "full" ? (openBlock(), createBlock(_component_v_btn, {
|
|
17271
|
+
key: 1,
|
|
17272
|
+
color: "green-darken-2",
|
|
17273
|
+
title: "Rank course content for difficulty",
|
|
17274
|
+
class: "me-2"
|
|
17275
|
+
}, {
|
|
17276
|
+
default: withCtx(() => [
|
|
17277
|
+
createVNode(_component_v_icon, { start: "" }, {
|
|
17278
|
+
default: withCtx(() => _cache[3] || (_cache[3] = [
|
|
17279
|
+
createTextVNode("mdi-format-list-numbered")
|
|
17280
|
+
])),
|
|
17281
|
+
_: 1
|
|
17282
|
+
}),
|
|
17283
|
+
_cache[4] || (_cache[4] = createTextVNode(" Arrange "))
|
|
17284
|
+
]),
|
|
17285
|
+
_: 1
|
|
17286
|
+
})) : createCommentVNode("", true),
|
|
17287
|
+
_ctx.editMode === "full" ? (openBlock(), createBlock(_component_v_btn, {
|
|
17288
|
+
key: 2,
|
|
17289
|
+
color: "error",
|
|
17290
|
+
size: "small",
|
|
17291
|
+
variant: "outlined",
|
|
17292
|
+
onClick: _ctx.drop
|
|
17293
|
+
}, {
|
|
17294
|
+
default: withCtx(() => _cache[5] || (_cache[5] = [
|
|
17295
|
+
createTextVNode(" Drop this course ")
|
|
17296
|
+
])),
|
|
17297
|
+
_: 1
|
|
17298
|
+
}, 8, ["onClick"])) : createCommentVNode("", true)
|
|
17299
|
+
])) : (openBlock(), createElementBlock("div", _hoisted_5, [
|
|
17300
|
+
createVNode(_component_v_btn, {
|
|
17301
|
+
"data-cy": "register-btn",
|
|
17302
|
+
color: "primary",
|
|
17303
|
+
class: "me-2",
|
|
17304
|
+
onClick: _ctx.register
|
|
17305
|
+
}, {
|
|
17306
|
+
default: withCtx(() => _cache[6] || (_cache[6] = [
|
|
17307
|
+
createTextVNode("Register")
|
|
17308
|
+
])),
|
|
17309
|
+
_: 1
|
|
17310
|
+
}, 8, ["onClick"]),
|
|
17311
|
+
createVNode(_component_v_btn, {
|
|
17312
|
+
variant: "outlined",
|
|
17313
|
+
color: "primary",
|
|
17314
|
+
class: "me-2"
|
|
17315
|
+
}, {
|
|
17316
|
+
default: withCtx(() => _cache[7] || (_cache[7] = [
|
|
17317
|
+
createTextVNode("Start a trial study session")
|
|
17318
|
+
])),
|
|
17319
|
+
_: 1
|
|
17320
|
+
})
|
|
17321
|
+
]))
|
|
17322
|
+
]),
|
|
17323
|
+
_: 1
|
|
17324
|
+
})
|
|
17325
|
+
], true),
|
|
17326
|
+
renderSlot(_ctx.$slots, "additional-content", {}, void 0, true),
|
|
17327
|
+
createVNode(_component_v_card, { class: "my-2" }, {
|
|
17328
|
+
default: withCtx(() => [
|
|
17329
|
+
createVNode(_component_v_toolbar, { density: "compact" }, {
|
|
17330
|
+
default: withCtx(() => [
|
|
17331
|
+
createVNode(_component_v_toolbar_title, null, {
|
|
17332
|
+
default: withCtx(() => _cache[8] || (_cache[8] = [
|
|
17333
|
+
createTextVNode("Tags")
|
|
17334
|
+
])),
|
|
17335
|
+
_: 1
|
|
17336
|
+
}),
|
|
17337
|
+
createVNode(_component_v_toolbar_items, null, {
|
|
17338
|
+
default: withCtx(() => [
|
|
17339
|
+
createVNode(_component_v_btn, { variant: "text" }, {
|
|
17340
|
+
default: withCtx(() => [
|
|
17341
|
+
createTextVNode("(" + toDisplayString(_ctx.tags.length) + ")", 1)
|
|
17342
|
+
]),
|
|
17343
|
+
_: 1
|
|
17344
|
+
})
|
|
17345
|
+
]),
|
|
17346
|
+
_: 1
|
|
17347
|
+
})
|
|
17348
|
+
]),
|
|
17349
|
+
_: 1
|
|
17350
|
+
}),
|
|
17351
|
+
createVNode(_component_v_card_text, null, {
|
|
17352
|
+
default: withCtx(() => [
|
|
17353
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.tags, (tag2, i) => {
|
|
17354
|
+
return openBlock(), createElementBlock("span", { key: i }, [
|
|
17355
|
+
renderSlot(_ctx.$slots, "tag-link", {
|
|
17356
|
+
tag: tag2,
|
|
17357
|
+
courseId: _ctx.courseId
|
|
17358
|
+
}, () => [
|
|
17359
|
+
createVNode(_component_v_chip, {
|
|
17360
|
+
variant: "tonal",
|
|
17361
|
+
class: "me-2 mb-2"
|
|
17362
|
+
}, {
|
|
17363
|
+
default: withCtx(() => [
|
|
17364
|
+
createTextVNode(toDisplayString(tag2.name), 1)
|
|
17365
|
+
]),
|
|
17366
|
+
_: 2
|
|
17367
|
+
}, 1024)
|
|
17368
|
+
], true)
|
|
17369
|
+
]);
|
|
17370
|
+
}), 128))
|
|
17371
|
+
]),
|
|
17372
|
+
_: 3
|
|
17373
|
+
})
|
|
17374
|
+
]),
|
|
17375
|
+
_: 3
|
|
17376
|
+
}),
|
|
17377
|
+
createVNode(_component_course_card_browser, {
|
|
17378
|
+
class: "my-3",
|
|
17379
|
+
"course-id": _ctx.courseId,
|
|
17380
|
+
"view-lookup-function": _ctx.viewLookupFunction,
|
|
17381
|
+
"edit-mode": _ctx.editMode
|
|
17382
|
+
}, null, 8, ["course-id", "view-lookup-function", "edit-mode"])
|
|
17383
|
+
])) : createCommentVNode("", true);
|
|
17384
|
+
}
|
|
17385
|
+
const CourseInformation = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1], ["__scopeId", "data-v-799f691d"]]);
|
|
17386
|
+
const _sfc_main = defineComponent({
|
|
17387
|
+
name: "CardBrowser",
|
|
17388
|
+
components: {
|
|
17389
|
+
CardViewer
|
|
17390
|
+
},
|
|
17391
|
+
props: {
|
|
17392
|
+
views: {
|
|
17393
|
+
type: Array,
|
|
17394
|
+
required: true
|
|
17395
|
+
},
|
|
17396
|
+
data: {
|
|
17397
|
+
type: Array,
|
|
17398
|
+
required: true
|
|
17399
|
+
},
|
|
17400
|
+
suppressSpinner: {
|
|
17401
|
+
type: Boolean,
|
|
17402
|
+
default: false
|
|
17403
|
+
}
|
|
17404
|
+
},
|
|
17405
|
+
data() {
|
|
17406
|
+
return {
|
|
17407
|
+
viewIndex: 0,
|
|
17408
|
+
previewMode: useCardPreviewModeStore()
|
|
17409
|
+
};
|
|
17410
|
+
},
|
|
17411
|
+
computed: {
|
|
17412
|
+
spinner() {
|
|
17413
|
+
return this.views.length > 1;
|
|
17414
|
+
}
|
|
17415
|
+
},
|
|
17416
|
+
created() {
|
|
17417
|
+
console.log(`[CardBrowser] Card browser created. Cards now in 'prewviewMode'`);
|
|
17418
|
+
this.previewMode.setPreviewMode(true);
|
|
17419
|
+
},
|
|
17420
|
+
unmounted() {
|
|
17421
|
+
console.log(`[CardBrowser] Card browser unmounted. Cards no longer in 'prewviewMode'`);
|
|
17422
|
+
this.previewMode.setPreviewMode(false);
|
|
17423
|
+
},
|
|
17424
|
+
methods: {
|
|
17425
|
+
incrementView() {
|
|
17426
|
+
this.viewIndex++;
|
|
17427
|
+
this.viewIndex = (this.viewIndex + this.views.length) % this.views.length;
|
|
17428
|
+
},
|
|
17429
|
+
decrementView() {
|
|
17430
|
+
this.viewIndex--;
|
|
17431
|
+
this.viewIndex = (this.viewIndex + this.views.length) % this.views.length;
|
|
17432
|
+
}
|
|
17433
|
+
}
|
|
17434
|
+
});
|
|
17435
|
+
const _hoisted_1 = {
|
|
17436
|
+
key: 0,
|
|
17437
|
+
class: "text-subtitle-1 pa-2"
|
|
17438
|
+
};
|
|
17439
|
+
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
17440
|
+
const _component_CardViewer = resolveComponent("CardViewer");
|
|
17441
|
+
const _component_v_icon = resolveComponent("v-icon");
|
|
17442
|
+
const _component_v_btn = resolveComponent("v-btn");
|
|
17443
|
+
const _component_v_row = resolveComponent("v-row");
|
|
17444
|
+
return openBlock(), createBlock(_component_v_row, {
|
|
17445
|
+
column: "",
|
|
17446
|
+
align: "center",
|
|
17447
|
+
justify: "center"
|
|
17448
|
+
}, {
|
|
17449
|
+
default: withCtx(() => [
|
|
17450
|
+
createVNode(_component_CardViewer, {
|
|
17451
|
+
view: _ctx.views[_ctx.viewIndex],
|
|
17452
|
+
data: _ctx.data,
|
|
17453
|
+
course_id: "[browsing]",
|
|
17454
|
+
card_id: "[browsing]"
|
|
17455
|
+
}, null, 8, ["view", "data"]),
|
|
17456
|
+
_cache[2] || (_cache[2] = createElementVNode("br", null, null, -1)),
|
|
17457
|
+
_cache[3] || (_cache[3] = createElementVNode("br", null, null, -1)),
|
|
17458
|
+
!_ctx.suppressSpinner ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
17459
|
+
_ctx.spinner ? (openBlock(), createBlock(_component_v_btn, {
|
|
17460
|
+
key: 0,
|
|
17461
|
+
icon: "",
|
|
17462
|
+
variant: "outlined",
|
|
17463
|
+
color: "primary",
|
|
17464
|
+
onClick: _ctx.decrementView
|
|
17465
|
+
}, {
|
|
17466
|
+
default: withCtx(() => [
|
|
17467
|
+
createVNode(_component_v_icon, null, {
|
|
17468
|
+
default: withCtx(() => _cache[0] || (_cache[0] = [
|
|
17469
|
+
createTextVNode("mdi-chevron-left")
|
|
17470
|
+
])),
|
|
17471
|
+
_: 1
|
|
17472
|
+
})
|
|
17473
|
+
]),
|
|
17474
|
+
_: 1
|
|
17475
|
+
}, 8, ["onClick"])) : createCommentVNode("", true),
|
|
17476
|
+
createTextVNode(" " + toDisplayString(_ctx.views[_ctx.viewIndex].name) + " ", 1),
|
|
17477
|
+
_ctx.spinner ? (openBlock(), createBlock(_component_v_btn, {
|
|
17478
|
+
key: 1,
|
|
17479
|
+
icon: "",
|
|
17480
|
+
variant: "outlined",
|
|
17481
|
+
color: "primary",
|
|
17482
|
+
onClick: _ctx.incrementView
|
|
17483
|
+
}, {
|
|
17484
|
+
default: withCtx(() => [
|
|
17485
|
+
createVNode(_component_v_icon, null, {
|
|
17486
|
+
default: withCtx(() => _cache[1] || (_cache[1] = [
|
|
17487
|
+
createTextVNode("mdi-chevron-right")
|
|
17488
|
+
])),
|
|
17489
|
+
_: 1
|
|
17490
|
+
})
|
|
17491
|
+
]),
|
|
17492
|
+
_: 1
|
|
17493
|
+
}, 8, ["onClick"])) : createCommentVNode("", true)
|
|
17494
|
+
])) : createCommentVNode("", true)
|
|
17495
|
+
]),
|
|
17496
|
+
_: 1
|
|
17497
|
+
});
|
|
17498
|
+
}
|
|
17499
|
+
const CardBrowser = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
|
|
16328
17500
|
export {
|
|
16329
17501
|
AudioAutoPlayer,
|
|
17502
|
+
CardBrowser,
|
|
16330
17503
|
CardLoader,
|
|
16331
17504
|
CardViewer,
|
|
16332
|
-
_sfc_main$
|
|
17505
|
+
_sfc_main$a as CodeBlockRenderer,
|
|
17506
|
+
CourseCardBrowser,
|
|
17507
|
+
CourseInformation,
|
|
16333
17508
|
Displayable,
|
|
16334
17509
|
FillInInput,
|
|
16335
17510
|
HeatMap,
|
|
@@ -16346,6 +17521,7 @@ export {
|
|
|
16346
17521
|
StudySession,
|
|
16347
17522
|
StudySessionTimer,
|
|
16348
17523
|
TrueFalse as TFSelect,
|
|
17524
|
+
TagsInput,
|
|
16349
17525
|
UserChip,
|
|
16350
17526
|
UserInputNumber,
|
|
16351
17527
|
UserInputString,
|