libf 2 سال پیش
والد
کامیت
59d92de178

+ 3 - 2
src/App.vue

@@ -4,7 +4,7 @@
     <div class="main">
       <SideBar class="sidebar" :auth="auth.signedUser" :global="global"  v-if="control.sidebar.show"></SideBar>
       <div class="mainview" style="width:100vw;height:100vh;display:flex;flex-flow:column nowrap;align-items:center;justify-content:center;">
-         <Calendar style="flex: 1 1 auto; margin:10px;"></Calendar>
+         <Calendar style="flex: 1 1 auto; margin:10px;" :attendees="attendees"></Calendar>
       </div>
     </div>
     <Footer :auth="auth.signedUser" class="footer" v-if="control.footer.show"></Footer>
@@ -40,7 +40,8 @@ export default {
         footer:{
           show: true,
         }
-      }
+      },
+      attendees: ["ids from app","ids from app","ids from app","ids from app","ids from app","ids from app","ids from app"],
     }
   },
   created(){

+ 5 - 0
src/components/calendar/Calendar.js

@@ -33,6 +33,7 @@ export default Vue.component('ToastUICalendar', {
     theme: Object,
     template: Object,
     calendars: Array,
+    attendees: Array,
     notices: Array,
     events: Array,
   },
@@ -85,6 +86,9 @@ export default Vue.component('ToastUICalendar', {
       this.calendarInstance.clear();
       this.calendarInstance.createEvents(value);
     },
+    attendees(value) {
+      this.calendarInstance.setAttendees(value);
+    },
   },
   mounted() {
     this.calendarInstance = new Calendar(this.$refs.container, {
@@ -101,6 +105,7 @@ export default Vue.component('ToastUICalendar', {
       theme: this.theme,
       template: this.template,
       calendars: this.calendars,
+      attendees: this.attendees,
       notices: this.notices,
     });
     this.addEventListeners();

+ 31 - 11
src/components/calendar/Calendar.vue

@@ -20,12 +20,12 @@
       </option>
     </select>
     <div class="buttons">
-      <button
-        type="button"
+      <el-button
+        type="text"
         @click="onClickTodayButton"
       >
         今天
-      </button>
+      </el-button>
       <el-button
         type="text" 
         icon="el-icon-d-arrow-left"
@@ -49,13 +49,16 @@
       :timezone="{ zones }"
       :theme="theme"
       :template="{
-        milestone: getTemplateForMilestone,
-        allday: getTemplateForAllday,
+        xxmilestone: getTemplateForMilestone,
+        xxtask: getTemplateForTask,
+        xxallday: getTemplateForAllday,
+        xxtime: getTemplateForTime,
         monthGridHeader: monthGridHeader,
         monthMoreTitleDate: monthMoreTitleDate,
       }"
       :grid-selection="true"
       :calendars="calendars"
+      :attendees="attendees"
       :notices="notices"
       :events="events"
       @selectDateTime="onSelectDateTime"
@@ -88,6 +91,12 @@ export default {
   components: {
     ToastUICalendar,
   },
+  props: {
+    attendees: {
+      type: Array,
+      default: () => ['*'],
+    },
+  },
   data() {
     return {
       calendars: calendars,
@@ -120,10 +129,10 @@ export default {
           title: '周',
           value: 'week',
         },
-        {
-          title: '天',
-          value: 'day',
-        },
+        // {
+        //   title: '天',
+        //   value: 'day',
+        // },
       ],
       uioption: {
         month: {
@@ -147,6 +156,9 @@ export default {
     },
   },
   watch: {
+    attendees(value) {
+      this.calendarInstance.setAttendees(value);
+    },
     selectedView(newView) {
       this.calendarInstance.changeView(newView);
       this.setDateRangeText();
@@ -176,8 +188,14 @@ export default {
     getTemplateForMilestone(event) {
       return `<span style="color: #fff; background-color: ${event.backgroundColor};">${event.title}</span>`;
     },
+    getTemplateForTask(event) {
+      return `[T] ${event.title}`;
+    },
     getTemplateForAllday(event) {
-      return `[All day] ${event.title}`;
+      return `[A] ${event.title}`;
+    },
+    getTemplateForTime(event) {
+      return `[T] ${event.title}`;
     },
     monthGridHeader(model) {
       const year = parseInt(model.date.split('-')[0], 10);
@@ -214,11 +232,13 @@ export default {
         isAllday: eventData.isAllday,
         start: eventData.start,
         end: eventData.end,
-        category: eventData.isAllday ? 'allday' : 'time',
+        category: eventData.category,
         dueDateClass: '',
         location: eventData.location,
         state: eventData.state,
         isPrivate: eventData.isPrivate,
+        body: eventData.body,
+        attendees: this.attendees,
       };
 
       this.calendarInstance.createEvents([event]);

+ 34 - 27
src/components/calendar/mock-data.js

@@ -1,6 +1,6 @@
 import { TZDate } from './tuical/toastui-calendar';
 
-import { addDate, addHours, subtractDate } from './utils';
+import { addDate, addHours, diffDays, subDate, subtractDate } from './utils';
 
 const today = new TZDate();
 
@@ -29,59 +29,66 @@ const today = new TZDate();
 
 var events = [
   {
-    id: '1',
-    calendarId: '0',
-    title: 'TOAST UI Calendar Study',
-    category: 'time',
+    id: '777',
+    calendarId: 'work',
+    title: '离中考还有 '+diffDays(new TZDate('2023-06-18'), today)+" 天",
+    category: 'milestone',
     start: today,
-    end: addHours(today, 3),
+    end: today,
+    isReadOnly: true,
   },
   {
-    id: '2',
-    calendarId: '0',
-    title: 'Practice',
+    id: '991',
+    calendarId: 'work',
+    title: '测试吐司日历',
+    category: 'time',
+    start: addHours(today, 24),
+    end: addHours(today, 27),
+  },
+  {
+    id: '992',
+    calendarId: 'rest',
+    title: '测试完成',
     category: 'milestone',
-    start: addDate(today, 1),
-    end: addDate(today, 1),
-    isReadOnly: true,
+    start: addDate(today, 5),
+    end: addDate(today, 5),
   },
   {
-    id: '3',
-    calendarId: '3',
-    title: 'FE Workshop',
+    id: '993',
+    calendarId: 'maintain',
+    title: '全天维护',
     category: 'allday',
     start: subtractDate(today, 2),
     end: subtractDate(today, 1),
-    isReadOnly: true,
   },
   {
-    id: '4',
-    calendarId: '0',
-    title: 'Report',
+    id: '994',
+    calendarId: 'work',
+    title: '报表开发',
     category: 'task',
-    start: today,
-    end: addHours(today, 1),
+    start: addHours(today, 48),
+    end: addHours(today, 51),
   },
 ];
 
 var calendars = [
   {
-    id: '0',
-    name: '工作',
+    id: 'work',
+    name: '工作',
     backgroundColor: '#9e5fff',
     borderColor: '#9e5fff',
     dragBackgroundColor: '#9e5fff',
   },
   {
-    id: '1',
-    name: '休息',
+    id: 'rest',
+    name: '休息',
     backgroundColor: '#00a9ff',
     borderColor: '#00a9ff',
     dragBackgroundColor: '#00a9ff',
   },
   {
-    id: '2',
-    name: '维护',
+    id: 'maintain',
+    name: '维护',
     backgroundColor: '#55a9ff',
     borderColor: '#55a9ff',
     dragBackgroundColor: '#55a9ff',

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 33 - 0
src/components/calendar/tuical/toastui-calendar.css


+ 124 - 37
src/components/calendar/tuical/toastui-calendar.mjs

@@ -2289,10 +2289,11 @@ function clearEvents(calendarData) {
   calendarData.idsOfDay = {};
   calendarData.events.clear();
 }
-function createCalendarSlice(calendars = []) {
+function createCalendarSlice(calendars = [], attendees = []) {
   return {
     calendar: {
       calendars,
+      attendees,
       events: createEventCollection(),
       idsOfDay: {}
     }
@@ -2315,6 +2316,9 @@ function createCalendarDispatchers(set) {
     setCalendars: (calendars) => set(produce((state) => {
       state.calendar.calendars = calendars;
     })),
+    setAttendees: (attendees) => set(produce((state) => {
+      state.calendar.attendees = attendees;
+    })),
     setCalendarColor: (calendarId, colorOptions) => set(produce((state) => {
       const calendars = state.calendar.calendars.map((calendar) => {
         if (calendar.id === calendarId) {
@@ -2716,20 +2720,27 @@ const templates = {
   milestoneTitle() {
     return /* @__PURE__ */ h$3("span", {
       className: cls("left-content")
-    }, "Milestone");
+    }, "里程碑");
   },
   task(model) {
-    return `#${model.title}`;
+    const classNames2 = cls("icon", "ic-task");
+    return /* @__PURE__ */ h$3(p$3, null, /* @__PURE__ */ h$3("span", {
+      className: classNames2
+    }), /* @__PURE__ */ h$3("span", {
+      style: {
+        backgroundColor: model.backgroundColor
+      }
+    }, stripTags(model.title)));
   },
   taskTitle() {
     return /* @__PURE__ */ h$3("span", {
       className: cls("left-content")
-    }, "Task");
+    }, "任务");
   },
   alldayTitle() {
     return /* @__PURE__ */ h$3("span", {
       className: cls("left-content")
-    }, "All Day");
+    }, "全天");
   },
   allday(model) {
     return stripTags(model.title);
@@ -2818,7 +2829,7 @@ const templates = {
   },
   timegridDisplayPrimaryTime(props) {
     const { time } = props;
-    return toFormat(time, "hh tt");
+    return toFormat(time, "HH:mm");
   },
   timegridDisplayTime(props) {
     const { time } = props;
@@ -2829,7 +2840,7 @@ const templates = {
     return toFormat(time, format);
   },
   popupIsAllday() {
-    return "All day";
+    return "全天";
   },
   popupStateFree() {
     return "Free";
@@ -2838,13 +2849,26 @@ const templates = {
     return "Busy";
   },
   popupCategory(category) {
+    switch(category){
+    case "milestone":
+      return "里程碑";
+    case "task":
+      return "任务";
+    case "allday":
+      return "全天";
+    case "time":
+      return "时间段";
+    }
     return category;
   },
   titlePlaceholder() {
-    return "Subject";
+    return "标题";
   },
   locationPlaceholder() {
-    return "Location";
+    return "地点";
+  },
+  bodyPlaceholder() {
+    return "备注";
   },
   startDatePlaceholder() {
     return "Start date";
@@ -2853,23 +2877,23 @@ const templates = {
     return "End date";
   },
   popupSave() {
-    return "Save";
+    return "保存";
   },
   popupUpdate() {
-    return "Update";
+    return "保存";
   },
   popupEdit() {
-    return "Edit";
+    return "编辑";
   },
   popupDelete() {
-    return "Delete";
+    return "删除";
   },
   popupDetailTitle({ title }) {
     return title;
   },
   popupDetailDate({ isAllday: isAllday2, start, end }) {
     const dayFormat = "YYYY.MM.DD";
-    const timeFormat = "hh:mm tt";
+    const timeFormat = "HH:mm";
     const detailFormat = `${dayFormat} ${timeFormat}`;
     const startDate = toFormat(start, isAllday2 ? dayFormat : timeFormat);
     const endDateFormat = isSameDate(start, end) ? timeFormat : detailFormat;
@@ -2887,6 +2911,19 @@ const templates = {
   popupDetailState({ state }) {
     return state || "Busy";
   },
+  popupDetailCategory({ category }) {
+    switch(category){
+    case "milestone":
+      return "里程碑";
+    case "task":
+      return "任务";
+    case "allday":
+      return "全天";
+    case "time":
+      return "时间段";
+    }
+    return category;
+  },
   popupDetailRecurrenceRule({ recurrenceRule }) {
     return recurrenceRule;
   },
@@ -3041,7 +3078,7 @@ function createStore(storeCreator2) {
   return internal;
 }
 const storeCreator = (options) => (set) => {
-  return __spreadProps(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, createOptionsSlice(options)), createTemplateSlice(options.template)), createPopupSlice()), createWeekViewLayoutSlice()), createCalendarSlice(options.calendars)), createViewSlice(options.defaultView)), createDndSlice()), createGridSelectionSlice()), {
+  return __spreadProps(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, createOptionsSlice(options)), createTemplateSlice(options.template)), createPopupSlice()), createWeekViewLayoutSlice()), createCalendarSlice(options.calendars, options.attendees)), createViewSlice(options.defaultView)), createDndSlice()), createGridSelectionSlice()), {
     dispatch: {
       options: createOptionsDispatchers(set),
       popup: createPopupDispatchers(set),
@@ -5751,7 +5788,7 @@ function HorizontalEvent({
     onMoveStart(e2);
   };
   const isDotEvent = !isDraggingTarget && currentView === "month" && uiModel.model.category === "time" && isSameDate(uiModel.model.start, uiModel.model.end);
-  const shouldHideResizeHandler = !isDraggableEvent2 || flat || isDraggingTarget || uiModel.exceedRight;
+  const shouldHideResizeHandler = !isDraggableEvent2 || flat || isDraggingTarget || uiModel.exceedRight || uiModel.model.category === "milestone" || uiModel.model.category === "task";
   const containerStyle = getContainerStyle({
     uiModel,
     eventHeight,
@@ -5879,7 +5916,7 @@ function useAlldayGridRowEventMove({ rowStyleInfo, gridPositionFinder }) {
       return null;
     }
     const newColumnIndex = targetEventStartGridX + columnIndex - startGridXRef.current;
-    return newColumnIndex < 0 ? -rowStyleInfo[-newColumnIndex].left : rowStyleInfo[newColumnIndex].left;
+    return newColumnIndex < 0 ? (rowStyleInfo[-newColumnIndex] ? -rowStyleInfo[-newColumnIndex].left : 0) : (rowStyleInfo[newColumnIndex] ? rowStyleInfo[newColumnIndex].left : 0);
   }, [columnIndex, rowStyleInfo, targetEventStartGridX]);
   _$2(() => {
     if (isNil(startGridXRef.current) && isPresent(columnIndex)) {
@@ -6342,9 +6379,12 @@ const classNames$j = {
   locationIcon: cls("icon", "ic-location-b"),
   repeatIcon: cls("icon", "ic-repeat-b"),
   userIcon: cls("icon", "ic-user-b"),
+  attendeesIconB: cls("icon", "ic-attendees-b"),
+  attendeesIcon: cls("icon", "ic-attendees"),
   stateIcon: cls("icon", "ic-state-b"),
   categoryIcon: cls("icon", "ic-category-b"),
-  calendarDotIcon: cls("icon", "calendar-dot")
+  calendarDotIcon: cls("icon", "calendar-dot"),
+  detailAttendees: cls("detail-attendees")
 };
 function EventDetailSectionDetail({ event }) {
   var _a, _b;
@@ -6375,23 +6415,13 @@ function EventDetailSectionDetail({ event }) {
   }))), attendees && /* @__PURE__ */ h$3("div", {
     className: classNames$j.detailItemIndent
   }, /* @__PURE__ */ h$3("span", {
-    className: classNames$j.userIcon
+    className: classNames$j.attendeesIconB
   }), /* @__PURE__ */ h$3("span", {
     className: classNames$j.content
   }, /* @__PURE__ */ h$3(Template, {
     template: "popupDetailAttendees",
     param: event,
     as: "span"
-  }))), state && /* @__PURE__ */ h$3("div", {
-    className: classNames$j.detailItem
-  }, /* @__PURE__ */ h$3("span", {
-    className: classNames$j.stateIcon
-  }), /* @__PURE__ */ h$3("span", {
-    className: classNames$j.content
-  }, /* @__PURE__ */ h$3(Template, {
-    template: "popupDetailState",
-    param: event,
-    as: "span"
   }))), category && /* @__PURE__ */ h$3("div", {
     className: classNames$j.detailItem
   }, /* @__PURE__ */ h$3("span", {
@@ -6590,8 +6620,10 @@ function EventDetailPopup() {
     end = new TZDate(),
     location: location2,
     state,
+    category,
     isReadOnly,
-    isPrivate
+    isPrivate,
+    body,
   } = event;
   const popupArrowPointPosition = {
     top: eventRect.top + eventRect.height / 2,
@@ -6609,6 +6641,8 @@ function EventDetailPopup() {
         isAllday: isAllday2,
         isPrivate,
         eventState: state,
+        eventCategory: category,
+        body,
         popupArrowPointPosition
       });
     } else {
@@ -6725,6 +6759,7 @@ var FormStateActionType = /* @__PURE__ */ ((FormStateActionType2) => {
   FormStateActionType2["setAllday"] = "setAllday";
   FormStateActionType2["setState"] = "setState";
   FormStateActionType2["setCategory"] = "setCategory";
+  FormStateActionType2["setBody"] = "setBody";
   FormStateActionType2["reset"] = "reset";
   return FormStateActionType2;
 })(FormStateActionType || {});
@@ -6735,6 +6770,8 @@ const defaultFormState = {
   isPrivate: false,
   state: "Busy",
   category: "task",
+  attendees: null,
+  body: "",
 };
 function formStateReducer(state, action) {
   switch (action.type) {
@@ -6754,6 +6791,8 @@ function formStateReducer(state, action) {
       return __spreadProps(__spreadValues({}, state), { state: action.state });
     case "setCategory":
       return __spreadProps(__spreadValues({}, state), { category: action.category });
+    case "setBody":
+      return __spreadProps(__spreadValues({}, state), { body: action.body });
     case "reset":
       return __spreadValues(__spreadValues({}, state), defaultFormState);
     default:
@@ -7060,6 +7099,33 @@ function EventCategorySelector({ eventCategory = "task", formStateDispatch }) {
   }));
 }
 
+const classNames$body = {
+  popupSectionItem: cls("popup-section-item", "popup-section-body"),
+  bodyIcon: cls("icon", "ic-body"),
+  content: cls("content")
+};
+
+function BodyInputBox({ body, formStateDispatch }) {
+  const bodyPlaceholder = useStringOnlyTemplate({
+    template: "bodyPlaceholder",
+    defaultValue: "comments"
+  });
+  const handleBodyChange = (e2) => {
+    formStateDispatch({ type: FormStateActionType.setBody, body: e2.currentTarget.value });
+  };
+  return /* @__PURE__ */ h$3(PopupSection, null, /* @__PURE__ */ h$3("div", {
+    className: classNames$body.popupSectionItem
+  }, /* @__PURE__ */ h$3("span", {
+    className: classNames$body.bodyIcon
+  }), /* @__PURE__ */ h$3("input", {
+    name: "body",
+    className: classNames$body.content,
+    placeholder: bodyPlaceholder,
+    value: body,
+    onChange: handleBodyChange
+  })));
+}
+
 const classNames$9 = {
   popupSectionItem: cls("popup-section-item", "popup-section-location"),
   locationIcon: cls("icon", "ic-location"),
@@ -7169,13 +7235,16 @@ function getChanges(event, eventObject) {
 }
 function EventFormPopup() {
   var _a;
-  const { calendars } = useStore(calendarSelector);
+  const { calendars, attendees } = useStore(calendarSelector);
   const { hideAllPopup } = useDispatch("popup");
   const popupParams = useStore(eventFormPopupParamSelector);
   const { start, end, popupArrowPointPosition, close, isCreationPopup, event } = popupParams != null ? popupParams : {};
   const eventBus = useEventBus();
   const formPopupSlot = useFloatingLayer("formPopupSlot");
   const [formState, formStateDispatch] = useFormState((_a = calendars[0]) == null ? void 0 : _a.id);
+  if (!formState.attendees) {
+    formState.attendees = attendees;
+  }
   const datePickerRef = s$2(null);
   const popupContainerRef = s$2(null);
   const [style, setStyle] = y$1({});
@@ -7204,11 +7273,14 @@ function EventFormPopup() {
         type: FormStateActionType.init,
         event: {
           title: popupParams.title,
+          body: popupParams.body,
           location: popupParams.location,
           isAllday: popupParams.isAllday,
           isPrivate: popupParams.isPrivate,
           calendarId: event.calendarId,
-          state: popupParams.eventState
+          state: popupParams.eventState,
+          category: popupParams.eventCategory,
+          attendees: event.attendees,
         }
       });
     }
@@ -7256,8 +7328,8 @@ function EventFormPopup() {
     title: formState.title,
     isPrivate: formState.isPrivate,
     formStateDispatch
-  }), /* @__PURE__ */ h$3(LocationInputBox, {
-    location: formState.location,
+  }), /* @__PURE__ */ h$3(BodyInputBox, {
+    body: formState.body,
     formStateDispatch
   }), /* @__PURE__ */ h$3(DateSelector, {
     start,
@@ -7268,7 +7340,17 @@ function EventFormPopup() {
   }), /* @__PURE__ */ h$3(EventCategorySelector, {
     eventCategory: formState.category,
     formStateDispatch
-  }), /* @__PURE__ */ h$3(ClosePopupButton, {
+  }), /* @__PURE__ */ h$3("div", {
+    className: classNames$j.detailAttendees
+  }, /* @__PURE__ */ h$3("div", {
+    className: classNames$j.attendeesIcon
+  }), /* @__PURE__ */ h$3("span", {
+    className: classNames$j.content
+  }, /* @__PURE__ */ h$3(Template, {
+    template: "popupDetailAttendees",
+    param: formState,
+    as: "span"
+  }))), /* @__PURE__ */ h$3(ClosePopupButton, {
     type: "form",
     close
   }), /* @__PURE__ */ h$3(PopupSection, null, /* @__PURE__ */ h$3(ConfirmPopupButton, null, isCreationPopup ? /* @__PURE__ */ h$3(Template, {
@@ -10598,10 +10680,14 @@ class CalendarCore {
     const { setCalendars } = this.getStoreDispatchers().calendar;
     setCalendars(calendars);
   }
+  setAttendees(attendees) {
+    const { setAttendees } = this.getStoreDispatchers().calendar;
+    setAttendees(attendees);
+  }
   openFormPopup(event) {
     const { showFormPopup } = this.getStoreDispatchers().popup;
     const eventModel = new EventModel(event);
-    const { title, location: location2, start, end, isAllday: isAllday2, isPrivate, state: eventState } = eventModel;
+    const { title, location: location2, start, end, isAllday: isAllday2, isPrivate, state: eventState, category: eventCategory } = eventModel;
     showFormPopup({
       isCreationPopup: true,
       event: eventModel,
@@ -10611,7 +10697,8 @@ class CalendarCore {
       end,
       isAllday: isAllday2,
       isPrivate,
-      eventState
+      eventState,
+      eventCategory,
     });
   }
   clearGridSelections() {

+ 10 - 0
src/components/calendar/utils.js

@@ -24,3 +24,13 @@ export function subtractDate(d, steps) {
 
   return date;
 }
+
+export function diffMilliseconds(d1, d2) {
+  return d1.getTime() - d2.getTime();
+}
+
+export function diffDays(d1, d2) {
+  var ms = diffMilliseconds(d1,d2);
+  var d = ms / 3600000
+  return parseInt(d/24)
+}