@team-monolith/cds 1.49.0 → 1.49.2
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/patterns/LexicalEditor/nodes/ProblemSelectNode/ProblemSelectNode.d.ts +18 -13
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/ProblemSelectNode.js +30 -16
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.d.ts +3 -3
- package/dist/patterns/LexicalEditor/nodes/ProblemSelectNode/SelectComponent.js +16 -19
- package/dist/patterns/LexicalEditor/plugins/ComponentPickerMenuPlugin/ComponentPickerMenuPlugin.js +0 -1
- package/package.json +1 -1
|
@@ -4,43 +4,48 @@ export interface ImageProps {
|
|
|
4
4
|
src: string;
|
|
5
5
|
altText: string;
|
|
6
6
|
}
|
|
7
|
-
export interface
|
|
8
|
-
/** 해당 선택지의 정답 유무는 채점하기 전의 학생에게는 노출하지 않습니다. */
|
|
9
|
-
isAnswer?: boolean;
|
|
7
|
+
export interface SelectionWithoutSolution {
|
|
10
8
|
show: {
|
|
11
9
|
image: ImageProps | null;
|
|
12
10
|
text: string;
|
|
13
11
|
};
|
|
14
12
|
value: string;
|
|
15
13
|
}
|
|
16
|
-
export
|
|
17
|
-
|
|
14
|
+
export type Selection = SelectionWithoutSolution & {
|
|
15
|
+
isAnswer: boolean;
|
|
16
|
+
};
|
|
17
|
+
/** 정답이 공개되지 않은 객관식 문제는 다중정답 여부를 전달받기 위해서 서버에서 hasMultipleSolutions를 보내줍니다. */
|
|
18
|
+
export type ProblemSelectPayload = {
|
|
18
19
|
selected: string[];
|
|
19
|
-
hasMultipleAnswers: boolean;
|
|
20
20
|
key?: NodeKey;
|
|
21
|
-
}
|
|
21
|
+
} & ({
|
|
22
|
+
selections: Selection[];
|
|
23
|
+
} | {
|
|
24
|
+
selections: SelectionWithoutSolution[];
|
|
25
|
+
hasMultipleSolutions?: boolean;
|
|
26
|
+
});
|
|
22
27
|
export type SerializedProblemSelectNode = Spread<ProblemSelectPayload, SerializedLexicalNode>;
|
|
23
28
|
/**
|
|
24
29
|
* selections는 Selection타입의 배열로서 객관식 정보를 담고 있습니다. (교사용)
|
|
25
30
|
* selected는 학생이 선택한 답의 value를 담고 있습니다.(학생용)
|
|
26
31
|
*/
|
|
27
32
|
export declare class ProblemSelectNode extends DecoratorNode<ReactNode> {
|
|
28
|
-
__selections: Selection[];
|
|
33
|
+
__selections: Selection[] | SelectionWithoutSolution[];
|
|
29
34
|
__selected: string[];
|
|
30
|
-
|
|
35
|
+
__hasMultipleSolutions: boolean | undefined;
|
|
31
36
|
isInline(): boolean;
|
|
32
37
|
static getType(): string;
|
|
33
|
-
getSelections(): Selection[];
|
|
38
|
+
getSelections(): Selection[] | SelectionWithoutSolution[];
|
|
34
39
|
getSelected(): string[];
|
|
35
|
-
setSelections(selections: Selection[]): void;
|
|
40
|
+
setSelections(selections: Selection[] | SelectionWithoutSolution[]): void;
|
|
36
41
|
setSelected(selected: string[]): void;
|
|
37
42
|
static clone(node: ProblemSelectNode): ProblemSelectNode;
|
|
38
|
-
constructor(selections: Selection[], selected: string[],
|
|
43
|
+
constructor(selections: Selection[] | SelectionWithoutSolution[], selected: string[], hasMultipleSolutions?: boolean, key?: NodeKey);
|
|
39
44
|
createDOM(config: EditorConfig): HTMLElement;
|
|
40
45
|
updateDOM(): boolean;
|
|
41
46
|
static importJSON(serializedNode: SerializedProblemSelectNode): ProblemSelectNode;
|
|
42
47
|
exportJSON(): SerializedProblemSelectNode;
|
|
43
48
|
decorate(): ReactNode;
|
|
44
49
|
}
|
|
45
|
-
export declare function $createProblemSelectNode(
|
|
50
|
+
export declare function $createProblemSelectNode(payload: ProblemSelectPayload): ProblemSelectNode;
|
|
46
51
|
export declare function $isProblemSelectNode(node: LexicalNode | null | undefined): node is ProblemSelectNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { DecoratorNode, } from "lexical";
|
|
3
3
|
import { addClassNamesToElement } from "@lexical/utils";
|
|
4
4
|
import { SelectComponent } from "./SelectComponent";
|
|
5
5
|
/**
|
|
@@ -28,13 +28,13 @@ export class ProblemSelectNode extends DecoratorNode {
|
|
|
28
28
|
self.__selected = selected;
|
|
29
29
|
}
|
|
30
30
|
static clone(node) {
|
|
31
|
-
return new ProblemSelectNode(node.__selections, node.__selected, node.
|
|
31
|
+
return new ProblemSelectNode(node.__selections, node.__selected, node.__hasMultipleSolutions, node.__key);
|
|
32
32
|
}
|
|
33
|
-
constructor(selections, selected,
|
|
33
|
+
constructor(selections, selected, hasMultipleSolutions, key) {
|
|
34
34
|
super(key);
|
|
35
35
|
this.__selections = selections;
|
|
36
36
|
this.__selected = selected;
|
|
37
|
-
this.
|
|
37
|
+
this.__hasMultipleSolutions = hasMultipleSolutions;
|
|
38
38
|
}
|
|
39
39
|
createDOM(config) {
|
|
40
40
|
// Define the DOM element here
|
|
@@ -46,29 +46,43 @@ export class ProblemSelectNode extends DecoratorNode {
|
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
static importJSON(serializedNode) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
if ("hasMultipleSolutions" in serializedNode) {
|
|
50
|
+
return $createProblemSelectNode({
|
|
51
|
+
key: serializedNode.key,
|
|
52
|
+
selections: serializedNode.selections,
|
|
53
|
+
selected: serializedNode.selected,
|
|
54
|
+
hasMultipleSolutions: serializedNode.hasMultipleSolutions,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return $createProblemSelectNode({
|
|
59
|
+
key: serializedNode.key,
|
|
60
|
+
selections: serializedNode.selections,
|
|
61
|
+
selected: serializedNode.selected,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
65
|
exportJSON() {
|
|
58
66
|
return {
|
|
59
|
-
version: 1,
|
|
60
67
|
type: "problem-select",
|
|
68
|
+
version: 1,
|
|
61
69
|
selections: this.__selections,
|
|
62
70
|
selected: this.__selected,
|
|
63
|
-
hasMultipleAnswers: this.__hasMultipleAnswers,
|
|
64
71
|
};
|
|
65
72
|
}
|
|
66
73
|
decorate() {
|
|
67
|
-
return (_jsx(SelectComponent, { selections: this.__selections, selected: this.__selected,
|
|
74
|
+
return (_jsx(SelectComponent, { selections: this.__selections, selected: this.__selected, hasMultipleSolutions: this.__hasMultipleSolutions, nodeKey: this.getKey() }));
|
|
68
75
|
}
|
|
69
76
|
}
|
|
70
|
-
export function $createProblemSelectNode(
|
|
71
|
-
|
|
77
|
+
export function $createProblemSelectNode(payload) {
|
|
78
|
+
if ("hasMultipleSolutions" in payload) {
|
|
79
|
+
const { selections, selected, key, hasMultipleSolutions } = payload;
|
|
80
|
+
return new ProblemSelectNode(selections, selected, hasMultipleSolutions, key);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const { selections, selected, key } = payload;
|
|
84
|
+
return new ProblemSelectNode(selections, selected, undefined, key);
|
|
85
|
+
}
|
|
72
86
|
}
|
|
73
87
|
export function $isProblemSelectNode(node) {
|
|
74
88
|
return node instanceof ProblemSelectNode;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** @jsxImportSource @emotion/react */
|
|
2
2
|
import { NodeKey } from "lexical";
|
|
3
|
-
import { Selection } from "./ProblemSelectNode";
|
|
3
|
+
import { Selection, SelectionWithoutSolution } from "./ProblemSelectNode";
|
|
4
4
|
export declare function SelectComponent(props: {
|
|
5
|
-
selections: Selection[];
|
|
5
|
+
selections: Selection[] | SelectionWithoutSolution[];
|
|
6
6
|
selected: string[];
|
|
7
|
-
|
|
7
|
+
hasMultipleSolutions: boolean | undefined;
|
|
8
8
|
nodeKey: NodeKey;
|
|
9
9
|
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "@emotion/react/jsx-runtime";
|
|
13
2
|
/** @jsxImportSource @emotion/react */
|
|
14
3
|
import { $getNodeByKey } from "lexical";
|
|
15
|
-
import { $isProblemSelectNode } from "./ProblemSelectNode";
|
|
4
|
+
import { $isProblemSelectNode, } from "./ProblemSelectNode";
|
|
16
5
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
17
6
|
import { useContext, useState } from "react";
|
|
18
7
|
import useLexicalEditable from "@lexical/react/useLexicalEditable";
|
|
@@ -24,18 +13,26 @@ import SettingForm from "./SettingForm";
|
|
|
24
13
|
import styled from "@emotion/styled";
|
|
25
14
|
import { LexicalCustomConfigContext } from "../../LexicalCustomConfigContext";
|
|
26
15
|
export function SelectComponent(props) {
|
|
27
|
-
const { selected,
|
|
28
|
-
const { selections, nodeKey } = settingFormProps;
|
|
16
|
+
const { selected, hasMultipleSolutions, selections, nodeKey } = props;
|
|
29
17
|
const [editor] = useLexicalComposerContext();
|
|
30
18
|
const [settingOpen, setSettingOpen] = useState(false);
|
|
31
19
|
const isEditable = useLexicalEditable();
|
|
32
20
|
const { freezeProblemNode, showQuizSolution } = useContext(LexicalCustomConfigContext);
|
|
21
|
+
const showMultipleSolutions = hasMultipleSolutions ||
|
|
22
|
+
selections.flatMap((s) => {
|
|
23
|
+
if ("isAnswer" in s && s.isAnswer) {
|
|
24
|
+
return [s.isAnswer];
|
|
25
|
+
}
|
|
26
|
+
return [];
|
|
27
|
+
}).length > 1;
|
|
33
28
|
// view
|
|
34
29
|
if (!isEditable) {
|
|
35
|
-
return (_jsxs(_Fragment, { children: [
|
|
30
|
+
return (_jsxs(_Fragment, { children: [showMultipleSolutions && (_jsxs(Alert, { children: [_jsx(AlarmWarningFillIcon, { css: css `
|
|
36
31
|
width: 14px;
|
|
37
32
|
height: 14px;
|
|
38
|
-
` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uC81C\uC785\uB2C8\uB2E4."] })), selections.map((selection, index) => (_jsx(SelectBoxView, { index: index + 1, isAnswer: showQuizSolution
|
|
33
|
+
` }), "\uC9C8\uBB38\uC5D0 \uD574\uB2F9\uD558\uB294 \uB2F5\uC744 \uBAA8\uB450 \uACE0\uB974\uB294 \uBB38\uC81C\uC785\uB2C8\uB2E4."] })), selections.map((selection, index) => (_jsx(SelectBoxView, { index: index + 1, isAnswer: showQuizSolution && "isAnswer" in selection
|
|
34
|
+
? selection.isAnswer
|
|
35
|
+
: undefined, isSelected: selected.includes(selection.value), image: selection.show.image, text: selection.show.text, onClick: freezeProblemNode
|
|
39
36
|
? undefined
|
|
40
37
|
: () => {
|
|
41
38
|
const isSelected = selected.includes(selection.value);
|
|
@@ -54,7 +51,7 @@ export function SelectComponent(props) {
|
|
|
54
51
|
if (!$isProblemSelectNode(node)) {
|
|
55
52
|
return;
|
|
56
53
|
}
|
|
57
|
-
if (
|
|
54
|
+
if (showMultipleSolutions) {
|
|
58
55
|
node.setSelected([...selected, selection.value]);
|
|
59
56
|
}
|
|
60
57
|
else {
|
|
@@ -72,9 +69,9 @@ export function SelectComponent(props) {
|
|
|
72
69
|
display: flex;
|
|
73
70
|
flex-direction: column;
|
|
74
71
|
gap: 4px;
|
|
75
|
-
` }, { children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, isAnswer:
|
|
72
|
+
` }, { children: selections.map((selection, index) => (_jsx(SelectBoxEdit, { index: index + 1, isAnswer: "isAnswer" in selection && selection.isAnswer, image: selection.show.image, text: selection.show.text || `${index + 1}번 선택지`, onClick: () => setSettingOpen(true) }, index))) })), _jsx(SquareButton, { size: "small", color: "icon", icon: _jsx(Settings3FillIcon, {}), onClick: () => {
|
|
76
73
|
setSettingOpen(true);
|
|
77
|
-
} })] })), settingOpen && (_jsx(SettingForm,
|
|
74
|
+
} })] })), settingOpen && (_jsx(SettingForm, { selections: selections, nodeKey: nodeKey, onClose: () => setSettingOpen(false) }))] }));
|
|
78
75
|
}
|
|
79
76
|
const Alert = styled.div(({ theme }) => css `
|
|
80
77
|
display: flex;
|