@vue-skuilder/platform-ui 0.1.5 → 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/index.html CHANGED
@@ -8,8 +8,8 @@
8
8
  <meta name="viewport" content="width=device-width,initial-scale=1.0" />
9
9
  <link rel="shortcut icon" href="/favicon.ico" />
10
10
  <title>eduQuilt</title>
11
- <script type="module" crossorigin src="/assets/index-WMkqlHec.js"></script>
12
- <link rel="stylesheet" crossorigin href="/assets/index-BNUK840O.css">
11
+ <script type="module" crossorigin src="/assets/index-D6gUuyAZ.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index-C5DT5vWX.css">
13
13
  <link rel="manifest" href="/manifest.webmanifest"></head>
14
14
 
15
15
  <body>
package/dist/sw.js CHANGED
@@ -1,2 +1,2 @@
1
- if(!self.define){let o,s={};const e=(e,i)=>(e=new URL(e+".js",i).href,s[e]||new Promise((s=>{if("document"in self){const o=document.createElement("script");o.src=e,o.onload=s,document.head.appendChild(o)}else o=e,importScripts(e),s()})).then((()=>{let o=s[e];if(!o)throw new Error(`Module ${e} didn’t register its module`);return o})));self.define=(i,l)=>{const n=o||("document"in self?document.currentScript.src:"")||location.href;if(s[n])return;let r={};const t=o=>e(o,n),u={module:{uri:n},exports:r,require:t};s[n]=Promise.all(i.map((o=>u[o]||t(o)))).then((o=>(l(...o),r)))}}define(["./workbox-1be04862"],(function(o){"use strict";self.skipWaiting(),o.clientsClaim(),o.precacheAndRoute([{url:"assets/index-BNUK840O.css",revision:null},{url:"assets/index-WMkqlHec.js",revision:null},{url:"assets/materialdesignicons-webfont-Dp5v-WZN.woff2",revision:null},{url:"assets/Roboto-Black-VhoA2qKx.woff2",revision:null},{url:"assets/Roboto-BlackItalic-D4yie1YO.woff2",revision:null},{url:"assets/Roboto-Bold-hN3duQhD.woff2",revision:null},{url:"assets/Roboto-BoldItalic-BWDm51uc.woff2",revision:null},{url:"assets/Roboto-Light-DHTugVNA.woff2",revision:null},{url:"assets/Roboto-LightItalic-JQyp2Y3P.woff2",revision:null},{url:"assets/Roboto-Medium-ByKogCTi.woff2",revision:null},{url:"assets/Roboto-MediumItalic-i1eR0KbF.woff2",revision:null},{url:"assets/Roboto-Regular-C6rbFxYz.woff2",revision:null},{url:"assets/Roboto-RegularItalic-CvPUdkvM.woff2",revision:null},{url:"assets/Roboto-Thin-NicBC1pN.woff2",revision:null},{url:"assets/Roboto-ThinItalic-CKlCjrO_.woff2",revision:null},{url:"assets/workbox-window.prod.es5-p40uij6f.js",revision:null},{url:"favicon.ico",revision:"b71387b4508120b59615e43d5e103706"},{url:"img/icons/safari-pinned-tab.svg",revision:"f22d501a35a87d9f21701cb031f6ea17"},{url:"index.html",revision:"d246f75183ccd7b5956caeecb7fd11bf"},{url:"manifest.json",revision:"14a155103e25199244cdda503219c3e1"},{url:"robots.txt",revision:"b6216d61c03e6ce0c9aea6ca7808f7ca"},{url:"manifest.webmanifest",revision:"0ad80257ac95729a8c88588d23a396c1"}],{}),o.cleanupOutdatedCaches(),o.registerRoute(new o.NavigationRoute(o.createHandlerBoundToURL("/index.html"),{allowlist:[/^(?!\/(couch|express)).*$/]}))}));
1
+ if(!self.define){let o,s={};const e=(e,i)=>(e=new URL(e+".js",i).href,s[e]||new Promise((s=>{if("document"in self){const o=document.createElement("script");o.src=e,o.onload=s,document.head.appendChild(o)}else o=e,importScripts(e),s()})).then((()=>{let o=s[e];if(!o)throw new Error(`Module ${e} didn’t register its module`);return o})));self.define=(i,l)=>{const n=o||("document"in self?document.currentScript.src:"")||location.href;if(s[n])return;let r={};const t=o=>e(o,n),u={module:{uri:n},exports:r,require:t};s[n]=Promise.all(i.map((o=>u[o]||t(o)))).then((o=>(l(...o),r)))}}define(["./workbox-1be04862"],(function(o){"use strict";self.skipWaiting(),o.clientsClaim(),o.precacheAndRoute([{url:"assets/index-C5DT5vWX.css",revision:null},{url:"assets/index-D6gUuyAZ.js",revision:null},{url:"assets/materialdesignicons-webfont-Dp5v-WZN.woff2",revision:null},{url:"assets/Roboto-Black-VhoA2qKx.woff2",revision:null},{url:"assets/Roboto-BlackItalic-D4yie1YO.woff2",revision:null},{url:"assets/Roboto-Bold-hN3duQhD.woff2",revision:null},{url:"assets/Roboto-BoldItalic-BWDm51uc.woff2",revision:null},{url:"assets/Roboto-Light-DHTugVNA.woff2",revision:null},{url:"assets/Roboto-LightItalic-JQyp2Y3P.woff2",revision:null},{url:"assets/Roboto-Medium-ByKogCTi.woff2",revision:null},{url:"assets/Roboto-MediumItalic-i1eR0KbF.woff2",revision:null},{url:"assets/Roboto-Regular-C6rbFxYz.woff2",revision:null},{url:"assets/Roboto-RegularItalic-CvPUdkvM.woff2",revision:null},{url:"assets/Roboto-Thin-NicBC1pN.woff2",revision:null},{url:"assets/Roboto-ThinItalic-CKlCjrO_.woff2",revision:null},{url:"assets/workbox-window.prod.es5-p40uij6f.js",revision:null},{url:"favicon.ico",revision:"b71387b4508120b59615e43d5e103706"},{url:"img/icons/safari-pinned-tab.svg",revision:"f22d501a35a87d9f21701cb031f6ea17"},{url:"index.html",revision:"966239aa2fe2f5a413dfbe31306d249f"},{url:"manifest.json",revision:"14a155103e25199244cdda503219c3e1"},{url:"robots.txt",revision:"b6216d61c03e6ce0c9aea6ca7808f7ca"},{url:"manifest.webmanifest",revision:"0ad80257ac95729a8c88588d23a396c1"}],{}),o.cleanupOutdatedCaches(),o.registerRoute(new o.NavigationRoute(o.createHandlerBoundToURL("/index.html"),{allowlist:[/^(?!\/(couch|express)).*$/]}))}));
2
2
  //# sourceMappingURL=sw.js.map
package/dist/sw.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sw.js","sources":["../../../../../../../tmp/94f77804a2d8c92b1817825a58ac1e4f/sw.js"],"sourcesContent":["import {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-routing/registerRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"assets/index-BNUK840O.css\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-WMkqlHec.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/materialdesignicons-webfont-Dp5v-WZN.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Black-VhoA2qKx.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-BlackItalic-D4yie1YO.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Bold-hN3duQhD.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-BoldItalic-BWDm51uc.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Light-DHTugVNA.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-LightItalic-JQyp2Y3P.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Medium-ByKogCTi.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-MediumItalic-i1eR0KbF.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Regular-C6rbFxYz.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-RegularItalic-CvPUdkvM.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Thin-NicBC1pN.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-ThinItalic-CKlCjrO_.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/workbox-window.prod.es5-p40uij6f.js\",\n \"revision\": null\n },\n {\n \"url\": \"favicon.ico\",\n \"revision\": \"b71387b4508120b59615e43d5e103706\"\n },\n {\n \"url\": \"img/icons/safari-pinned-tab.svg\",\n \"revision\": \"f22d501a35a87d9f21701cb031f6ea17\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"d246f75183ccd7b5956caeecb7fd11bf\"\n },\n {\n \"url\": \"manifest.json\",\n \"revision\": \"14a155103e25199244cdda503219c3e1\"\n },\n {\n \"url\": \"robots.txt\",\n \"revision\": \"b6216d61c03e6ce0c9aea6ca7808f7ca\"\n },\n {\n \"url\": \"manifest.webmanifest\",\n \"revision\": \"0ad80257ac95729a8c88588d23a396c1\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\"), {\n allowlist: [/^(?!\\/(couch|express)).*$/],\n \n}));\n\n\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches","workbox","registerRoute","workbox_routing_NavigationRoute","NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,4BACPC,SAAY,MAEd,CACED,IAAO,2BACPC,SAAY,MAEd,CACED,IAAO,oDACPC,SAAY,MAEd,CACED,IAAO,qCACPC,SAAY,MAEd,CACED,IAAO,2CACPC,SAAY,MAEd,CACED,IAAO,oCACPC,SAAY,MAEd,CACED,IAAO,0CACPC,SAAY,MAEd,CACED,IAAO,qCACPC,SAAY,MAEd,CACED,IAAO,2CACPC,SAAY,MAEd,CACED,IAAO,sCACPC,SAAY,MAEd,CACED,IAAO,4CACPC,SAAY,MAEd,CACED,IAAO,uCACPC,SAAY,MAEd,CACED,IAAO,6CACPC,SAAY,MAEd,CACED,IAAO,oCACPC,SAAY,MAEd,CACED,IAAO,0CACPC,SAAY,MAEd,CACED,IAAO,6CACPC,SAAY,MAEd,CACED,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,kCACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,gBACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,uBACPC,SAAY,qCAEb,CAAE,GACLC,EAAAA,wBAC6BC,EAAAC,cAAC,IAAIC,EAA+BC,gBAACC,0BAA2C,eAAgB,CAC3HC,UAAW,CAAC"}
1
+ {"version":3,"file":"sw.js","sources":["../../../../../../../tmp/938e454bd62fa647563b204ae5598419/sw.js"],"sourcesContent":["import {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-routing/registerRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/vue-skuilder/vue-skuilder/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"assets/index-C5DT5vWX.css\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-D6gUuyAZ.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/materialdesignicons-webfont-Dp5v-WZN.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Black-VhoA2qKx.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-BlackItalic-D4yie1YO.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Bold-hN3duQhD.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-BoldItalic-BWDm51uc.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Light-DHTugVNA.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-LightItalic-JQyp2Y3P.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Medium-ByKogCTi.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-MediumItalic-i1eR0KbF.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Regular-C6rbFxYz.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-RegularItalic-CvPUdkvM.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-Thin-NicBC1pN.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/Roboto-ThinItalic-CKlCjrO_.woff2\",\n \"revision\": null\n },\n {\n \"url\": \"assets/workbox-window.prod.es5-p40uij6f.js\",\n \"revision\": null\n },\n {\n \"url\": \"favicon.ico\",\n \"revision\": \"b71387b4508120b59615e43d5e103706\"\n },\n {\n \"url\": \"img/icons/safari-pinned-tab.svg\",\n \"revision\": \"f22d501a35a87d9f21701cb031f6ea17\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"966239aa2fe2f5a413dfbe31306d249f\"\n },\n {\n \"url\": \"manifest.json\",\n \"revision\": \"14a155103e25199244cdda503219c3e1\"\n },\n {\n \"url\": \"robots.txt\",\n \"revision\": \"b6216d61c03e6ce0c9aea6ca7808f7ca\"\n },\n {\n \"url\": \"manifest.webmanifest\",\n \"revision\": \"0ad80257ac95729a8c88588d23a396c1\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\"), {\n allowlist: [/^(?!\\/(couch|express)).*$/],\n \n}));\n\n\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches","workbox","registerRoute","workbox_routing_NavigationRoute","NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,4BACPC,SAAY,MAEd,CACED,IAAO,2BACPC,SAAY,MAEd,CACED,IAAO,oDACPC,SAAY,MAEd,CACED,IAAO,qCACPC,SAAY,MAEd,CACED,IAAO,2CACPC,SAAY,MAEd,CACED,IAAO,oCACPC,SAAY,MAEd,CACED,IAAO,0CACPC,SAAY,MAEd,CACED,IAAO,qCACPC,SAAY,MAEd,CACED,IAAO,2CACPC,SAAY,MAEd,CACED,IAAO,sCACPC,SAAY,MAEd,CACED,IAAO,4CACPC,SAAY,MAEd,CACED,IAAO,uCACPC,SAAY,MAEd,CACED,IAAO,6CACPC,SAAY,MAEd,CACED,IAAO,oCACPC,SAAY,MAEd,CACED,IAAO,0CACPC,SAAY,MAEd,CACED,IAAO,6CACPC,SAAY,MAEd,CACED,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,kCACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,gBACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,uBACPC,SAAY,qCAEb,CAAE,GACLC,EAAAA,wBAC6BC,EAAAC,cAAC,IAAIC,EAA+BC,gBAACC,0BAA2C,eAAgB,CAC3HC,UAAW,CAAC"}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.5",
6
+ "version": "0.1.6",
7
7
  "scripts": {
8
8
  "dev": "vite",
9
9
  "build": "vite build",
@@ -25,11 +25,10 @@
25
25
  "dependencies": {
26
26
  "@mdi/font": "^7.3.67",
27
27
  "@tonaljs/tonal": "^3.6.0",
28
- "@vojtechlanka/vue-tags-input": "^3",
29
- "@vue-skuilder/common": "0.1.5",
30
- "@vue-skuilder/common-ui": "0.1.5",
31
- "@vue-skuilder/courses": "0.1.5",
32
- "@vue-skuilder/db": "0.1.5",
28
+ "@vue-skuilder/common": "0.1.6",
29
+ "@vue-skuilder/common-ui": "0.1.6",
30
+ "@vue-skuilder/courses": "0.1.6",
31
+ "@vue-skuilder/db": "0.1.6",
33
32
  "@vue/compiler-sfc": "^3.5.13",
34
33
  "abcjs": "^6.2.2",
35
34
  "canvas-confetti": "^1.9.3",
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <div>
3
+ <course-information :course-id="courseId" :view-lookup-function="viewLookup" :edit-mode="editMode">
4
+ <template #header="{ courseConfig: config }">
5
+ <h1 class="text-h4 mb-2"><router-link to="/q">Quilts</router-link> / {{ config.name }}</h1>
6
+ </template>
7
+
8
+ <template #actions="{ userIsRegistered, courseId: id, editMode: mode, register, drop }">
9
+ <transition name="component-fade" mode="out-in">
10
+ <div v-if="userIsRegistered">
11
+ <router-link :to="`/study/${id}`" class="me-2">
12
+ <v-btn color="success">Start a study session</v-btn>
13
+ </router-link>
14
+ <router-link v-if="mode === 'full'" :to="`/edit/${id}`" class="me-2">
15
+ <v-btn data-cy="add-content-btn" color="indigo-lighten-1">
16
+ <v-icon start>mdi-plus</v-icon>
17
+ Add content
18
+ </v-btn>
19
+ </router-link>
20
+ <router-link v-if="mode === 'full'" :to="`/courses/${id}/elo`" class="me-2">
21
+ <v-btn color="green-darken-2" title="Rank course content for difficulty">
22
+ <v-icon start>mdi-format-list-numbered</v-icon>
23
+ Arrange
24
+ </v-btn>
25
+ </router-link>
26
+ <v-btn v-if="mode === 'full'" color="error" size="small" variant="outlined" @click="drop">
27
+ Drop this course
28
+ </v-btn>
29
+ </div>
30
+ <div v-else>
31
+ <v-btn data-cy="register-btn" color="primary" class="me-2" @click="register">Register</v-btn>
32
+ <router-link :to="`/q/${id}/preview`">
33
+ <v-btn variant="outlined" color="primary" class="me-2">Start a trial study session</v-btn>
34
+ </router-link>
35
+ </div>
36
+ </transition>
37
+ </template>
38
+
39
+ <template #tag-link="{ tag, courseId: id }">
40
+ <router-link :to="`/q/${id}/tags/${tag.name}`">
41
+ <v-chip variant="tonal" class="me-2 mb-2">
42
+ {{ tag.name }}
43
+ </v-chip>
44
+ </router-link>
45
+ </template>
46
+
47
+ <template #additional-content>
48
+ <midi-config v-if="isPianoCourse" :_id="courseId" :user="user" class="my-3" />
49
+ </template>
50
+ </course-information>
51
+ </div>
52
+ </template>
53
+
54
+ <script lang="ts">
55
+ import { defineComponent, PropType } from 'vue';
56
+ import { CourseInformation, getCurrentUser } from '@vue-skuilder/common-ui';
57
+ import { MidiConfig, allCourses } from '@vue-skuilder/courses';
58
+ import { UserDBInterface, getDataLayer } from '@vue-skuilder/db';
59
+ import { CourseConfig } from '@vue-skuilder/common';
60
+
61
+ export default defineComponent({
62
+ name: 'CourseInformationWrapper',
63
+
64
+ components: {
65
+ CourseInformation,
66
+ MidiConfig,
67
+ },
68
+
69
+ props: {
70
+ courseId: {
71
+ type: String as PropType<string>,
72
+ required: true,
73
+ },
74
+ },
75
+
76
+ data() {
77
+ return {
78
+ courseConfig: {} as CourseConfig,
79
+ user: null as UserDBInterface | null,
80
+ editMode: 'full' as 'none' | 'readonly' | 'full',
81
+ };
82
+ },
83
+
84
+ computed: {
85
+ isPianoCourse(): boolean {
86
+ return this.courseConfig.name?.toLowerCase().includes('piano') ?? false;
87
+ },
88
+ },
89
+
90
+ async created() {
91
+ const dataLayer = getDataLayer();
92
+ const courseDB = dataLayer.getCourseDB(this.courseId);
93
+ this.courseConfig = await courseDB.getCourseConfig();
94
+ this.user = await getCurrentUser();
95
+
96
+ // Determine edit mode based on data layer capabilities
97
+ this.editMode = dataLayer.isReadOnly() ? 'readonly' : 'full';
98
+ },
99
+
100
+ methods: {
101
+ viewLookup(x: unknown) {
102
+ return allCourses.getView(x);
103
+ },
104
+ },
105
+ });
106
+ </script>
107
+
108
+ <style scoped>
109
+ .component-fade-enter-active,
110
+ .component-fade-leave-active {
111
+ transition: opacity 0.5s ease;
112
+ }
113
+ .component-fade-enter,
114
+ .component-fade-leave-to {
115
+ opacity: 0;
116
+ }
117
+ </style>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div>
3
3
  <div v-if="initComplete">
4
- <course-information v-if="courseId !== undefined && courseId !== ''" :course-id="courseId" />
4
+ <course-information-wrapper v-if="courseId !== undefined && courseId !== ''" :course-id="courseId" />
5
5
  <v-container v-else-if="candidates.length === 0">
6
6
  <v-row class="text-h4">
7
7
  {{ query }}
@@ -47,13 +47,13 @@ import { defineComponent } from 'vue';
47
47
  import { getDataLayer } from '@vue-skuilder/db';
48
48
  import { CourseConfig } from '@vue-skuilder/common';
49
49
  import CourseEditor from './CourseEditor.vue';
50
- import CourseInformation from './CourseInformation.vue';
50
+ import CourseInformationWrapper from './CourseInformationWrapper.vue';
51
51
 
52
52
  export default defineComponent({
53
53
  name: 'CourseRouter',
54
54
 
55
55
  components: {
56
- CourseInformation,
56
+ CourseInformationWrapper,
57
57
  CourseEditor,
58
58
  },
59
59
 
@@ -57,7 +57,7 @@
57
57
  </template>
58
58
  </v-text-field>
59
59
 
60
- <course-card-browser :course-id="courseId" :tag-id="tagId" />
60
+ <course-card-browser :course-id="courseId" :tag-id="tagId" :view-lookup-function="viewLookup" />
61
61
  </div>
62
62
  </template>
63
63
 
@@ -65,8 +65,9 @@
65
65
  import { defineComponent } from 'vue';
66
66
  import { DocType, Tag, getDataLayer, CourseDBInterface } from '@vue-skuilder/db';
67
67
  import { Status, CourseConfig } from '@vue-skuilder/common';
68
- import CourseCardBrowser from './CourseCardBrowser.vue';
68
+ import { CourseCardBrowser } from '@vue-skuilder/common-ui';
69
69
  import { alertUser } from '@vue-skuilder/common-ui';
70
+ import { allCourses } from '@vue-skuilder/courses';
70
71
 
71
72
  export default defineComponent({
72
73
  name: 'TagInformation',
@@ -131,6 +132,10 @@ export default defineComponent({
131
132
  },
132
133
 
133
134
  methods: {
135
+ viewLookup(x: unknown) {
136
+ return allCourses.getView(x);
137
+ },
138
+
134
139
  editSnippet() {
135
140
  console.log('[TagInformation] EditSnip');
136
141
  this.editingSnippet = true;
@@ -106,7 +106,7 @@
106
106
  import { ViewComponent, SkldrMouseTrap, HotKey, SkMouseTrap } from '@vue-skuilder/common-ui';
107
107
  import { DataShape, ParsedCard, ViewData } from '@vue-skuilder/common';
108
108
  import { defineComponent, PropType } from 'vue';
109
- import CardBrowser from '../CardBrowser.vue';
109
+ import { CardBrowser } from '@vue-skuilder/common-ui';
110
110
 
111
111
  export default defineComponent({
112
112
  name: 'CardPreviewList',
@@ -311,14 +311,14 @@ export default defineComponent({
311
311
  // Show alert to confirm deletion
312
312
  alertUser({
313
313
  text: 'Card removed from import list',
314
- status: Status.info,
314
+ status: Status.ok,
315
315
  });
316
316
  },
317
317
 
318
318
  handleEditCard(card: ParsedCard, index: number) {
319
319
  // Disable keyboard shortcuts while editing
320
320
  if (this.$refs.cardPreviewList) {
321
- (this.$refs.cardPreviewList as any).toggleShortcuts(false);
321
+ (this.$refs.cardPreviewList as { toggleShortcuts: (enabled: boolean) => void }).toggleShortcuts(false);
322
322
  }
323
323
 
324
324
  this.editingCard = { ...card }; // Create a copy
@@ -331,7 +331,7 @@ export default defineComponent({
331
331
  // Focus the text area after dialog opens
332
332
  this.$nextTick(() => {
333
333
  if (this.$refs.markdownTextarea) {
334
- (this.$refs.markdownTextarea as any).$el.querySelector('textarea')?.focus();
334
+ (this.$refs.markdownTextarea as { $el: HTMLElement }).$el.querySelector('textarea')?.focus();
335
335
  }
336
336
  });
337
337
  },
@@ -357,7 +357,7 @@ export default defineComponent({
357
357
  // Show alert to confirm edit
358
358
  alertUser({
359
359
  text: 'Card updated successfully',
360
- status: Status.success,
360
+ status: Status.ok,
361
361
  });
362
362
  },
363
363
 
@@ -372,7 +372,7 @@ export default defineComponent({
372
372
  // Re-enable keyboard shortcuts after editing
373
373
  setTimeout(() => {
374
374
  if (this.$refs.cardPreviewList) {
375
- (this.$refs.cardPreviewList as any).toggleShortcuts(true);
375
+ (this.$refs.cardPreviewList as { toggleShortcuts: (enabled: boolean) => void }).toggleShortcuts(true);
376
376
  }
377
377
  }, 100);
378
378
  },
@@ -582,7 +582,7 @@ export default defineComponent({
582
582
  // this.bulkText = ''; // Clear input text
583
583
  // this.parsingComplete = false; // Go back to input stage
584
584
  // this.parsedCards = [];
585
- alertUser({ text: `${this.results.length} card(s) imported successfully!`, status: Status.success });
585
+ alertUser({ text: `${this.results.length} card(s) imported successfully!`, status: Status.ok });
586
586
  } else if (this.results.some((r) => r.status === 'error')) {
587
587
  alertUser({ text: 'Some cards failed to import. Please review the results below.', status: Status.warning });
588
588
  }
@@ -82,8 +82,9 @@
82
82
  <script lang="ts">
83
83
  import { defineComponent } from 'vue';
84
84
  import { DataShape } from '@vue-skuilder/common';
85
- import CardBrowser from '@pui/components/Edit/CardBrowser.vue';
86
- import TagsInput, { TagsInputInstance } from '@pui/components/Edit/TagsInput.vue';
85
+ import { CardBrowser } from '@vue-skuilder/common-ui';
86
+ import { TagsInput } from '@vue-skuilder/common-ui';
87
+ import type { TagsInputInstance } from '@vue-skuilder/common-ui/src/components/TagsInput.vue';
87
88
  import { FieldInputInstance, isFieldInput } from '@pui/components/Edit/ViewableDataInputForm/FieldInput.types';
88
89
  import { alertUser } from '@vue-skuilder/common-ui';
89
90
  import { allCourses } from '@vue-skuilder/courses';
package/src/main.ts CHANGED
@@ -7,8 +7,11 @@ import './registerServiceWorker';
7
7
  import router from './router';
8
8
  import { createPinia } from 'pinia';
9
9
  import vuetify from './plugins/vuetify';
10
- // `courses` imports - keep style import for initial page rendering
11
- // import '@vue-skuilder/courses/style';
10
+
11
+ // styles from component library packages
12
+ import '@vue-skuilder/courses/style';
13
+ import '@vue-skuilder/common-ui/style';
14
+
12
15
  // `db` import and initialization
13
16
  import { initializeDataLayer } from '@vue-skuilder/db';
14
17