@vue-skuilder/common-ui 0.1.1
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 +10 -0
- package/dist/common-ui.es.js +16404 -0
- package/dist/common-ui.es.js.map +1 -0
- package/dist/common-ui.umd.js +9 -0
- package/dist/common-ui.umd.js.map +1 -0
- package/dist/components/HeatMap.types.d.ts +13 -0
- package/dist/components/PaginatingToolbar.types.d.ts +40 -0
- package/dist/components/SkMouseTrap.types.d.ts +3 -0
- package/dist/components/SkMouseTrapToolTip.types.d.ts +35 -0
- package/dist/components/SnackbarService.d.ts +11 -0
- package/dist/components/StudySession.types.d.ts +6 -0
- package/dist/components/auth/index.d.ts +4 -0
- package/dist/components/cardRendering/MarkdownRendererHelpers.d.ts +22 -0
- package/dist/components/studentInputs/BaseUserInput.d.ts +16 -0
- package/dist/components/studentInputs/RadioMultipleChoice.types.d.ts +5 -0
- package/dist/composables/CompositionViewable.d.ts +33 -0
- package/dist/composables/Displayable.d.ts +47 -0
- package/dist/composables/index.d.ts +2 -0
- package/dist/index.d.ts +36 -0
- package/dist/plugins/pinia.d.ts +5 -0
- package/dist/stores/useAuthStore.d.ts +225 -0
- package/dist/stores/useCardPreviewModeStore.d.ts +8 -0
- package/dist/stores/useConfigStore.d.ts +11 -0
- package/dist/utils/SkldrMouseTrap.d.ts +32 -0
- package/package.json +67 -0
- package/src/components/HeatMap.types.ts +15 -0
- package/src/components/HeatMap.vue +354 -0
- package/src/components/PaginatingToolbar.types.ts +48 -0
- package/src/components/PaginatingToolbar.vue +75 -0
- package/src/components/SkMouseTrap.types.ts +3 -0
- package/src/components/SkMouseTrap.vue +70 -0
- package/src/components/SkMouseTrapToolTip.types.ts +41 -0
- package/src/components/SkMouseTrapToolTip.vue +316 -0
- package/src/components/SnackbarService.ts +39 -0
- package/src/components/SnackbarService.vue +71 -0
- package/src/components/StudySession.types.ts +6 -0
- package/src/components/StudySession.vue +670 -0
- package/src/components/StudySessionTimer.vue +121 -0
- package/src/components/auth/UserChip.vue +106 -0
- package/src/components/auth/UserLogin.vue +141 -0
- package/src/components/auth/UserLoginAndRegistrationContainer.vue +85 -0
- package/src/components/auth/UserRegistration.vue +181 -0
- package/src/components/auth/index.ts +4 -0
- package/src/components/cardRendering/AudioAutoPlayer.vue +131 -0
- package/src/components/cardRendering/CardLoader.vue +123 -0
- package/src/components/cardRendering/CardViewer.vue +101 -0
- package/src/components/cardRendering/CodeBlockRenderer.vue +81 -0
- package/src/components/cardRendering/MarkdownRenderer.vue +46 -0
- package/src/components/cardRendering/MarkdownRendererHelpers.ts +114 -0
- package/src/components/cardRendering/MdTokenRenderer.vue +244 -0
- package/src/components/studentInputs/BaseUserInput.ts +71 -0
- package/src/components/studentInputs/MultipleChoiceOption.vue +127 -0
- package/src/components/studentInputs/RadioMultipleChoice.types.ts +6 -0
- package/src/components/studentInputs/RadioMultipleChoice.vue +168 -0
- package/src/components/studentInputs/TrueFalse.vue +27 -0
- package/src/components/studentInputs/UserInputNumber.vue +63 -0
- package/src/components/studentInputs/UserInputString.vue +89 -0
- package/src/components/studentInputs/fillInInput.vue +71 -0
- package/src/composables/CompositionViewable.ts +180 -0
- package/src/composables/Displayable.ts +133 -0
- package/src/composables/index.ts +2 -0
- package/src/index.ts +79 -0
- package/src/plugins/pinia.ts +24 -0
- package/src/stores/useAuthStore.ts +92 -0
- package/src/stores/useCardPreviewModeStore.ts +32 -0
- package/src/stores/useConfigStore.ts +60 -0
- package/src/utils/SkldrMouseTrap.ts +141 -0
- package/src/vue-shims.d.ts +5 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface PaginatingToolbarProps {
|
|
2
|
+
/**
|
|
3
|
+
* Array of page numbers
|
|
4
|
+
*/
|
|
5
|
+
pages: number[];
|
|
6
|
+
/**
|
|
7
|
+
* Current active page
|
|
8
|
+
*/
|
|
9
|
+
page: number;
|
|
10
|
+
/**
|
|
11
|
+
* Main title displayed in the toolbar
|
|
12
|
+
*/
|
|
13
|
+
title?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Secondary text displayed next to the title
|
|
16
|
+
*/
|
|
17
|
+
subtitle?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface PaginatingToolbarEvents {
|
|
20
|
+
/**
|
|
21
|
+
* Navigate to the first page
|
|
22
|
+
*/
|
|
23
|
+
(e: 'first'): void;
|
|
24
|
+
/**
|
|
25
|
+
* Navigate to the previous page
|
|
26
|
+
*/
|
|
27
|
+
(e: 'prev'): void;
|
|
28
|
+
/**
|
|
29
|
+
* Navigate to the next page
|
|
30
|
+
*/
|
|
31
|
+
(e: 'next'): void;
|
|
32
|
+
/**
|
|
33
|
+
* Navigate to the last page
|
|
34
|
+
*/
|
|
35
|
+
(e: 'last'): void;
|
|
36
|
+
/**
|
|
37
|
+
* Set the page to a specific number
|
|
38
|
+
*/
|
|
39
|
+
(e: 'set-page', page: number): void;
|
|
40
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface SkMouseTrapToolTipProps {
|
|
2
|
+
/**
|
|
3
|
+
* The keyboard shortcut(s) to bind to this tooltip.
|
|
4
|
+
* Can be a single string like "ctrl+s" or an array of strings.
|
|
5
|
+
*/
|
|
6
|
+
hotkey: string | string[];
|
|
7
|
+
/**
|
|
8
|
+
* Descriptive name for the keyboard shortcut.
|
|
9
|
+
* Will be displayed in the shortcut dialog.
|
|
10
|
+
*/
|
|
11
|
+
command: string;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the shortcut is currently disabled.
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The position of the tooltip relative to the wrapped element.
|
|
19
|
+
* @default 'top'
|
|
20
|
+
*/
|
|
21
|
+
position?: 'top' | 'bottom' | 'left' | 'right';
|
|
22
|
+
/**
|
|
23
|
+
* Whether to show the tooltip when the Ctrl key is pressed.
|
|
24
|
+
* @default true
|
|
25
|
+
*/
|
|
26
|
+
showTooltip?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The visual effect to apply to the wrapped element when Ctrl is pressed.
|
|
29
|
+
* @default 'glow'
|
|
30
|
+
*/
|
|
31
|
+
highlightEffect?: 'glow' | 'scale' | 'border' | 'none';
|
|
32
|
+
}
|
|
33
|
+
export interface SkMouseTrapToolTipEmits {
|
|
34
|
+
(event: 'hotkey-triggered', hotkey: string | string[]): void;
|
|
35
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Status } from '@vue-skuilder/common';
|
|
2
|
+
export interface SnackbarOptions {
|
|
3
|
+
text: string;
|
|
4
|
+
status: Status;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare const setInstance: (instance: {
|
|
8
|
+
addSnack: (snack: SnackbarOptions) => void;
|
|
9
|
+
}) => void, getInstance: () => {
|
|
10
|
+
addSnack: (snack: SnackbarOptions) => void;
|
|
11
|
+
} | null, alertUser: (msg: SnackbarOptions) => void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as UserChip } from './UserChip.vue';
|
|
2
|
+
export { default as UserLogin } from './UserLogin.vue';
|
|
3
|
+
export { default as UserRegistration } from './UserRegistration.vue';
|
|
4
|
+
export { default as UserLoginAndRegistrationContainer } from './UserLoginAndRegistrationContainer.vue';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MarkedToken, Tokens } from 'marked';
|
|
2
|
+
/**
|
|
3
|
+
* recursively splits text according to the passed delimiters.
|
|
4
|
+
*
|
|
5
|
+
* eg: ("abcde", "b", "d") => ["a", "bcd", "e"]
|
|
6
|
+
* ("a[b][c]", "[", "]") => ["a", "[b]", "[c]"]
|
|
7
|
+
*
|
|
8
|
+
* it does not check that the delimiters are well formed in the text
|
|
9
|
+
* @param text the text to be split
|
|
10
|
+
* @param l the left delimiter
|
|
11
|
+
* @param r the right delimiter
|
|
12
|
+
* @returns the split result
|
|
13
|
+
*/
|
|
14
|
+
export declare function splitByDelimiters(text: string, l: string, r: string): string[];
|
|
15
|
+
export declare function splitTextToken(token: Tokens.Text): Tokens.Text[];
|
|
16
|
+
export type TokenOrComponent = MarkedToken | {
|
|
17
|
+
type: 'component';
|
|
18
|
+
raw: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function splitParagraphToken(token: Tokens.Paragraph): TokenOrComponent[];
|
|
21
|
+
export declare function containsComponent(token: MarkedToken): boolean;
|
|
22
|
+
export declare function isComponent(token: MarkedToken): boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Answer } from '@vue-skuilder/common';
|
|
2
|
+
import { useCardPreviewModeStore } from '../../stores/useCardPreviewModeStore';
|
|
3
|
+
import { ViewComponent } from '../../composables/Displayable';
|
|
4
|
+
import { QuestionRecord } from '@vue-skuilder/db';
|
|
5
|
+
declare const _default: import("vue").DefineComponent<{}, {}, {
|
|
6
|
+
answer: Answer;
|
|
7
|
+
previewModeStore: ReturnType<typeof useCardPreviewModeStore> | null;
|
|
8
|
+
}, {
|
|
9
|
+
autofocus(): boolean;
|
|
10
|
+
autoFocus(): boolean;
|
|
11
|
+
}, {
|
|
12
|
+
submitAnswer(answer: Answer): QuestionRecord;
|
|
13
|
+
submit(answer: Answer): any;
|
|
14
|
+
getQuestionViewAncestor(): ViewComponent;
|
|
15
|
+
}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import moment from 'moment';
|
|
2
|
+
import { ComputedRef, Ref } from 'vue';
|
|
3
|
+
import { CardRecord, QuestionRecord } from '@vue-skuilder/db';
|
|
4
|
+
import { HotKey } from '../utils/SkldrMouseTrap';
|
|
5
|
+
import { Question } from './Displayable';
|
|
6
|
+
import { ViewData, Answer } from '@vue-skuilder/common';
|
|
7
|
+
export interface ViewableUtils {
|
|
8
|
+
startTime: Ref<moment.Moment>;
|
|
9
|
+
hotKeys: Ref<HotKey[]>;
|
|
10
|
+
timeSpent: ComputedRef<number>;
|
|
11
|
+
logger: ViewableLogger;
|
|
12
|
+
getURL: (item: string, dataShapeIndex?: number) => string;
|
|
13
|
+
emitResponse: (record: CardRecord) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface ViewableLogger {
|
|
16
|
+
log: (message?: unknown, ...params: unknown[]) => void;
|
|
17
|
+
error: (message?: unknown, ...params: unknown[]) => void;
|
|
18
|
+
warn: (message?: unknown, ...params: unknown[]) => void;
|
|
19
|
+
}
|
|
20
|
+
export interface QuestionViewUtils<Q extends Question> {
|
|
21
|
+
priorSessionViews: Ref<number>;
|
|
22
|
+
priorAttempts: Ref<number>;
|
|
23
|
+
priorAnswers: Ref<[Answer, string][]>;
|
|
24
|
+
maxAttemptsPerView: Ref<number>;
|
|
25
|
+
maxSessionViews: Ref<number>;
|
|
26
|
+
question: Ref<Q | undefined>;
|
|
27
|
+
submitAnswer: (answer: Answer, submittingClass?: string) => QuestionRecord;
|
|
28
|
+
}
|
|
29
|
+
export declare function useViewable(props: {
|
|
30
|
+
data: ViewData[];
|
|
31
|
+
}, emit: (event: string, ...args: unknown[]) => void, componentName: string): ViewableUtils;
|
|
32
|
+
export declare function useQuestionView<Q extends Question>(viewableUtils: ViewableUtils): QuestionViewUtils<Q>;
|
|
33
|
+
export declare function isQuestionView(component: any): component is QuestionViewUtils<Question>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type DefineComponent, defineComponent } from 'vue';
|
|
2
|
+
import { DataShape, ViewData, Answer, Evaluation } from '@vue-skuilder/common';
|
|
3
|
+
export type ViewComponent = DefineComponent<unknown, unknown, unknown> | ReturnType<typeof defineComponent>;
|
|
4
|
+
export declare function isDefineComponent(v: ViewComponent): v is DefineComponent<unknown, unknown, unknown>;
|
|
5
|
+
export declare abstract class Displayable {
|
|
6
|
+
static dataShapes: DataShape[];
|
|
7
|
+
static views: Array<ViewComponent>;
|
|
8
|
+
static seedData?: Array<any>;
|
|
9
|
+
/**
|
|
10
|
+
* True if this displayable content type is meant to have
|
|
11
|
+
* user-submitted questions. False if supplied seedData array
|
|
12
|
+
* is comprehensive for the content type. EG, a SingleDigitAddition
|
|
13
|
+
* type may comprehensively supply 0+0,0+1,...,9+9 as its seed
|
|
14
|
+
* data, and not want any user input.
|
|
15
|
+
*/
|
|
16
|
+
static acceptsUserData: boolean;
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
constructor(viewData: ViewData[]);
|
|
21
|
+
abstract dataShapes(): DataShape[];
|
|
22
|
+
abstract views(): Array<ViewComponent>;
|
|
23
|
+
}
|
|
24
|
+
export declare abstract class Question extends Displayable {
|
|
25
|
+
/**
|
|
26
|
+
* returns a yes/no evaluation of a user's answer. Informs the SRS
|
|
27
|
+
* algorithm's decision to expand or reset a card's spacing
|
|
28
|
+
* @param answer
|
|
29
|
+
*/
|
|
30
|
+
protected abstract isCorrect(answer: Answer): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* returns a number from [0,1] representing the user's performance on the question,
|
|
33
|
+
* which informs elo adjustments and SRS multipliers
|
|
34
|
+
*
|
|
35
|
+
* @param answer the user's answer
|
|
36
|
+
* @param timeSpent the time the user spent on the card in milliseconds
|
|
37
|
+
* @returns a rating of the user's displayed skill, from 0-1
|
|
38
|
+
*/
|
|
39
|
+
protected displayedSkill(answer: Answer, timeSpent: number): number;
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @param answer the student's answer
|
|
43
|
+
* @param timeSpent the amount of time spent in ms
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
evaluate(answer: Answer, timeSpent: number): Evaluation;
|
|
47
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export { default as HeatMap } from './components/HeatMap.vue';
|
|
2
|
+
export type { DayData, Color, ActivityRecord } from './components/HeatMap.types';
|
|
3
|
+
export { default as SkMouseTrap } from './components/SkMouseTrap.vue';
|
|
4
|
+
export { default as SkMouseTrapToolTip } from './components/SkMouseTrapToolTip.vue';
|
|
5
|
+
export * from './components/SkMouseTrap.types';
|
|
6
|
+
export * from './components/SkMouseTrapToolTip.types';
|
|
7
|
+
export { SkldrMouseTrap } from './utils/SkldrMouseTrap';
|
|
8
|
+
export type { HotKey, HotKeyMetaData } from './utils/SkldrMouseTrap';
|
|
9
|
+
export { default as SnackbarService } from './components/SnackbarService.vue';
|
|
10
|
+
export { alertUser, type SnackbarOptions } from './components/SnackbarService';
|
|
11
|
+
export { default as PaginatingToolbar } from './components/PaginatingToolbar.vue';
|
|
12
|
+
export * from './components/PaginatingToolbar.types';
|
|
13
|
+
export * from './composables/CompositionViewable';
|
|
14
|
+
export * from './composables/Displayable';
|
|
15
|
+
export { default as StudySession } from './components/StudySession.vue';
|
|
16
|
+
export { default as StudySessionTimer } from './components/StudySessionTimer.vue';
|
|
17
|
+
export type { StudySessionConfig } from './components/StudySession.types';
|
|
18
|
+
export * from './components/studentInputs/BaseUserInput';
|
|
19
|
+
export { default as RadioMultipleChoice } from './components/studentInputs/RadioMultipleChoice.vue';
|
|
20
|
+
export { default as MultipleChoiceOption } from './components/studentInputs/MultipleChoiceOption.vue';
|
|
21
|
+
export { default as TFSelect } from './components/studentInputs/TrueFalse.vue';
|
|
22
|
+
export { default as UserInputNumber } from './components/studentInputs/UserInputNumber.vue';
|
|
23
|
+
export { default as UserInputString } from './components/studentInputs/UserInputString.vue';
|
|
24
|
+
export { default as FillInInput } from './components/studentInputs/fillInInput.vue';
|
|
25
|
+
export { default as CardViewer } from './components/cardRendering/CardViewer.vue';
|
|
26
|
+
export { default as CardLoader } from './components/cardRendering/CardLoader.vue';
|
|
27
|
+
export * from './components/cardRendering/MarkdownRendererHelpers';
|
|
28
|
+
export { default as AudioAutoPlayer } from './components/cardRendering/AudioAutoPlayer.vue';
|
|
29
|
+
export { default as CodeBlockRenderer } from './components/cardRendering/CodeBlockRenderer.vue';
|
|
30
|
+
export { default as MdTokenRenderer } from './components/cardRendering/MdTokenRenderer.vue';
|
|
31
|
+
export { default as MarkdownRenderer } from './components/cardRendering/MarkdownRenderer.vue';
|
|
32
|
+
export * from './components/auth';
|
|
33
|
+
export * from './stores/useCardPreviewModeStore';
|
|
34
|
+
export * from './stores/useAuthStore';
|
|
35
|
+
export * from './stores/useConfigStore';
|
|
36
|
+
export { piniaPlugin } from './plugins/pinia';
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { UserDBInterface } from '@vue-skuilder/db';
|
|
2
|
+
export interface AuthState {
|
|
3
|
+
_user: UserDBInterface | undefined;
|
|
4
|
+
loginAndRegistration: {
|
|
5
|
+
init: boolean;
|
|
6
|
+
loggedIn: boolean;
|
|
7
|
+
regDialogOpen: boolean;
|
|
8
|
+
loginDialogOpen: boolean;
|
|
9
|
+
};
|
|
10
|
+
onLoadComplete: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function getCurrentUser(): Promise<UserDBInterface>;
|
|
13
|
+
export declare const useAuthStore: () => import("pinia").Store<"auth", AuthState, {
|
|
14
|
+
currentUser: () => Promise<UserDBInterface>;
|
|
15
|
+
isLoggedIn: (state: {
|
|
16
|
+
_user: {
|
|
17
|
+
createAccount: (username: string, password: string) => Promise<{
|
|
18
|
+
status: import("@vue-skuilder/common").Status;
|
|
19
|
+
error: string;
|
|
20
|
+
}>;
|
|
21
|
+
login: (username: string, password: string) => Promise<{
|
|
22
|
+
ok: boolean;
|
|
23
|
+
name?: string;
|
|
24
|
+
roles?: string[];
|
|
25
|
+
}>;
|
|
26
|
+
logout: () => Promise<{
|
|
27
|
+
ok: boolean;
|
|
28
|
+
}>;
|
|
29
|
+
getUsername: () => string;
|
|
30
|
+
isLoggedIn: () => boolean;
|
|
31
|
+
getConfig: () => Promise<import("@vue-skuilder/db").UserConfig>;
|
|
32
|
+
setConfig: (config: Partial<import("@vue-skuilder/db").UserConfig>) => Promise<void>;
|
|
33
|
+
putCardRecord: <T extends import("@vue-skuilder/db").CardRecord>(record: T) => Promise<import("@vue-skuilder/db").CardHistory<import("@vue-skuilder/db").CardRecord>>;
|
|
34
|
+
getSeenCards: (courseId?: string) => Promise<string[]>;
|
|
35
|
+
getActiveCards: () => Promise<string[]>;
|
|
36
|
+
registerForCourse: (courseId: string, previewMode?: boolean) => Promise<PouchDB.Core.Response>;
|
|
37
|
+
dropCourse: (courseId: string, dropStatus?: string) => Promise<PouchDB.Core.Response>;
|
|
38
|
+
getCourseRegistrationsDoc: () => Promise<import("@vue-skuilder/db").CourseRegistrationDoc>;
|
|
39
|
+
getCourseRegDoc: (courseId: string) => Promise<import("@vue-skuilder/db").CourseRegistration>;
|
|
40
|
+
getActiveCourses: () => Promise<import("@vue-skuilder/db").CourseRegistration[]>;
|
|
41
|
+
getPendingReviews: (courseId?: string) => Promise<import("@vue-skuilder/db").ScheduledCard[]>;
|
|
42
|
+
getActivityRecords: () => Promise<import("@vue-skuilder/db").ActivityRecord[]>;
|
|
43
|
+
scheduleCardReview: (review: {
|
|
44
|
+
user: string;
|
|
45
|
+
course_id: string;
|
|
46
|
+
card_id: string;
|
|
47
|
+
time: import("moment").Moment;
|
|
48
|
+
scheduledFor: "course" | "classroom";
|
|
49
|
+
schedulingAgentId: string;
|
|
50
|
+
}) => Promise<void>;
|
|
51
|
+
removeScheduledCardReview: (reviewId: string) => Promise<void>;
|
|
52
|
+
registerForClassroom: (classId: string, registerAs: "student" | "teacher" | "aide" | "admin") => Promise<PouchDB.Core.Response>;
|
|
53
|
+
dropFromClassroom: (classId: string) => Promise<PouchDB.Core.Response>;
|
|
54
|
+
getUserClassrooms: () => Promise<import("@vue-skuilder/db").ClassroomRegistrationDoc>;
|
|
55
|
+
getActiveClasses: () => Promise<string[]>;
|
|
56
|
+
updateUserElo: (courseId: string, elo: import("@vue-skuilder/common").CourseElo) => Promise<PouchDB.Core.Response>;
|
|
57
|
+
getCourseInterface: (courseId: string) => Promise<import("@vue-skuilder/db").UsrCrsDataInterface>;
|
|
58
|
+
update: <T extends PouchDB.Core.Document<object>>(id: string, update: Partial<T> | ((x: T) => T)) => Promise<T>;
|
|
59
|
+
} | undefined;
|
|
60
|
+
loginAndRegistration: {
|
|
61
|
+
init: boolean;
|
|
62
|
+
loggedIn: boolean;
|
|
63
|
+
regDialogOpen: boolean;
|
|
64
|
+
loginDialogOpen: boolean;
|
|
65
|
+
};
|
|
66
|
+
onLoadComplete: boolean;
|
|
67
|
+
} & import("pinia").PiniaCustomStateProperties<AuthState>) => boolean;
|
|
68
|
+
isInitialized: (state: {
|
|
69
|
+
_user: {
|
|
70
|
+
createAccount: (username: string, password: string) => Promise<{
|
|
71
|
+
status: import("@vue-skuilder/common").Status;
|
|
72
|
+
error: string;
|
|
73
|
+
}>;
|
|
74
|
+
login: (username: string, password: string) => Promise<{
|
|
75
|
+
ok: boolean;
|
|
76
|
+
name?: string;
|
|
77
|
+
roles?: string[];
|
|
78
|
+
}>;
|
|
79
|
+
logout: () => Promise<{
|
|
80
|
+
ok: boolean;
|
|
81
|
+
}>;
|
|
82
|
+
getUsername: () => string;
|
|
83
|
+
isLoggedIn: () => boolean;
|
|
84
|
+
getConfig: () => Promise<import("@vue-skuilder/db").UserConfig>;
|
|
85
|
+
setConfig: (config: Partial<import("@vue-skuilder/db").UserConfig>) => Promise<void>;
|
|
86
|
+
putCardRecord: <T extends import("@vue-skuilder/db").CardRecord>(record: T) => Promise<import("@vue-skuilder/db").CardHistory<import("@vue-skuilder/db").CardRecord>>;
|
|
87
|
+
getSeenCards: (courseId?: string) => Promise<string[]>;
|
|
88
|
+
getActiveCards: () => Promise<string[]>;
|
|
89
|
+
registerForCourse: (courseId: string, previewMode?: boolean) => Promise<PouchDB.Core.Response>;
|
|
90
|
+
dropCourse: (courseId: string, dropStatus?: string) => Promise<PouchDB.Core.Response>;
|
|
91
|
+
getCourseRegistrationsDoc: () => Promise<import("@vue-skuilder/db").CourseRegistrationDoc>;
|
|
92
|
+
getCourseRegDoc: (courseId: string) => Promise<import("@vue-skuilder/db").CourseRegistration>;
|
|
93
|
+
getActiveCourses: () => Promise<import("@vue-skuilder/db").CourseRegistration[]>;
|
|
94
|
+
getPendingReviews: (courseId?: string) => Promise<import("@vue-skuilder/db").ScheduledCard[]>;
|
|
95
|
+
getActivityRecords: () => Promise<import("@vue-skuilder/db").ActivityRecord[]>;
|
|
96
|
+
scheduleCardReview: (review: {
|
|
97
|
+
user: string;
|
|
98
|
+
course_id: string;
|
|
99
|
+
card_id: string;
|
|
100
|
+
time: import("moment").Moment;
|
|
101
|
+
scheduledFor: "course" | "classroom";
|
|
102
|
+
schedulingAgentId: string;
|
|
103
|
+
}) => Promise<void>;
|
|
104
|
+
removeScheduledCardReview: (reviewId: string) => Promise<void>;
|
|
105
|
+
registerForClassroom: (classId: string, registerAs: "student" | "teacher" | "aide" | "admin") => Promise<PouchDB.Core.Response>;
|
|
106
|
+
dropFromClassroom: (classId: string) => Promise<PouchDB.Core.Response>;
|
|
107
|
+
getUserClassrooms: () => Promise<import("@vue-skuilder/db").ClassroomRegistrationDoc>;
|
|
108
|
+
getActiveClasses: () => Promise<string[]>;
|
|
109
|
+
updateUserElo: (courseId: string, elo: import("@vue-skuilder/common").CourseElo) => Promise<PouchDB.Core.Response>;
|
|
110
|
+
getCourseInterface: (courseId: string) => Promise<import("@vue-skuilder/db").UsrCrsDataInterface>;
|
|
111
|
+
update: <T extends PouchDB.Core.Document<object>>(id: string, update: Partial<T> | ((x: T) => T)) => Promise<T>;
|
|
112
|
+
} | undefined;
|
|
113
|
+
loginAndRegistration: {
|
|
114
|
+
init: boolean;
|
|
115
|
+
loggedIn: boolean;
|
|
116
|
+
regDialogOpen: boolean;
|
|
117
|
+
loginDialogOpen: boolean;
|
|
118
|
+
};
|
|
119
|
+
onLoadComplete: boolean;
|
|
120
|
+
} & import("pinia").PiniaCustomStateProperties<AuthState>) => boolean;
|
|
121
|
+
status: (state: {
|
|
122
|
+
_user: {
|
|
123
|
+
createAccount: (username: string, password: string) => Promise<{
|
|
124
|
+
status: import("@vue-skuilder/common").Status;
|
|
125
|
+
error: string;
|
|
126
|
+
}>;
|
|
127
|
+
login: (username: string, password: string) => Promise<{
|
|
128
|
+
ok: boolean;
|
|
129
|
+
name?: string;
|
|
130
|
+
roles?: string[];
|
|
131
|
+
}>;
|
|
132
|
+
logout: () => Promise<{
|
|
133
|
+
ok: boolean;
|
|
134
|
+
}>;
|
|
135
|
+
getUsername: () => string;
|
|
136
|
+
isLoggedIn: () => boolean;
|
|
137
|
+
getConfig: () => Promise<import("@vue-skuilder/db").UserConfig>;
|
|
138
|
+
setConfig: (config: Partial<import("@vue-skuilder/db").UserConfig>) => Promise<void>;
|
|
139
|
+
putCardRecord: <T extends import("@vue-skuilder/db").CardRecord>(record: T) => Promise<import("@vue-skuilder/db").CardHistory<import("@vue-skuilder/db").CardRecord>>;
|
|
140
|
+
getSeenCards: (courseId?: string) => Promise<string[]>;
|
|
141
|
+
getActiveCards: () => Promise<string[]>;
|
|
142
|
+
registerForCourse: (courseId: string, previewMode?: boolean) => Promise<PouchDB.Core.Response>;
|
|
143
|
+
dropCourse: (courseId: string, dropStatus?: string) => Promise<PouchDB.Core.Response>;
|
|
144
|
+
getCourseRegistrationsDoc: () => Promise<import("@vue-skuilder/db").CourseRegistrationDoc>;
|
|
145
|
+
getCourseRegDoc: (courseId: string) => Promise<import("@vue-skuilder/db").CourseRegistration>;
|
|
146
|
+
getActiveCourses: () => Promise<import("@vue-skuilder/db").CourseRegistration[]>;
|
|
147
|
+
getPendingReviews: (courseId?: string) => Promise<import("@vue-skuilder/db").ScheduledCard[]>;
|
|
148
|
+
getActivityRecords: () => Promise<import("@vue-skuilder/db").ActivityRecord[]>;
|
|
149
|
+
scheduleCardReview: (review: {
|
|
150
|
+
user: string;
|
|
151
|
+
course_id: string;
|
|
152
|
+
card_id: string;
|
|
153
|
+
time: import("moment").Moment;
|
|
154
|
+
scheduledFor: "course" | "classroom";
|
|
155
|
+
schedulingAgentId: string;
|
|
156
|
+
}) => Promise<void>;
|
|
157
|
+
removeScheduledCardReview: (reviewId: string) => Promise<void>;
|
|
158
|
+
registerForClassroom: (classId: string, registerAs: "student" | "teacher" | "aide" | "admin") => Promise<PouchDB.Core.Response>;
|
|
159
|
+
dropFromClassroom: (classId: string) => Promise<PouchDB.Core.Response>;
|
|
160
|
+
getUserClassrooms: () => Promise<import("@vue-skuilder/db").ClassroomRegistrationDoc>;
|
|
161
|
+
getActiveClasses: () => Promise<string[]>;
|
|
162
|
+
updateUserElo: (courseId: string, elo: import("@vue-skuilder/common").CourseElo) => Promise<PouchDB.Core.Response>;
|
|
163
|
+
getCourseInterface: (courseId: string) => Promise<import("@vue-skuilder/db").UsrCrsDataInterface>;
|
|
164
|
+
update: <T extends PouchDB.Core.Document<object>>(id: string, update: Partial<T> | ((x: T) => T)) => Promise<T>;
|
|
165
|
+
} | undefined;
|
|
166
|
+
loginAndRegistration: {
|
|
167
|
+
init: boolean;
|
|
168
|
+
loggedIn: boolean;
|
|
169
|
+
regDialogOpen: boolean;
|
|
170
|
+
loginDialogOpen: boolean;
|
|
171
|
+
};
|
|
172
|
+
onLoadComplete: boolean;
|
|
173
|
+
} & import("pinia").PiniaCustomStateProperties<AuthState>) => {
|
|
174
|
+
loggedIn: boolean;
|
|
175
|
+
init: boolean;
|
|
176
|
+
user: {
|
|
177
|
+
createAccount: (username: string, password: string) => Promise<{
|
|
178
|
+
status: import("@vue-skuilder/common").Status;
|
|
179
|
+
error: string;
|
|
180
|
+
}>;
|
|
181
|
+
login: (username: string, password: string) => Promise<{
|
|
182
|
+
ok: boolean;
|
|
183
|
+
name?: string;
|
|
184
|
+
roles?: string[];
|
|
185
|
+
}>;
|
|
186
|
+
logout: () => Promise<{
|
|
187
|
+
ok: boolean;
|
|
188
|
+
}>;
|
|
189
|
+
getUsername: () => string;
|
|
190
|
+
isLoggedIn: () => boolean;
|
|
191
|
+
getConfig: () => Promise<import("@vue-skuilder/db").UserConfig>;
|
|
192
|
+
setConfig: (config: Partial<import("@vue-skuilder/db").UserConfig>) => Promise<void>;
|
|
193
|
+
putCardRecord: <T extends import("@vue-skuilder/db").CardRecord>(record: T) => Promise<import("@vue-skuilder/db").CardHistory<import("@vue-skuilder/db").CardRecord>>;
|
|
194
|
+
getSeenCards: (courseId?: string) => Promise<string[]>;
|
|
195
|
+
getActiveCards: () => Promise<string[]>;
|
|
196
|
+
registerForCourse: (courseId: string, previewMode?: boolean) => Promise<PouchDB.Core.Response>;
|
|
197
|
+
dropCourse: (courseId: string, dropStatus?: string) => Promise<PouchDB.Core.Response>;
|
|
198
|
+
getCourseRegistrationsDoc: () => Promise<import("@vue-skuilder/db").CourseRegistrationDoc>;
|
|
199
|
+
getCourseRegDoc: (courseId: string) => Promise<import("@vue-skuilder/db").CourseRegistration>;
|
|
200
|
+
getActiveCourses: () => Promise<import("@vue-skuilder/db").CourseRegistration[]>;
|
|
201
|
+
getPendingReviews: (courseId?: string) => Promise<import("@vue-skuilder/db").ScheduledCard[]>;
|
|
202
|
+
getActivityRecords: () => Promise<import("@vue-skuilder/db").ActivityRecord[]>;
|
|
203
|
+
scheduleCardReview: (review: {
|
|
204
|
+
user: string;
|
|
205
|
+
course_id: string;
|
|
206
|
+
card_id: string;
|
|
207
|
+
time: import("moment").Moment;
|
|
208
|
+
scheduledFor: "course" | "classroom";
|
|
209
|
+
schedulingAgentId: string;
|
|
210
|
+
}) => Promise<void>;
|
|
211
|
+
removeScheduledCardReview: (reviewId: string) => Promise<void>;
|
|
212
|
+
registerForClassroom: (classId: string, registerAs: "student" | "teacher" | "aide" | "admin") => Promise<PouchDB.Core.Response>;
|
|
213
|
+
dropFromClassroom: (classId: string) => Promise<PouchDB.Core.Response>;
|
|
214
|
+
getUserClassrooms: () => Promise<import("@vue-skuilder/db").ClassroomRegistrationDoc>;
|
|
215
|
+
getActiveClasses: () => Promise<string[]>;
|
|
216
|
+
updateUserElo: (courseId: string, elo: import("@vue-skuilder/common").CourseElo) => Promise<PouchDB.Core.Response>;
|
|
217
|
+
getCourseInterface: (courseId: string) => Promise<import("@vue-skuilder/db").UsrCrsDataInterface>;
|
|
218
|
+
update: <T extends PouchDB.Core.Document<object>>(id: string, update: Partial<T> | ((x: T) => T)) => Promise<T>;
|
|
219
|
+
} | undefined;
|
|
220
|
+
};
|
|
221
|
+
}, {
|
|
222
|
+
init(): Promise<void>;
|
|
223
|
+
setLoginDialog(open: boolean): void;
|
|
224
|
+
setRegDialog(open: boolean): void;
|
|
225
|
+
}>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { UserConfig } from '@vue-skuilder/db';
|
|
2
|
+
export declare const useConfigStore: () => import("pinia").Store<"config", {
|
|
3
|
+
config: UserConfig;
|
|
4
|
+
}, {}, {
|
|
5
|
+
updateConfig(newConfig: UserConfig): void;
|
|
6
|
+
updateDarkMode(darkMode: boolean): Promise<void>;
|
|
7
|
+
updateLikesConfetti(likesConfetti: boolean): Promise<void>;
|
|
8
|
+
hydrate(): Promise<void>;
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
resetDefaults(): void;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import 'mousetrap/plugins/global-bind/mousetrap-global-bind.js';
|
|
2
|
+
import { ExtendedKeyboardEvent } from 'mousetrap';
|
|
3
|
+
export interface HotKey extends HotKeyMetaData {
|
|
4
|
+
callback: (e: ExtendedKeyboardEvent, combo: string) => any;
|
|
5
|
+
}
|
|
6
|
+
export interface HotKeyMetaData {
|
|
7
|
+
command: string;
|
|
8
|
+
hotkey: string | string[];
|
|
9
|
+
}
|
|
10
|
+
export declare class SkldrMouseTrap {
|
|
11
|
+
private static _instance;
|
|
12
|
+
private mouseTrap;
|
|
13
|
+
private hotkeys;
|
|
14
|
+
private constructor();
|
|
15
|
+
static get commands(): HotKeyMetaData[];
|
|
16
|
+
/**
|
|
17
|
+
* Add keyboard bindings without resetting existing ones
|
|
18
|
+
* @param hk Single hotkey or array of hotkeys to bind
|
|
19
|
+
*/
|
|
20
|
+
static addBinding(hk: HotKey | HotKey[]): void;
|
|
21
|
+
/**
|
|
22
|
+
* Remove specific keyboard binding(s) without affecting others
|
|
23
|
+
* @param hotkey Single hotkey or array of hotkeys to remove
|
|
24
|
+
*/
|
|
25
|
+
static removeBinding(hotkey: string | string[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* Reset all keyboard bindings
|
|
28
|
+
* @warning Consider using removeBinding() for targeted cleanup instead to avoid affecting other components
|
|
29
|
+
*/
|
|
30
|
+
static reset(): void;
|
|
31
|
+
private static instance;
|
|
32
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vue-skuilder/common-ui",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.1.1",
|
|
7
|
+
"main": "./dist/common-ui.umd.js",
|
|
8
|
+
"module": "./dist/common-ui.es.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/common-ui.es.js",
|
|
14
|
+
"require": "./dist/common-ui.umd.js"
|
|
15
|
+
},
|
|
16
|
+
"./style": "./dist/assets/index.css",
|
|
17
|
+
"./styles": "./dist/assets/index.css"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"src"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "vite build --watch",
|
|
25
|
+
"build": "vite build && yarn build-types",
|
|
26
|
+
"build-types": "tsc --project tsconfig.types.json",
|
|
27
|
+
"lint": "eslint . --fix",
|
|
28
|
+
"lint:check": "eslint .",
|
|
29
|
+
"test:unit": "vitest run",
|
|
30
|
+
"cypress:open": "cypress open --component",
|
|
31
|
+
"cypress:run": "cypress run --component"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@highlightjs/vue-plugin": "^2.1.2",
|
|
35
|
+
"@mdi/font": "^7.3.67",
|
|
36
|
+
"@vue-skuilder/common": "workspace:*",
|
|
37
|
+
"@vue-skuilder/db": "workspace:*",
|
|
38
|
+
"highlight.js": "^11.0.1",
|
|
39
|
+
"marked": "^15.0.6",
|
|
40
|
+
"moment": "^2.29.4",
|
|
41
|
+
"mousetrap": "^1.6.5",
|
|
42
|
+
"pinia": "^2.3.0",
|
|
43
|
+
"vue": "^3.5.13",
|
|
44
|
+
"vuetify": "^3.7.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"vue": "^3.2.0",
|
|
48
|
+
"vuetify": "^3.0.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@cypress/vite-dev-server": "^6.0.3",
|
|
52
|
+
"@types/pouchdb": "^6.4.2",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^8.25.0",
|
|
54
|
+
"@typescript-eslint/parser": "^8.25.0",
|
|
55
|
+
"@vitejs/plugin-vue": "^5.2.1",
|
|
56
|
+
"@vue/eslint-config-typescript": "^14.4.0",
|
|
57
|
+
"cypress": "^14.2.1",
|
|
58
|
+
"cypress-vite": "^1.6.0",
|
|
59
|
+
"eslint": "^9.21.0",
|
|
60
|
+
"eslint-config-prettier": "^10.0.2",
|
|
61
|
+
"eslint-plugin-vue": "^9.32.0",
|
|
62
|
+
"sass": "^1.83.0",
|
|
63
|
+
"typescript": "~5.7.2",
|
|
64
|
+
"vite": "^6.0.9",
|
|
65
|
+
"vitest": "^3.0.5"
|
|
66
|
+
}
|
|
67
|
+
}
|