touchstudy-core 0.1.171 → 0.1.172

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.
@@ -0,0 +1,4 @@
1
+ declare const useDeviceType: () => {
2
+ isTablet: boolean;
3
+ };
4
+ export default useDeviceType;
@@ -1,6 +1,6 @@
1
1
  import { FormikProps } from "formik";
2
2
  import React, { FC } from "react";
3
- import { TextbookRequest } from "../configs/types";
3
+ import { TextbookDetailResponse, TextbookRequest } from "../configs/types";
4
4
  interface Props extends FormikProps<TextbookRequest> {
5
5
  isCreatedByAdmin?: boolean;
6
6
  isSuperAdminUser: boolean;
@@ -11,6 +11,8 @@ interface Props extends FormikProps<TextbookRequest> {
11
11
  coverImage?: string;
12
12
  disabled?: boolean;
13
13
  ownersDisabled?: boolean;
14
+ handleSaveData: (values: TextbookRequest) => Promise<void>;
15
+ selectedTextbook?: TextbookDetailResponse;
14
16
  onUploadImage: (event: React.ChangeEvent<HTMLInputElement>) => Promise<void>;
15
17
  onChangeTab: (_: React.SyntheticEvent, newValue: number) => void;
16
18
  }
@@ -93,3 +93,5 @@ export declare const CompareTypeOptions: {
93
93
  label: string;
94
94
  value: QuestionAnswerType;
95
95
  }[];
96
+ export declare const SAVE_TIME_INTERVAL_IN_MILLISECONDS: number;
97
+ export declare const SAVE_TIME_MAX_DIFF_IN_MILLISECONDS = 500;
@@ -19,3 +19,8 @@ export declare enum TextbookEditorType {
19
19
  Korea = 1,
20
20
  Math = 2
21
21
  }
22
+ export declare enum PrintStatus {
23
+ Idle = 0,
24
+ Saving = 1,
25
+ Saved = 2
26
+ }
@@ -11,7 +11,7 @@ declare const useTextbookManagement: ({ textbookId, role, onNavigateList }: Prop
11
11
  isAdminSite: boolean;
12
12
  disabledTextbookOwners: boolean;
13
13
  isReadonly: boolean;
14
- isEditable: boolean;
14
+ isEditable: any;
15
15
  isAdmin: any;
16
16
  theme: import("@mui/material").Theme;
17
17
  history: History;
@@ -20,6 +20,7 @@ declare const useTextbookManagement: ({ textbookId, role, onNavigateList }: Prop
20
20
  isSuperAdminUser: any;
21
21
  openDialog: boolean;
22
22
  handleSubmit: (values: TextbookRequest, _formikHelpers: FormikHelpers<TextbookRequest>) => Promise<void>;
23
+ handleSaveData: (values: TextbookRequest) => Promise<void>;
23
24
  selectedTextbook: TextbookDetailResponse | undefined;
24
25
  handleOpenDialog: (item?: any) => void;
25
26
  handleCloseDialog: () => void;
package/dist/index.js CHANGED
@@ -70,6 +70,7 @@ var reactHookForm = require('react-hook-form');
70
70
  var yup$1 = require('@hookform/resolvers/yup');
71
71
  var pi = require('react-icons/pi');
72
72
  var Container = _interopDefault(require('@mui/material/Container'));
73
+ var ai = require('react-icons/ai');
73
74
  var bs = require('react-icons/bs');
74
75
  var Popover = _interopDefault(require('@mui/material/Popover'));
75
76
  var MenuItem = _interopDefault(require('@mui/material/MenuItem'));
@@ -1029,6 +1030,7 @@ var teacher_required = "선생님은 필수입니다";
1029
1030
  var total_users = "총 사용자";
1030
1031
  var added_date = "추가된 날짜";
1031
1032
  var sync_exam_results = "시험 결과 동기화";
1033
+ var sync_textbook_results = "교재 결과 동기화";
1032
1034
  var update_data_fail = "데이터 업데이트 실패";
1033
1035
  var add_students_to_class = "수업에 학생 추가";
1034
1036
  var add_teachers_to_class = "수업에 교사 추가";
@@ -1039,9 +1041,13 @@ var question_management = "질문 관리";
1039
1041
  var student_data = "학생 데이터";
1040
1042
  var problem_number_question_chart = "문제 {{number}}번";
1041
1043
  var are_you_sure_to_sync_exam_results_to_academy = "시험 결과를 아카데미 {{ academyName }}에 동기화하시겠습니까(백그라운드에서 실행되며 시간이 다소 소요됨)";
1044
+ var are_you_sure_to_sync_textbook_results_to_academy = "교재 학습 결과를 아카데미 {{ academyName }}에 동기화하시겠습니까? (백그라운드에서 실행되며 시간이 다소 소요됨)";
1042
1045
  var messages = {
1043
- exam_sessions_are_being_synchronized: "{{ total }} 개의 시험 세션이 동기화되고 있습니다"
1046
+ exam_sessions_are_being_synchronized: "{{ total }} 개의 시험 세션이 동기화되고 있습니다",
1047
+ textbook_sessions_are_being_synchronized: "{{ total }} 개의 교재 학습 세션이 동기화되고 있습니다"
1044
1048
  };
1049
+ var sync_exam = "시험 동기화";
1050
+ var sync_textbook = "교재 동기화";
1045
1051
  var submit = "제출하다";
1046
1052
  var must_select_a_teacher_first = "먼저 교사를 선택해야 합니다";
1047
1053
  var student_grade_is_invalid = "학생 등급은 1에서 12 사이여야 합니다";
@@ -1488,6 +1494,8 @@ var order_matters = "순서 상관 있음";
1488
1494
  var order_does_not_matter = "순서 상관 없음";
1489
1495
  var synonym_processing = "답 이음동의어 처리";
1490
1496
  var compare_type = "비교 유형";
1497
+ var all_changes_saved = "모든 변경 사항이 저장되었습니다";
1498
+ var saving = "절약";
1491
1499
  var textbook_name = "교재 이름";
1492
1500
  var korean_language = "국어";
1493
1501
  var answer_cannot_be_empty = "답변은 비워둘 수 없습니다";
@@ -1534,6 +1542,7 @@ var admin_to_teachers = "관리자에서 교사들에게";
1534
1542
  var teacher_to_teachers = "교사에서 교사들에게";
1535
1543
  var student_required = "학생은 필수입니다";
1536
1544
  var teachers_required = "교사가 필요합니다";
1545
+ var all_changes_are_not_saved_yet = "아직 모든 변경 사항이 저장되지 않았습니다";
1537
1546
  var lang_ko = {
1538
1547
  problem_solving: problem_solving,
1539
1548
  my_story: my_story,
@@ -2213,6 +2222,7 @@ var lang_ko = {
2213
2222
  total_users: total_users,
2214
2223
  added_date: added_date,
2215
2224
  sync_exam_results: sync_exam_results,
2225
+ sync_textbook_results: sync_textbook_results,
2216
2226
  update_data_fail: update_data_fail,
2217
2227
  add_students_to_class: add_students_to_class,
2218
2228
  add_teachers_to_class: add_teachers_to_class,
@@ -2223,7 +2233,10 @@ var lang_ko = {
2223
2233
  student_data: student_data,
2224
2234
  problem_number_question_chart: problem_number_question_chart,
2225
2235
  are_you_sure_to_sync_exam_results_to_academy: are_you_sure_to_sync_exam_results_to_academy,
2236
+ are_you_sure_to_sync_textbook_results_to_academy: are_you_sure_to_sync_textbook_results_to_academy,
2226
2237
  messages: messages,
2238
+ sync_exam: sync_exam,
2239
+ sync_textbook: sync_textbook,
2227
2240
  submit: submit,
2228
2241
  must_select_a_teacher_first: must_select_a_teacher_first,
2229
2242
  student_grade_is_invalid: student_grade_is_invalid,
@@ -2658,6 +2671,8 @@ var lang_ko = {
2658
2671
  order_does_not_matter: order_does_not_matter,
2659
2672
  synonym_processing: synonym_processing,
2660
2673
  compare_type: compare_type,
2674
+ all_changes_saved: all_changes_saved,
2675
+ saving: saving,
2661
2676
  textbook_name: textbook_name,
2662
2677
  korean_language: korean_language,
2663
2678
  answer_cannot_be_empty: answer_cannot_be_empty,
@@ -2703,7 +2718,8 @@ var lang_ko = {
2703
2718
  admin_to_teachers: admin_to_teachers,
2704
2719
  teacher_to_teachers: teacher_to_teachers,
2705
2720
  student_required: student_required,
2706
- teachers_required: teachers_required
2721
+ teachers_required: teachers_required,
2722
+ all_changes_are_not_saved_yet: all_changes_are_not_saved_yet
2707
2723
  };
2708
2724
 
2709
2725
  var problem_solving$1 = "Problem Solving";
@@ -3390,6 +3406,7 @@ var teacher_required$1 = "Teacher is required";
3390
3406
  var total_users$1 = "Total users";
3391
3407
  var added_date$1 = "Added date";
3392
3408
  var sync_exam_results$1 = "Sync exam results";
3409
+ var sync_textbook_results$1 = "Sync textbook results";
3393
3410
  var update_data_fail$1 = "Update data fail";
3394
3411
  var add_students_to_class$1 = "Add students to class";
3395
3412
  var add_teachers_to_class$1 = "Add teachers to class";
@@ -3400,9 +3417,13 @@ var question_management$1 = "Question Management";
3400
3417
  var student_data$1 = "Student Data";
3401
3418
  var problem_number_question_chart$1 = "Q. {{number}}";
3402
3419
  var are_you_sure_to_sync_exam_results_to_academy$1 = "Are you sure to sync exam results to academy \"{{ academyName }}\" (it will run in the background and take a while)";
3420
+ var are_you_sure_to_sync_textbook_results_to_academy$1 = "Are you sure to sync textbook results to academy \"{{ academyName }}\" (it will run in the background and take a while)";
3403
3421
  var messages$1 = {
3404
- exam_sessions_are_being_synchronized: "{{ total }} exam sessions are being synchronized"
3422
+ exam_sessions_are_being_synchronized: "{{ total }} exam sessions are being synchronized",
3423
+ textbook_sessions_are_being_synchronized: "{{ total }} textbook sessions are being synchronized"
3405
3424
  };
3425
+ var sync_exam$1 = "Sync Exam";
3426
+ var sync_textbook$1 = "Sync Textbook";
3406
3427
  var submit$1 = "Submit";
3407
3428
  var must_select_a_teacher_first$1 = "Must select a teacher first";
3408
3429
  var student_grade_is_invalid$1 = "Student grade must be from 1 to 12";
@@ -3850,6 +3871,8 @@ var order_matters$1 = "Order matters";
3850
3871
  var order_does_not_matter$1 = "Order doesn't matter";
3851
3872
  var synonym_processing$1 = "Answer Synonym processing";
3852
3873
  var compare_type$1 = "Compare Type";
3874
+ var all_changes_saved$1 = "All changes saved";
3875
+ var saving$1 = "Saving";
3853
3876
  var textbook_name$1 = "Textbook name";
3854
3877
  var korean_language$1 = "Korean";
3855
3878
  var answer_cannot_be_empty$1 = "Answer cannot be empty";
@@ -3896,6 +3919,7 @@ var admin_to_teachers$1 = "Admin to teachers";
3896
3919
  var teacher_to_teachers$1 = "Teacher to teachers";
3897
3920
  var student_required$1 = "Student is required";
3898
3921
  var teachers_required$1 = "Teachers are required";
3922
+ var all_changes_are_not_saved_yet$1 = "All changes are not saved yet";
3899
3923
  var lang_en = {
3900
3924
  problem_solving: problem_solving$1,
3901
3925
  my_story: my_story$1,
@@ -4576,6 +4600,7 @@ var lang_en = {
4576
4600
  total_users: total_users$1,
4577
4601
  added_date: added_date$1,
4578
4602
  sync_exam_results: sync_exam_results$1,
4603
+ sync_textbook_results: sync_textbook_results$1,
4579
4604
  update_data_fail: update_data_fail$1,
4580
4605
  add_students_to_class: add_students_to_class$1,
4581
4606
  add_teachers_to_class: add_teachers_to_class$1,
@@ -4586,7 +4611,10 @@ var lang_en = {
4586
4611
  student_data: student_data$1,
4587
4612
  problem_number_question_chart: problem_number_question_chart$1,
4588
4613
  are_you_sure_to_sync_exam_results_to_academy: are_you_sure_to_sync_exam_results_to_academy$1,
4614
+ are_you_sure_to_sync_textbook_results_to_academy: are_you_sure_to_sync_textbook_results_to_academy$1,
4589
4615
  messages: messages$1,
4616
+ sync_exam: sync_exam$1,
4617
+ sync_textbook: sync_textbook$1,
4590
4618
  submit: submit$1,
4591
4619
  must_select_a_teacher_first: must_select_a_teacher_first$1,
4592
4620
  student_grade_is_invalid: student_grade_is_invalid$1,
@@ -5022,6 +5050,8 @@ var lang_en = {
5022
5050
  order_does_not_matter: order_does_not_matter$1,
5023
5051
  synonym_processing: synonym_processing$1,
5024
5052
  compare_type: compare_type$1,
5053
+ all_changes_saved: all_changes_saved$1,
5054
+ saving: saving$1,
5025
5055
  textbook_name: textbook_name$1,
5026
5056
  korean_language: korean_language$1,
5027
5057
  answer_cannot_be_empty: answer_cannot_be_empty$1,
@@ -5067,7 +5097,8 @@ var lang_en = {
5067
5097
  admin_to_teachers: admin_to_teachers$1,
5068
5098
  teacher_to_teachers: teacher_to_teachers$1,
5069
5099
  student_required: student_required$1,
5070
- teachers_required: teachers_required$1
5100
+ teachers_required: teachers_required$1,
5101
+ all_changes_are_not_saved_yet: all_changes_are_not_saved_yet$1
5071
5102
  };
5072
5103
 
5073
5104
  i18n__default.use(reactI18next.initReactI18next).init({
@@ -6262,6 +6293,12 @@ var HighSchoolGrade;
6262
6293
  TextbookEditorType[TextbookEditorType["Korea"] = 1] = "Korea";
6263
6294
  TextbookEditorType[TextbookEditorType["Math"] = 2] = "Math";
6264
6295
  })(exports.TextbookEditorType || (exports.TextbookEditorType = {}));
6296
+ var PrintStatus;
6297
+ (function (PrintStatus) {
6298
+ PrintStatus[PrintStatus["Idle"] = 0] = "Idle";
6299
+ PrintStatus[PrintStatus["Saving"] = 1] = "Saving";
6300
+ PrintStatus[PrintStatus["Saved"] = 2] = "Saved";
6301
+ })(PrintStatus || (PrintStatus = {}));
6265
6302
 
6266
6303
  (function (SchoolType) {
6267
6304
  SchoolType[SchoolType["Default"] = 0] = "Default";
@@ -33855,11 +33892,11 @@ var TextbookRow = function TextbookRow(_ref) {
33855
33892
  });
33856
33893
  var _useTranslation = reactI18next.useTranslation(),
33857
33894
  t = _useTranslation.t;
33858
- var isEditable = (!onAcademy || isAdminSite || isSuperAdmin || isSuperAdminUser || !isAdmin && data.isShared && (((_data$createdBy = data.createdBy) === null || _data$createdBy === void 0 ? void 0 : _data$createdBy.id) === (infoUser === null || infoUser === void 0 ? void 0 : infoUser.id) || ((_data$textbookOwners = data.textbookOwners) === null || _data$textbookOwners === void 0 ? void 0 : _data$textbookOwners.some(function (i) {
33895
+ var isEditable = !onAcademy || isAdminSite || isSuperAdmin || isSuperAdminUser || !isAdmin && data.isShared && (((_data$createdBy = data.createdBy) === null || _data$createdBy === void 0 ? void 0 : _data$createdBy.id) === (infoUser === null || infoUser === void 0 ? void 0 : infoUser.id) || ((_data$textbookOwners = data.textbookOwners) === null || _data$textbookOwners === void 0 ? void 0 : _data$textbookOwners.some(function (i) {
33859
33896
  var _infoUser$email, _infoUser$email$trim;
33860
33897
  return (i === null || i === void 0 ? void 0 : i.email.trim().toUpperCase()) === (infoUser === null || infoUser === void 0 ? void 0 : (_infoUser$email = infoUser.email) === null || _infoUser$email === void 0 ? void 0 : (_infoUser$email$trim = _infoUser$email.trim()) === null || _infoUser$email$trim === void 0 ? void 0 : _infoUser$email$trim.toUpperCase()) && (i === null || i === void 0 ? void 0 : i.academyId) === (academy === null || academy === void 0 ? void 0 : academy.id);
33861
- })))) && data.totalUses <= 0;
33862
- var isDeleteAble = !onAcademy || isAdminSite || isSuperAdmin || isSuperAdminUser || !isAdmin && data.isShared && ((_data$createdBy2 = data.createdBy) === null || _data$createdBy2 === void 0 ? void 0 : _data$createdBy2.id) === (infoUser === null || infoUser === void 0 ? void 0 : infoUser.id) && data.totalUses <= 0;
33898
+ })));
33899
+ var isDeleteAble = !onAcademy || isAdminSite || isSuperAdmin || isSuperAdminUser || !isAdmin && data.isShared && ((_data$createdBy2 = data.createdBy) === null || _data$createdBy2 === void 0 ? void 0 : _data$createdBy2.id) === (infoUser === null || infoUser === void 0 ? void 0 : infoUser.id);
33863
33900
  var isSharable = !data.isPublic && data.isShared && onAcademy && (isAdminSite || isSuperAdminUser || !isAdmin && data.createdBy.id === infoUser.id);
33864
33901
  var handleUpdateTextbook = function handleUpdateTextbook() {
33865
33902
  onUpdateTextbook(data);
@@ -34880,10 +34917,10 @@ var useTextbookManagement = function useTextbookManagement(_ref) {
34880
34917
  var isAdminSite = role === exports.Role.Admin;
34881
34918
  var onAcademy = !!(user !== null && user !== void 0 && user.academyDomain);
34882
34919
  var isSuperAdminUser = !!user && user.isSuperAdmin;
34883
- var isEditable = !selectedTextbook || (!onAcademy || isAdminSite || isSuperAdmin || isSuperAdminUser || !isAdmin && selectedTextbook.isShared && (((_selectedTextbook$cre = selectedTextbook.createdBy) === null || _selectedTextbook$cre === void 0 ? void 0 : _selectedTextbook$cre.id) === (user === null || user === void 0 ? void 0 : user.id) || selectedTextbook.textbookOwners.some(function (i) {
34920
+ var isEditable = !selectedTextbook || !onAcademy || isAdminSite || isSuperAdmin || isSuperAdminUser || !isAdmin && selectedTextbook.isShared && (((_selectedTextbook$cre = selectedTextbook.createdBy) === null || _selectedTextbook$cre === void 0 ? void 0 : _selectedTextbook$cre.id) === (user === null || user === void 0 ? void 0 : user.id) || selectedTextbook.textbookOwners.some(function (i) {
34884
34921
  var _user$email, _user$email$trim;
34885
34922
  return i.email.trim().toUpperCase() === (user === null || user === void 0 ? void 0 : (_user$email = user.email) === null || _user$email === void 0 ? void 0 : (_user$email$trim = _user$email.trim()) === null || _user$email$trim === void 0 ? void 0 : _user$email$trim.toUpperCase()) && i.academyId === (academy === null || academy === void 0 ? void 0 : academy.id);
34886
- }))) && selectedTextbook.totalUses <= 0;
34923
+ }));
34887
34924
  var disabledTextbookOwners = !selectedTextbook && isAdmin || selectedTextbook && (!isEditable || isTeacher && ((_selectedTextbook$cre2 = selectedTextbook.createdBy) === null || _selectedTextbook$cre2 === void 0 ? void 0 : _selectedTextbook$cre2.id) !== (user === null || user === void 0 ? void 0 : user.id) || isAdmin && !isSuperAdminUser);
34888
34925
  var handleOpenConfirmDeleteChapterDialog = function handleOpenConfirmDeleteChapterDialog(chapter) {
34889
34926
  setSelectedChapter(chapter);
@@ -34985,6 +35022,24 @@ var useTextbookManagement = function useTextbookManagement(_ref) {
34985
35022
  return Promise.reject(e);
34986
35023
  }
34987
35024
  };
35025
+ var handleSaveData = React.useCallback(function (values) {
35026
+ try {
35027
+ if (!coverImage && !(values !== null && values !== void 0 && values.coverImage)) {
35028
+ return Promise.resolve();
35029
+ }
35030
+ return Promise.resolve(_catch(function () {
35031
+ var coverImg = coverImage || (values === null || values === void 0 ? void 0 : values.coverImage);
35032
+ return Promise.resolve(updateTextbookApi$1(_extends({}, values, {
35033
+ coverImage: coverImg
35034
+ }), (selectedTextbook === null || selectedTextbook === void 0 ? void 0 : selectedTextbook.id) || 0, isSuperAdmin)).then(function () {});
35035
+ }, function (error) {
35036
+ reactToastify.toast.error(getErrorMessage(t, error));
35037
+ throw error;
35038
+ }));
35039
+ } catch (e) {
35040
+ return Promise.reject(e);
35041
+ }
35042
+ }, [coverImage, isSuperAdmin, JSON.stringify(selectedTextbook)]);
34988
35043
  React.useEffect(function () {
34989
35044
  if (!textbookId) return;
34990
35045
  handleGetTextbookDetail();
@@ -35003,6 +35058,7 @@ var useTextbookManagement = function useTextbookManagement(_ref) {
35003
35058
  isSuperAdminUser: isSuperAdminUser,
35004
35059
  openDialog: openDialog,
35005
35060
  handleSubmit: handleSubmit,
35061
+ handleSaveData: handleSaveData,
35006
35062
  selectedTextbook: selectedTextbook,
35007
35063
  handleOpenDialog: handleOpenDialog,
35008
35064
  handleCloseDialog: handleCloseDialog,
@@ -35296,6 +35352,8 @@ var CompareTypeOptions = [{
35296
35352
  label: "synonym_processing",
35297
35353
  value: exports.QuestionAnswerType.SynonymProcessing
35298
35354
  }];
35355
+ var SAVE_TIME_INTERVAL_IN_MILLISECONDS = 60 * 1000;
35356
+ var SAVE_TIME_MAX_DIFF_IN_MILLISECONDS = 500;
35299
35357
 
35300
35358
  var CustomTextbookTab = function CustomTextbookTab(props) {
35301
35359
  var children = props.children,
@@ -38471,7 +38529,7 @@ var TextbookOwnersTab = function TextbookOwnersTab(_ref) {
38471
38529
  }));
38472
38530
  };
38473
38531
 
38474
- var _excluded$n = ["isCreatedByAdmin", "isSuperAdminUser", "isSuperAdmin", "isAdmin", "textbookId", "selected", "coverImage", "disabled", "ownersDisabled", "onChangeTab", "onUploadImage"];
38532
+ var _excluded$n = ["isCreatedByAdmin", "isSuperAdminUser", "isSuperAdmin", "isAdmin", "textbookId", "selected", "coverImage", "disabled", "ownersDisabled", "selectedTextbook", "handleSaveData", "onChangeTab", "onUploadImage"];
38475
38533
  var PreparedTextbookForm = function PreparedTextbookForm(_ref) {
38476
38534
  var isCreatedByAdmin = _ref.isCreatedByAdmin,
38477
38535
  isSuperAdminUser = _ref.isSuperAdminUser,
@@ -38482,6 +38540,8 @@ var PreparedTextbookForm = function PreparedTextbookForm(_ref) {
38482
38540
  coverImage = _ref.coverImage,
38483
38541
  disabled = _ref.disabled,
38484
38542
  ownersDisabled = _ref.ownersDisabled,
38543
+ selectedTextbook = _ref.selectedTextbook,
38544
+ handleSaveData = _ref.handleSaveData,
38485
38545
  onChangeTab = _ref.onChangeTab,
38486
38546
  onUploadImage = _ref.onUploadImage,
38487
38547
  formikProps = _objectWithoutPropertiesLoose(_ref, _excluded$n);
@@ -38490,6 +38550,23 @@ var PreparedTextbookForm = function PreparedTextbookForm(_ref) {
38490
38550
  dirty = formikProps.dirty,
38491
38551
  submitCount = formikProps.submitCount,
38492
38552
  setValues = formikProps.setValues;
38553
+ var theme = material.useTheme();
38554
+ var savedRunRef = React.useRef(Date.now());
38555
+ var runTimeRef = React.useRef(Date.now());
38556
+ var valuesTextbook = React.useRef(null);
38557
+ var isFirstLoad = true;
38558
+ var _React$useState = React__default.useState(PrintStatus.Idle),
38559
+ saveStatus = _React$useState[0],
38560
+ setSaveStatus = _React$useState[1];
38561
+ var timeoutRef = React.useRef(null);
38562
+ var isProcessingRef = React.useRef(false);
38563
+ var pendingValuesRef = React.useRef(null);
38564
+ var _useState = React.useState(),
38565
+ saved = _useState[0],
38566
+ setSaved = _useState[1];
38567
+ var _useState2 = React.useState(),
38568
+ lastEdited = _useState2[0],
38569
+ setLastEdited = _useState2[1];
38493
38570
  React.useEffect(function () {
38494
38571
  var handleBeforeUnload = function handleBeforeUnload(event) {
38495
38572
  var message = i18n.t("are_you_sure_you_want_to_quit_yours_changes_may_not_be_saved");
@@ -38510,9 +38587,100 @@ var PreparedTextbookForm = function PreparedTextbookForm(_ref) {
38510
38587
  var newValues = _resetAllCategoriesAndQuestionTypesBySubject(values, val);
38511
38588
  setValues(newValues);
38512
38589
  };
38590
+ React.useEffect(function () {
38591
+ if (!valuesTextbook.current && isFirstLoad && !_$8.isEqual(values, DEFAULT_TEXTBOOK_REQUEST)) {
38592
+ valuesTextbook.current = _$8.cloneDeep(values);
38593
+ isFirstLoad = false;
38594
+ }
38595
+ }, [values]);
38596
+ var _handleSave = function handleSave(valuesProps) {
38597
+ try {
38598
+ var _temp = _finallyRethrows(function () {
38599
+ return _catch(function () {
38600
+ isProcessingRef.current = true;
38601
+ setSaveStatus(PrintStatus.Saving);
38602
+ var valuesToSave = valuesProps || values;
38603
+ return Promise.resolve(handleSaveData(valuesToSave)).then(function () {
38604
+ valuesTextbook.current = _$8.cloneDeep(valuesToSave);
38605
+ var now = Date.now();
38606
+ savedRunRef.current = now;
38607
+ runTimeRef.current = now;
38608
+ setSaveStatus(PrintStatus.Saved);
38609
+ setSaved(valuesToSave);
38610
+ });
38611
+ }, function (error) {
38612
+ setSaveStatus(PrintStatus.Idle);
38613
+ console.error(error);
38614
+ });
38615
+ }, function (_wasThrown, _result) {
38616
+ isProcessingRef.current = false;
38617
+ if (pendingValuesRef.current) {
38618
+ if (timeoutRef.current) {
38619
+ clearTimeout(timeoutRef.current);
38620
+ }
38621
+ timeoutRef.current = setTimeout(function () {
38622
+ timeoutRef.current = null;
38623
+ var pendingValues = pendingValuesRef.current;
38624
+ if (pendingValues) {
38625
+ _handleSave(pendingValues);
38626
+ pendingValuesRef.current = null;
38627
+ }
38628
+ }, SAVE_TIME_INTERVAL_IN_MILLISECONDS);
38629
+ }
38630
+ if (_wasThrown) throw _result;
38631
+ return _result;
38632
+ });
38633
+ return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
38634
+ } catch (e) {
38635
+ return Promise.reject(e);
38636
+ }
38637
+ };
38638
+ React.useEffect(function () {
38639
+ var now = Date.now();
38640
+ if (valuesTextbook.current && !_$8.isEqual(values, valuesTextbook.current)) setLastEdited(now);
38641
+ if (!_$8.isEmpty(errors) || !valuesTextbook.current || !(selectedTextbook !== null && selectedTextbook !== void 0 && selectedTextbook.id)) return;
38642
+ if (valuesTextbook.current && _$8.isEqual(values, valuesTextbook.current)) return;
38643
+ if (isProcessingRef.current) {
38644
+ pendingValuesRef.current = _$8.cloneDeep(values);
38645
+ return;
38646
+ }
38647
+ var timeSinceLastRun = now - runTimeRef.current;
38648
+ var maxTime = SAVE_TIME_INTERVAL_IN_MILLISECONDS + SAVE_TIME_MAX_DIFF_IN_MILLISECONDS;
38649
+ if (timeSinceLastRun > maxTime) {
38650
+ runTimeRef.current = now;
38651
+ timeSinceLastRun = 0;
38652
+ }
38653
+ if (timeSinceLastRun >= SAVE_TIME_INTERVAL_IN_MILLISECONDS) {
38654
+ if (timeoutRef.current) {
38655
+ clearTimeout(timeoutRef.current);
38656
+ timeoutRef.current = null;
38657
+ pendingValuesRef.current = null;
38658
+ }
38659
+ _handleSave();
38660
+ } else {
38661
+ pendingValuesRef.current = _$8.cloneDeep(values);
38662
+ var intevalTime = SAVE_TIME_INTERVAL_IN_MILLISECONDS - timeSinceLastRun;
38663
+ timeoutRef.current = setTimeout(function () {
38664
+ timeoutRef.current = null;
38665
+ var pendingValues = pendingValuesRef.current;
38666
+ if (pendingValues) {
38667
+ clearTimeout(timeoutRef.current);
38668
+ _handleSave(pendingValues);
38669
+ pendingValuesRef.current = null;
38670
+ }
38671
+ }, intevalTime);
38672
+ }
38673
+ return function () {
38674
+ if (timeoutRef.current) {
38675
+ clearTimeout(timeoutRef.current);
38676
+ }
38677
+ };
38678
+ }, [values, errors]);
38513
38679
  var inforErrors = errors.coverImage || errors.grade || errors.isbn || errors.preparedType || errors.publicationDate || errors.publisher;
38514
38680
  var contentsErrors = errors.chapters;
38515
38681
  var textbookOwnersErrors = errors.textbookOwners;
38682
+ var hasError = !_$8.isEmpty(errors);
38683
+ var isSaved = !lastEdited || _$8.isEqual(values, saved != null ? saved : {});
38516
38684
  return React__default.createElement(formik.Form, null, React__default.createElement(material.Stack, {
38517
38685
  direction: "column",
38518
38686
  gap: 3
@@ -38600,7 +38768,45 @@ var PreparedTextbookForm = function PreparedTextbookForm(_ref) {
38600
38768
  }), React__default.createElement(material.FormLabel, {
38601
38769
  htmlFor: "type",
38602
38770
  className: "text-center"
38603
- }, i18n.t("math"))))), React__default.createElement(material.Box, null, React__default.createElement(material.Button, {
38771
+ }, i18n.t("math"))))), React__default.createElement(material.Stack, {
38772
+ flexDirection: "row",
38773
+ gap: "8px"
38774
+ }, React__default.createElement(material.Stack, {
38775
+ padding: "6px 12px",
38776
+ sx: {
38777
+ transition: "opacity 0.3s ease",
38778
+ opacity: saveStatus === PrintStatus.Idle && isSaved ? 0 : 1,
38779
+ pointerEvents: "none",
38780
+ gap: "8px",
38781
+ flexDirection: "row",
38782
+ justifyContent: "center",
38783
+ alignItems: "center"
38784
+ }
38785
+ }, saveStatus === PrintStatus.Saving && React__default.createElement(ai.AiOutlineLoading3Quarters, {
38786
+ style: {
38787
+ animation: "spin 1s linear infinite"
38788
+ }
38789
+ }), saveStatus === PrintStatus.Saved && isSaved && React__default.createElement(io5.IoCheckmark, null), saveStatus !== PrintStatus.Saving && !isSaved && React__default.createElement(React.Fragment, null, hasError ? React__default.createElement(md.MdError, {
38790
+ color: red[900]
38791
+ }) : React__default.createElement(fa6.FaClockRotateLeft, {
38792
+ size: "14px"
38793
+ })), React__default.createElement(material.Typography, {
38794
+ sx: {
38795
+ color: theme.palette.grey[700],
38796
+ fontSize: "14px",
38797
+ display: "flex",
38798
+ alignItems: "center",
38799
+ gap: 1,
38800
+ "@keyframes spin": {
38801
+ "0%": {
38802
+ transform: "rotate(0deg)"
38803
+ },
38804
+ "100%": {
38805
+ transform: "rotate(360deg)"
38806
+ }
38807
+ }
38808
+ }
38809
+ }, saveStatus === PrintStatus.Saving && i18n.t("saving"), saveStatus === PrintStatus.Saved && isSaved && i18n.t("all_changes_saved"), saveStatus !== PrintStatus.Saving && (selectedTextbook === null || selectedTextbook === void 0 ? void 0 : selectedTextbook.id) && !isSaved && i18n.t("all_changes_are_not_saved_yet"))), React__default.createElement(material.Button, {
38604
38810
  type: "submit",
38605
38811
  sx: {
38606
38812
  width: "fit-content"
@@ -38707,6 +38913,7 @@ var PreparedTextbookView = function PreparedTextbookView(_ref) {
38707
38913
  isSuperAdminUser = _useTextbookManagemen.isSuperAdminUser,
38708
38914
  isAdmin = _useTextbookManagemen.isAdmin,
38709
38915
  coverImage = _useTextbookManagemen.coverImage,
38916
+ handleSaveData = _useTextbookManagemen.handleSaveData,
38710
38917
  selectedTextbook = _useTextbookManagemen.selectedTextbook,
38711
38918
  handleSubmit = _useTextbookManagemen.handleSubmit,
38712
38919
  handleUploadImage = _useTextbookManagemen.handleUploadImage;
@@ -38729,7 +38936,9 @@ var PreparedTextbookView = function PreparedTextbookView(_ref) {
38729
38936
  isAdmin: isAdmin,
38730
38937
  isSuperAdmin: isSuperAdmin,
38731
38938
  selected: selected,
38939
+ handleSaveData: handleSaveData,
38732
38940
  textbookId: textbookId,
38941
+ selectedTextbook: selectedTextbook,
38733
38942
  onChangeTab: handleChangeTab,
38734
38943
  onUploadImage: handleUploadImage,
38735
38944
  coverImage: coverImage,