@capytale/meta-player 0.3.4 → 0.3.5

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.
@@ -1,4 +1,3 @@
1
- import { Button } from "primereact/button";
2
1
  import { Panel } from "primereact/panel";
3
2
  import styles from "./style.module.scss";
4
3
  import { useAppDispatch, useAppSelector } from "../../app/hooks";
@@ -6,8 +5,6 @@ import {
6
5
  selectIsGradingVisible,
7
6
  selectOrientation,
8
7
  selectPedagoTab,
9
- toggleIsGradingVisible,
10
- toggleIsPedagoVisible,
11
8
  } from "../layout/layoutSlice";
12
9
 
13
10
  import "@capytale/capytale-rich-text-editor/style.css";
@@ -24,9 +21,10 @@ import {
24
21
  setIsMPDirty,
25
22
  } from "../activityData/activityDataSlice";
26
23
  import { ChangeEventHandler } from "react";
27
- import settings from "../../settings";
28
24
  import { DivProps } from "react-html-props";
29
- import AnswerSheetEditor from "./AnswerSheetEditor";
25
+ import SharedNotesEditor from "./SharedNotesEditor";
26
+ import { PedagoCommands } from "./PedagoCommands";
27
+ import { PdfEditor } from "./PdfEditor";
30
28
 
31
29
  const Pedago: React.FC<DivProps> = ({ className, ...props }) => {
32
30
  const dispatch = useAppDispatch();
@@ -60,40 +58,7 @@ const Pedago: React.FC<DivProps> = ({ className, ...props }) => {
60
58
  return (
61
59
  // @ts-ignore - Incompatibility for props in TS
62
60
  <div className={classNames(styles.pedago, className)} {...props}>
63
- <div className={styles.pedagoCommands}>
64
- <Button
65
- severity="secondary"
66
- icon="pi pi-times"
67
- rounded
68
- text
69
- aria-label="Masquer les consignes"
70
- tooltip="Masquer les consignes"
71
- tooltipOptions={{
72
- position: "left",
73
- showDelay: settings.TOOLTIP_SHOW_DELAY,
74
- }}
75
- onClick={() => dispatch(toggleIsPedagoVisible())}
76
- />
77
- {/*
78
- <Button
79
- rounded
80
- text
81
- icon="pi pi-times"
82
- label="H"
83
- onClick={() => {
84
- dispatch(
85
- setPedagoTab(
86
- pedagoTab === "instructions" ? "answerSheet" : "instructions",
87
- ),
88
- );
89
- }}
90
- />
91
- */}
92
- <div className={styles.pedagoSeparator}></div>
93
- {(mode === "assignment" || mode === "review") && (
94
- <ShowHideGradingButton />
95
- )}
96
- </div>
61
+ <PedagoCommands />
97
62
  <div
98
63
  className={styles.pedagoContent}
99
64
  data-grading-visible={isGradingVisible}
@@ -101,7 +66,8 @@ const Pedago: React.FC<DivProps> = ({ className, ...props }) => {
101
66
  {!isGradingVisible && (
102
67
  <>
103
68
  {pedagoTab === "instructions" && <InstructionsEditor />}
104
- {pedagoTab === "answerSheet" && <AnswerSheetEditor />}
69
+ {pedagoTab === "sharedNotes" && <SharedNotesEditor />}
70
+ {pedagoTab === "pdf" && <PdfEditor />}
105
71
  </>
106
72
  )}
107
73
  {isGradingVisible && (
@@ -173,11 +139,21 @@ const Pedago: React.FC<DivProps> = ({ className, ...props }) => {
173
139
  size={60}
174
140
  className={styles.pedagoPanel}
175
141
  >
176
- <Panel className={styles.fullSizePanel} header="Consignes">
142
+ <Panel
143
+ className={styles.fullSizePanel}
144
+ header={
145
+ pedagoTab === "instructions"
146
+ ? "Consignes"
147
+ : pedagoTab === "pdf"
148
+ ? "PDF"
149
+ : "Notes partagées"
150
+ }
151
+ >
177
152
  {pedagoTab === "instructions" && <InstructionsEditor />}
178
- {pedagoTab === "answerSheet" && <AnswerSheetEditor />}
153
+ {pedagoTab === "sharedNotes" && <SharedNotesEditor />}
154
+ {pedagoTab === "pdf" && <PdfEditor />}
179
155
  </Panel>
180
- </SplitterPanel>
156
+ </SplitterPanel>,
181
157
  ])}
182
158
  </Splitter>
183
159
  )}
@@ -186,35 +162,4 @@ const Pedago: React.FC<DivProps> = ({ className, ...props }) => {
186
162
  );
187
163
  };
188
164
 
189
- const ShowHideGradingButton: React.FC = () => {
190
- const dispatch = useAppDispatch();
191
- const mode = useAppSelector(selectMode);
192
- const hasGradingOrComments = useAppSelector(selectHasGradingOrComments);
193
- const isGradingVisible = useAppSelector(selectIsGradingVisible);
194
- const tooltip =
195
- hasGradingOrComments || mode === "review"
196
- ? isGradingVisible
197
- ? "Masquer la notation"
198
- : "Afficher la notation"
199
- : "Pas de note";
200
-
201
- return (
202
- <Button
203
- severity="secondary"
204
- icon="pi pi-graduation-cap"
205
- disabled={!(hasGradingOrComments || mode === "review")}
206
- rounded
207
- text={!isGradingVisible || !(hasGradingOrComments || mode === "review")}
208
- aria-label={tooltip}
209
- tooltip={tooltip}
210
- tooltipOptions={{
211
- position: "left",
212
- showDelay: settings.TOOLTIP_SHOW_DELAY,
213
- showOnDisabled: true,
214
- }}
215
- onClick={() => dispatch(toggleIsGradingVisible())}
216
- />
217
- );
218
- };
219
-
220
165
  export default Pedago;
@@ -1,29 +1,114 @@
1
1
  .pedago {
2
- display: grid;
2
+ display: flex;
3
3
  height: 100%;
4
4
  width: 100%;
5
5
  :global(.layout-horizontal) & {
6
- grid-template-columns: 1fr calc(3rem + 8px);
7
- grid-template-rows: 1fr;
6
+ flex-direction: row-reverse;
8
7
  }
9
8
  :global(.layout-vertical) & {
10
- grid-template-rows: calc(3rem + 8px) 1fr;
11
- grid-template-columns: 1fr;
9
+ flex-direction: column;
12
10
  }
13
11
  }
14
12
 
15
13
  .pedagoCommands {
16
14
  flex-direction: column;
17
- padding: 4px;
15
+ flex-shrink: 0;
18
16
  display: flex;
19
- gap: 8px;
20
17
  background-color: var(--surface-200);
21
- :global(.layout-horizontal) & {
22
- grid-column-start: 2;
23
- grid-row-start: 1;
18
+ :global(.layout-horizontal) & > *:first-child {
19
+ background-color: var(--surface-300);
24
20
  }
25
21
  :global(.layout-vertical) & {
26
- flex-direction: row-reverse;
22
+ gap: 8px;
23
+ flex-direction: row;
24
+ align-items: center;
25
+ }
26
+ }
27
+
28
+ .pdfActions {
29
+ padding: 10px 0;
30
+ display: flex;
31
+ :global(.layout-horizontal) & {
32
+ padding-right: 9px;
33
+ }
34
+ }
35
+
36
+ .pedagoHorizontalTabMenu {
37
+ display: flex;
38
+ flex-direction: column;
39
+ overflow-y: auto;
40
+ }
41
+
42
+ .pedagoHorizontalTab {
43
+ display: flex;
44
+ gap: 20px;
45
+ align-items: center;
46
+ justify-content: space-between;
47
+ color: var(--text-color-secondary);
48
+ padding: 0 16px;
49
+ transition: background-color 0.2s;
50
+ user-select: none;
51
+ cursor: pointer;
52
+ &[data-selected="true"] {
53
+ background-color: var(--surface-100);
54
+ color: var(--text-color);
55
+ }
56
+ &:hover,
57
+ &:focus {
58
+ background-color: var(--surface-50);
59
+ }
60
+ & > span {
61
+ padding: 13px 0;
62
+ }
63
+ & > i {
64
+ padding-right: 8px;
65
+ }
66
+ }
67
+
68
+ .dropzone {
69
+ width: 100%;
70
+ height: 100%;
71
+ display: flex;
72
+ flex-direction: column;
73
+ align-items: center;
74
+ justify-content: center;
75
+ padding: 16px;
76
+ cursor: pointer;
77
+ outline: none;
78
+ }
79
+
80
+ .dropzoneRectangle {
81
+ width: 100%;
82
+ height: 100%;
83
+ display: flex;
84
+ flex-direction: column;
85
+ align-items: center;
86
+ justify-content: center;
87
+ flex: 1;
88
+ padding: 20px;
89
+ border: 2px dashed var(--surface-100);
90
+ border-radius: 2px;
91
+ background-color: var(--surface-50);
92
+ color: var(--text-color-secondary);
93
+ cursor: pointer;
94
+ outline: none;
95
+ transition: border-color 0.2s ease-in-out;
96
+
97
+ &[data-is-ficused="true"] {
98
+ border-color: var(--primary-300);
99
+ }
100
+ &[data-is-drag-accept="true"] {
101
+ border-color: var(--green-300);
102
+ }
103
+ &[data-is-drag-reject="true"] {
104
+ border-color: var(--red-300);
105
+ }
106
+ }
107
+
108
+ .smallSelectButton {
109
+ flex-shrink: 0;
110
+ & > * {
111
+ padding: 11px 8px;
27
112
  }
28
113
  }
29
114
 
@@ -70,12 +155,31 @@
70
155
  }
71
156
  }
72
157
 
158
+ .pedagoTabMenu {
159
+ align-self: stretch;
160
+ & > * {
161
+ background-color: transparent;
162
+ flex-wrap: wrap;
163
+ min-height: 100%;
164
+ }
165
+ }
166
+
167
+ .pedagoTab {
168
+ background-color: transparent;
169
+ padding: 4px 1.25rem;
170
+ gap: 16px;
171
+ font-weight: normal;
172
+ border-right: 1px solid var(--surface-300);
173
+ border-radius: 0;
174
+ :global(.p-highlight) & {
175
+ z-index: 1;
176
+ }
177
+ }
178
+
73
179
  .pedagoContent {
180
+ flex-grow: 1;
74
181
  overflow-y: auto;
75
- :global(.layout-horizontal) & {
76
- grid-column-start: 1;
77
- grid-row-start: 1;
78
- }
182
+ text-align: center;
79
183
  }
80
184
 
81
185
  .pedagoFeedbackPanel {
package/src/index.css CHANGED
@@ -33,11 +33,15 @@ body,
33
33
  color-scheme: light;
34
34
  }
35
35
 
36
- .p-splitter-panel:has(> #meta-player-content-cover) {
36
+ .editor-shell {
37
+ text-align: start;
38
+ }
39
+
40
+ .p-splitter-panel:has(> .meta-player-content-cover) {
37
41
  position: relative;
38
42
  }
39
43
 
40
- #meta-player-content-cover {
44
+ .meta-player-content-cover {
41
45
  display: none;
42
46
  width: 100%;
43
47
  height: 100%;
@@ -1,72 +0,0 @@
1
- import { useCapytaleRichTextEditor } from "@capytale/capytale-rich-text-editor";
2
- import { useAppDispatch, useAppSelector } from "../../app/hooks";
3
- import {
4
- selectAnswerSheetContent,
5
- selectMode,
6
- setCanSaveAnswerSheet,
7
- setIsMPDirty,
8
- setLexicalAnswerSheetState,
9
- } from "../activityData/activityDataSlice";
10
- import { forwardRef, useImperativeHandle, useRef } from "react";
11
- import { Toast } from "primereact/toast";
12
- import settings from "../../settings";
13
-
14
- const AnswerSheetEditor: React.FC = forwardRef((_props, ref) => {
15
- const [Editor, getState, _canSave] = useCapytaleRichTextEditor();
16
- const dispatch = useAppDispatch();
17
- const toast = useRef<Toast>(null);
18
- const mode = useAppSelector(selectMode);
19
- const isEditable =
20
- mode === "create" || mode === "assignment" || mode === "review";
21
- const initialEditorState = useAppSelector(selectAnswerSheetContent);
22
- const initialStateOnChangeDone = useRef<boolean>(false);
23
-
24
- useImperativeHandle(ref, () => {
25
- return {
26
- save: async () => {
27
- const state = await getState();
28
- dispatch(setLexicalAnswerSheetState(state.json));
29
- },
30
- };
31
- });
32
-
33
- return (
34
- <>
35
- <Toast position="bottom-right" ref={toast} />
36
- <Editor
37
- placeholderText="Écrivez le contenu initial de la fiche réponse ici..."
38
- initialEditorState={initialEditorState}
39
- jsonSizeLimit={settings.STATEMENT_MAX_SIZE}
40
- onChange={(editorState) => {
41
- dispatch(setLexicalAnswerSheetState(editorState));
42
- if (initialStateOnChangeDone.current) {
43
- dispatch(setIsMPDirty(true));
44
- } else {
45
- initialStateOnChangeDone.current = true;
46
- }
47
- }}
48
- onJsonSizeLimitExceeded={() => {
49
- dispatch(setCanSaveAnswerSheet(false));
50
- toast.current!.show({
51
- summary: "Erreur",
52
- detail: `Le contenu de la fiche réponse est trop volumineux. Veuillez le réduire avant de l'enregistrer.\nPeut-être avez-vous inséré une image trop volumineuse ?`,
53
- severity: "error",
54
- life: 10000,
55
- });
56
- }}
57
- onJsonSizeLimitMet={() => {
58
- dispatch(setCanSaveAnswerSheet(true));
59
- toast.current!.show({
60
- summary: "Succès",
61
- detail: `Le contenu de la fiche réponse ne dépasse plus la taille limite.`,
62
- severity: "success",
63
- life: 4000,
64
- });
65
- }}
66
- isEditable={isEditable}
67
- />
68
- </>
69
- );
70
- });
71
-
72
- export default AnswerSheetEditor;