@opendesign-plus-test/components 0.0.1-rc.82 → 0.0.1-rc.83

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.
Files changed (218) hide show
  1. package/dist/chunk-OElCookieNotice.cjs.js +1 -1
  2. package/dist/chunk-OElCookieNotice.es.js +89 -77
  3. package/dist/components/activity/index.d.ts +9 -9
  4. package/dist/components/banner/index.d.ts +6 -6
  5. package/dist/components/events/index.d.ts +20 -20
  6. package/dist/components/header/OHeaderMobile.vue.d.ts +22 -22
  7. package/dist/components/header/components/HeaderNavMobile.vue.d.ts +3 -3
  8. package/dist/components/header/index.d.ts +27 -27
  9. package/dist/components/header-search/index.d.ts +13 -13
  10. package/dist/components/meeting/OMeetingForm.vue.d.ts +2 -0
  11. package/dist/components/meeting/OMeetingPlayback.vue.d.ts +6 -6
  12. package/dist/components/meeting/components/OMeetingPlaybackVideo.vue.d.ts +1 -1
  13. package/dist/components/meeting/index.d.ts +37 -31
  14. package/dist/components/meeting/types.d.ts +3 -0
  15. package/dist/components/search/index.d.ts +11 -11
  16. package/dist/components.cjs.js +35 -35
  17. package/dist/components.css +1 -1
  18. package/dist/components.es.js +6822 -6755
  19. package/dist/treeshaking/components/activity/index.d.ts +9 -9
  20. package/dist/treeshaking/components/banner/index.d.ts +6 -6
  21. package/dist/treeshaking/components/events/index.d.ts +20 -20
  22. package/dist/treeshaking/components/header/OHeaderMobile.vue.d.ts +22 -22
  23. package/dist/treeshaking/components/header/components/HeaderNavMobile.vue.d.ts +3 -3
  24. package/dist/treeshaking/components/header/index.d.ts +27 -27
  25. package/dist/treeshaking/components/header-search/index.d.ts +13 -13
  26. package/dist/treeshaking/components/meeting/OMeetingForm.vue.d.ts +2 -0
  27. package/dist/treeshaking/components/meeting/OMeetingForm.vue.mjs +104 -47
  28. package/dist/treeshaking/components/meeting/OMeetingMyCalendar.css +4 -0
  29. package/dist/treeshaking/components/meeting/OMeetingMyCalendar.vue.mjs +28 -12
  30. package/dist/treeshaking/components/meeting/OMeetingPlayback.vue.d.ts +6 -6
  31. package/dist/treeshaking/components/meeting/components/OMeetingPlaybackVideo.vue.d.ts +1 -1
  32. package/dist/treeshaking/components/meeting/index.d.ts +37 -31
  33. package/dist/treeshaking/components/meeting/types.d.ts +3 -0
  34. package/dist/treeshaking/components/search/index.d.ts +11 -11
  35. package/dist/treeshaking/i18n/en.mjs +6 -0
  36. package/dist/treeshaking/i18n/zh.mjs +8 -2
  37. package/package.json +4 -1
  38. package/dist/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +0 -664
  39. package/dist/treeshaking/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +0 -664
  40. package/docs/design.md +0 -27
  41. package/docs/design_banner.md +0 -41
  42. package/docs/design_section.md +0 -27
  43. package/plugins/css-inject-plugin.ts +0 -37
  44. package/scripts/build.js +0 -17
  45. package/scripts/generate-components-index.js +0 -62
  46. package/src/assets/events/svg-icons/icon-checked.svg +0 -3
  47. package/src/assets/events/svg-icons/icon-competition.svg +0 -7
  48. package/src/assets/events/svg-icons/icon-events.svg +0 -4
  49. package/src/assets/events/svg-icons/icon-release.svg +0 -4
  50. package/src/assets/events/svg-icons/icon-summit.svg +0 -4
  51. package/src/assets/meeting/empty.png +0 -0
  52. package/src/assets/meeting/svg-icons/icon-all.svg +0 -4
  53. package/src/assets/meeting/svg-icons/icon-backward.svg +0 -4
  54. package/src/assets/meeting/svg-icons/icon-calendar.svg +0 -3
  55. package/src/assets/meeting/svg-icons/icon-cancel.svg +0 -4
  56. package/src/assets/meeting/svg-icons/icon-captions.svg +0 -4
  57. package/src/assets/meeting/svg-icons/icon-close-captions.svg +0 -6
  58. package/src/assets/meeting/svg-icons/icon-close-fullscreen.svg +0 -6
  59. package/src/assets/meeting/svg-icons/icon-copy.svg +0 -4
  60. package/src/assets/meeting/svg-icons/icon-create.svg +0 -5
  61. package/src/assets/meeting/svg-icons/icon-delete.svg +0 -7
  62. package/src/assets/meeting/svg-icons/icon-empty.svg +0 -65
  63. package/src/assets/meeting/svg-icons/icon-event.svg +0 -4
  64. package/src/assets/meeting/svg-icons/icon-export.svg +0 -3
  65. package/src/assets/meeting/svg-icons/icon-forward.svg +0 -4
  66. package/src/assets/meeting/svg-icons/icon-fullscreen.svg +0 -6
  67. package/src/assets/meeting/svg-icons/icon-help.svg +0 -3
  68. package/src/assets/meeting/svg-icons/icon-important.svg +0 -4
  69. package/src/assets/meeting/svg-icons/icon-info.svg +0 -3
  70. package/src/assets/meeting/svg-icons/icon-meet.svg +0 -4
  71. package/src/assets/meeting/svg-icons/icon-meeting-message.svg +0 -5
  72. package/src/assets/meeting/svg-icons/icon-meeting.svg +0 -4
  73. package/src/assets/meeting/svg-icons/icon-play.svg +0 -5
  74. package/src/assets/meeting/svg-icons/icon-playing-tip.svg +0 -7
  75. package/src/assets/meeting/svg-icons/icon-playing.svg +0 -5
  76. package/src/assets/meeting/svg-icons/icon-question.svg +0 -4
  77. package/src/assets/meeting/svg-icons/icon-sound.svg +0 -5
  78. package/src/assets/meeting/svg-icons/icon-speaker.svg +0 -3
  79. package/src/assets/meeting/svg-icons/icon-summit.svg +0 -4
  80. package/src/assets/meeting/svg-icons/icon-telligent.svg +0 -3
  81. package/src/assets/meeting/svg-icons/icon-tip.svg +0 -3
  82. package/src/assets/meeting/svg-icons/icon-todo.svg +0 -4
  83. package/src/assets/meeting/transparent.png +0 -0
  84. package/src/assets/styles/element-plus.scss +0 -283
  85. package/src/assets/svg-icons/icon-arrow-left.svg +0 -3
  86. package/src/assets/svg-icons/icon-avatar-line.svg +0 -3
  87. package/src/assets/svg-icons/icon-caret-left.svg +0 -3
  88. package/src/assets/svg-icons/icon-caret-right.svg +0 -3
  89. package/src/assets/svg-icons/icon-chevron-down.svg +0 -3
  90. package/src/assets/svg-icons/icon-chevron-right.svg +0 -3
  91. package/src/assets/svg-icons/icon-chevron-up.svg +0 -3
  92. package/src/assets/svg-icons/icon-close.svg +0 -3
  93. package/src/assets/svg-icons/icon-delete-hover.svg +0 -4
  94. package/src/assets/svg-icons/icon-delete.svg +0 -7
  95. package/src/assets/svg-icons/icon-filter.svg +0 -3
  96. package/src/assets/svg-icons/icon-header-back.svg +0 -3
  97. package/src/assets/svg-icons/icon-header-delete.svg +0 -3
  98. package/src/assets/svg-icons/icon-header-menu.svg +0 -3
  99. package/src/assets/svg-icons/icon-header-person.svg +0 -3
  100. package/src/assets/svg-icons/icon-header-search.svg +0 -4
  101. package/src/assets/svg-icons/icon-image-close.svg +0 -4
  102. package/src/assets/svg-icons/icon-image-upload.svg +0 -3
  103. package/src/assets/svg-icons/icon-image-zoomin.svg +0 -3
  104. package/src/assets/svg-icons/icon-loading.svg +0 -4
  105. package/src/assets/svg-icons/icon-locale.svg +0 -3
  106. package/src/assets/svg-icons/icon-log-off.svg +0 -3
  107. package/src/assets/svg-icons/icon-message.svg +0 -3
  108. package/src/assets/svg-icons/icon-moon.svg +0 -3
  109. package/src/assets/svg-icons/icon-outlink.svg +0 -3
  110. package/src/assets/svg-icons/icon-overview.svg +0 -3
  111. package/src/assets/svg-icons/icon-refresh.svg +0 -3
  112. package/src/assets/svg-icons/icon-search.svg +0 -3
  113. package/src/assets/svg-icons/icon-setting.svg +0 -3
  114. package/src/assets/svg-icons/icon-sun.svg +0 -3
  115. package/src/assets/svg-icons/icon-tips.svg +0 -3
  116. package/src/components/activity/OActivityApproval.vue +0 -868
  117. package/src/components/activity/OActivityForm.vue +0 -548
  118. package/src/components/activity/OActivityMyCalendar.vue +0 -1540
  119. package/src/components/activity/composables/useActivityConfig.ts +0 -141
  120. package/src/components/activity/config.ts +0 -1
  121. package/src/components/activity/index.ts +0 -24
  122. package/src/components/activity/types.ts +0 -95
  123. package/src/components/banner/OBanner.vue +0 -288
  124. package/src/components/banner/OBannerContent.vue +0 -175
  125. package/src/components/banner/index.ts +0 -18
  126. package/src/components/banner/types.ts +0 -39
  127. package/src/components/common/AppAvatar.vue +0 -83
  128. package/src/components/common/ClientOnly.vue +0 -13
  129. package/src/components/common/ContentWrapper.vue +0 -82
  130. package/src/components/common/MoreText.vue +0 -124
  131. package/src/components/common/ThFilter.vue +0 -330
  132. package/src/components/config-provider/OPlusConfigProvider.vue +0 -32
  133. package/src/components/config-provider/index.ts +0 -10
  134. package/src/components/cookie-notice/OCookieNotice.vue +0 -575
  135. package/src/components/cookie-notice/index.ts +0 -10
  136. package/src/components/element-plus/OElCookieNotice.vue +0 -603
  137. package/src/components/element-plus/index.ts +0 -3
  138. package/src/components/events/OEventsApply.vue +0 -509
  139. package/src/components/events/OEventsCalendar.vue +0 -600
  140. package/src/components/events/OEventsList.vue +0 -461
  141. package/src/components/events/config.ts +0 -35
  142. package/src/components/events/index.ts +0 -24
  143. package/src/components/events/types.ts +0 -84
  144. package/src/components/events/utils.ts +0 -9
  145. package/src/components/footer/OFooter.vue +0 -577
  146. package/src/components/footer/index.ts +0 -10
  147. package/src/components/header/OHeader.vue +0 -157
  148. package/src/components/header/OHeaderMobile.vue +0 -184
  149. package/src/components/header/components/HeaderContent.vue +0 -1125
  150. package/src/components/header/components/HeaderNav.vue +0 -278
  151. package/src/components/header/components/HeaderNavMobile.vue +0 -380
  152. package/src/components/header/index.ts +0 -18
  153. package/src/components/header/types.ts +0 -96
  154. package/src/components/header-language-switcher/OHeaderLanguageSwitcher.vue +0 -249
  155. package/src/components/header-language-switcher/index.ts +0 -10
  156. package/src/components/header-search/OHeaderSearch.vue +0 -628
  157. package/src/components/header-search/index.ts +0 -10
  158. package/src/components/header-source-code/OHeaderSourceCode.vue +0 -151
  159. package/src/components/header-source-code/index.ts +0 -10
  160. package/src/components/header-theme/OHeaderTheme.vue +0 -132
  161. package/src/components/header-theme/index.ts +0 -10
  162. package/src/components/header-user/OHeaderUser.vue +0 -249
  163. package/src/components/header-user/index.ts +0 -10
  164. package/src/components/meeting/OMeetingCalendar.vue +0 -943
  165. package/src/components/meeting/OMeetingForm.vue +0 -1131
  166. package/src/components/meeting/OMeetingMyCalendar.vue +0 -1628
  167. package/src/components/meeting/OMeetingPlayback.vue +0 -469
  168. package/src/components/meeting/OMeetingSigCalendar.vue +0 -500
  169. package/src/components/meeting/components/OMeetingCalendarList.vue +0 -626
  170. package/src/components/meeting/components/OMeetingCalendarSelector.vue +0 -213
  171. package/src/components/meeting/components/OMeetingDetail.vue +0 -285
  172. package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +0 -615
  173. package/src/components/meeting/components/OMeetingPlaybackVideo.vue +0 -741
  174. package/src/components/meeting/components/OMeetingSigAside.vue +0 -205
  175. package/src/components/meeting/composables/useMeetingConfig.ts +0 -108
  176. package/src/components/meeting/config.ts +0 -48
  177. package/src/components/meeting/index.ts +0 -45
  178. package/src/components/meeting/types.ts +0 -270
  179. package/src/components/meeting/utils.ts +0 -70
  180. package/src/components/search/OSearchInput.vue +0 -526
  181. package/src/components/search/composables/useImageSearch.ts +0 -157
  182. package/src/components/search/composables/useKeywordHighlight.ts +0 -30
  183. package/src/components/search/composables/useSearchHistory.ts +0 -75
  184. package/src/components/search/index.ts +0 -23
  185. package/src/components/search/internal/HighlightText.vue +0 -37
  186. package/src/components/search/internal/SearchImageInput.vue +0 -498
  187. package/src/components/search/internal/SearchPanel.vue +0 -431
  188. package/src/components/search/types.ts +0 -25
  189. package/src/components/section/OSection.vue +0 -178
  190. package/src/components/section/index.ts +0 -10
  191. package/src/draft/Banner.vue +0 -265
  192. package/src/draft/ButtonCards.vue +0 -106
  193. package/src/draft/Feature.vue +0 -134
  194. package/src/draft/Footer.vue +0 -519
  195. package/src/draft/HorizontalAnchor.vue +0 -165
  196. package/src/draft/ItemSwiper.vue +0 -133
  197. package/src/draft/Logo.vue +0 -141
  198. package/src/draft/LogoCard.vue +0 -75
  199. package/src/draft/LogoV2.vue +0 -19
  200. package/src/draft/MainCard.vue +0 -38
  201. package/src/draft/MultiCard.vue +0 -95
  202. package/src/draft/MultiIconCard.vue +0 -74
  203. package/src/draft/OInfoCard.vue +0 -176
  204. package/src/draft/Process.vue +0 -81
  205. package/src/draft/Section.vue +0 -167
  206. package/src/draft/SingleTabCard.vue +0 -85
  207. package/src/draft/SliderCard.vue +0 -111
  208. package/src/env.d.ts +0 -16
  209. package/src/i18n/en.ts +0 -278
  210. package/src/i18n/index.ts +0 -56
  211. package/src/i18n/zh.ts +0 -268
  212. package/src/index.ts +0 -18
  213. package/src/shared/provide.ts +0 -6
  214. package/src/shims-vue-dompurify-html.d.ts +0 -17
  215. package/src/vue.d.ts +0 -10
  216. package/tsconfig.json +0 -37
  217. package/vite.config.ts +0 -123
  218. package/vite.treeshaking.config.ts +0 -127
@@ -1,1628 +0,0 @@
1
- <script setup lang="ts">
2
- import {
3
- DialogActionT, OButton,
4
- OCollapse,
5
- OCollapseItem,
6
- ODialog,
7
- ODivider,
8
- OIcon,
9
- OIconArrowLeft,
10
- OIconArrowRight,
11
- OIconChevronLeft,
12
- OIconChevronRight,
13
- OLink,
14
- ORadio,
15
- ORadioGroup,
16
- OScroller,
17
- OTag,
18
- useMessage,
19
- } from '@opensig/opendesign';
20
- import { ElCalendar } from 'element-plus';
21
- import { computed, nextTick, onMounted, ref, onUnmounted, watch } from 'vue';
22
- import OMeetingDetail from './components/OMeetingDetail.vue';
23
- import { CalendarDataType, MeetingGroupType, MeetingItemT, PageParamsT } from './types.ts';
24
- import dayjs from 'dayjs';
25
- import { INTERVAL_DAY, INTERVAL_MONTH, INTERVAL_WEEK } from './config.ts';
26
- import { formatDate, getDateNumber } from './utils.ts';
27
- import { useMeetingConfig } from './composables/useMeetingConfig';
28
- import { useDebounceFn } from '@vueuse/core';
29
- import { useScreen } from '@opendesign-plus/composables';
30
- import { Locales } from '@/i18n';
31
- import IconCopy from '~icons/meeting/icon-copy.svg';
32
-
33
- const message = useMessage(null);
34
- const tableLoading = ref(false); // 列表数据加载状态
35
- const currentPage = ref(1); // 分页-当前页
36
- const pageSize = ref(50); // 分页-每页数量
37
- const total = ref<number | null>(null); // 分页-总数
38
- const list = ref<MeetingItemT[]>([]); // 列表数据
39
- const originList = ref<MeetingItemT[]>([]); // 原始数据
40
- const canLoadMore = computed(() => total.value === null || originList.value.length < total.value);
41
- const reloadAll = ref(false); // 是否需要清空数据
42
- const { t, locale, getPointStr, getConfig, getWeekFromDate } = useMeetingConfig();
43
- const isEn = computed(() => locale.value === Locales.EN);
44
-
45
- const props = withDefaults(defineProps<{
46
- cancelSubMeetingRequest: any;
47
- deleteMeetingRequest: any;
48
- getMeetingListRequest: any;
49
- groupType: MeetingGroupType
50
- }>(), {
51
- groupType: MeetingGroupType.SIG,
52
- });
53
-
54
- const dialogLoading = ref(false); // 弹窗按钮状态
55
- const { isPhone } = useScreen();
56
- const expanded = ref<(string | number)[]>([]); // 展开的数据, sub_id 或 id
57
- const emits = defineEmits(['edit']);
58
- // -------------------- 自动加载下一页 --------------------
59
- const nextLoading = ref(false);
60
- const bottomReached = ref(false);
61
-
62
- const getList = async () => {
63
- if (!props.getMeetingListRequest) {
64
- return;
65
- }
66
- if (nextLoading.value) {
67
- return;
68
- }
69
- try {
70
- if (total.value !== null && total.value > 0 && (currentPage.value - 1) * pageSize.value > total.value) {
71
- return;
72
- }
73
- // 当月数据已加载完,手动切换下一月
74
- if (!canLoadMore.value && isPhone.value) {
75
- changeMonth('next-month');
76
- return;
77
- }
78
- tableLoading.value = true;
79
- nextLoading.value = true;
80
- const res = await props.getMeetingListRequest({
81
- page: currentPage.value,
82
- size: pageSize.value,
83
- order_by: 'date',
84
- order_type: 'asc',
85
- month: dayjs(selectedDate.value).format('YYYY-MM'),
86
- } as unknown as PageParamsT);
87
- const tempList = (res.data || [])
88
- .map((item: MeetingItemT) => {
89
- const {
90
- is_cycle,
91
- date,
92
- start,
93
- end,
94
- cycle_sub,
95
- cycle_start_date,
96
- cycle_end_date,
97
- cycle_start,
98
- cycle_end,
99
- cycle_type,
100
- cycle_interval,
101
- cycle_point,
102
- } =
103
- item;
104
- if (is_cycle) {
105
- let timeRange = '';
106
- let cycleType = '';
107
- if (cycle_type === INTERVAL_DAY) {
108
- cycleType = t('meeting.cycleDay');
109
- }
110
- if (cycle_type === INTERVAL_WEEK) {
111
- if (cycle_interval > 1) {
112
- cycleType = t('meeting.cycleWeek.other', [getPointStr(cycle_type, cycle_point), cycle_interval]);
113
- } else {
114
- cycleType = t('meeting.cycleWeek.one', [getPointStr(cycle_type, cycle_point)]);
115
- }
116
- }
117
- if (cycle_type === INTERVAL_MONTH) {
118
- cycleType = t('meeting.cycleMonth', [getPointStr(cycle_type, cycle_point)]);
119
- }
120
- timeRange = t('meeting.cycleMeetingText2', {
121
- startDate: cycle_start_date,
122
- endDate: cycle_end_date,
123
- startTime: cycle_start,
124
- endTime: cycle_end,
125
- cycleType,
126
- });
127
- const obsData = item.obs_data?.filter((v) => v.text_video_url) || [];
128
- return cycle_sub
129
- .filter((v) => {
130
- return (
131
- dayjs(v.date).isBefore(dayjs(selectedDate.value).add(1, 'month').format('YYYY-MM-01')) &&
132
- !dayjs(v.date).isBefore(dayjs(selectedDate.value).format('YYYY-MM-01'))
133
- );
134
- })
135
- .map(({ id: _id, ...sub }) => {
136
- return {
137
- ...item,
138
- ...sub,
139
- timeRange: timeRange,
140
- dateRange: `${ sub.start }-${ sub.end }`,
141
- hasObsData: obsData.find((v) => v.sub_id === sub.sub_id),
142
- time: `${ sub.start }-${ sub.end }`,
143
- isExpired: dayjs(`${ sub.date } ${ sub.start }`).isBefore(dayjs()),
144
- };
145
- });
146
- }
147
- return [
148
- {
149
- ...item,
150
- dateRange: `${ start } - ${ end }`,
151
- timeRange: `${ start } - ${ end }`,
152
- hasObsData: !!item.obs_data?.filter((v) => v.text_video_url)?.length,
153
- time: `${ start }-${ end }`,
154
- isExpired: dayjs(`${ date } ${ start }`).isBefore(dayjs()),
155
- },
156
- ];
157
- })
158
- .flat()
159
- .filter((v: MeetingItemT) => v.date.slice(0, 7) === formatDate(selectedDate.value, 'YYYY-MM-DD').slice(0, 7));
160
- // 如果需要清空,则完全替换
161
- // 如果页码为1,表示第一次加载
162
- // 如果是移动端,则一直往里填充数据
163
- if (reloadAll.value) {
164
- originList.value = res.data || [];
165
- list.value = tempList;
166
- } else {
167
- if (currentPage.value === 1 && !isPhone.value) {
168
- originList.value = res.data || [];
169
- list.value = tempList;
170
- } else {
171
- originList.value = [...originList.value, ...(res.data || [])];
172
- list.value = [...list.value, ...tempList];
173
- }
174
- }
175
- list.value.sort((a, b) => {
176
- if (a.date === b.date) {
177
- return getDateNumber(a.start) > getDateNumber(b.start) ? 1 : -1;
178
- } else {
179
- return dayjs(a.date).isAfter(dayjs(b.date)) ? 1 : -1;
180
- }
181
- });
182
- total.value = res?.total || 0;
183
- nextTick(() => {
184
- getSelectedDate();
185
- // 监听滚动事件以自动加载下一页
186
- if (scrollerRef.value && !isPhone.value) {
187
- updateScroller();
188
- }
189
- });
190
- } finally {
191
- tableLoading.value = false;
192
- nextLoading.value = false;
193
- bottomReached.value = false;
194
- reloadAll.value = false;
195
- }
196
- };
197
-
198
- const load = useDebounceFn(() => {
199
- if (!canLoadMore.value) return;
200
- if (isPhone.value) return;
201
- bottomReached.value = true;
202
- currentPage.value++;
203
- getList();
204
- }, 200);
205
- const handleScroll = useDebounceFn(() => {
206
- if (!canLoadMore.value) return;
207
- if (!isPhone.value) return;
208
- const scrollPosition = window.scrollY || window.pageYOffset;
209
- // 检测是否接近底部
210
- const windowHeight = window.innerHeight;
211
- const docHeight = document.documentElement.scrollHeight;
212
- const distanceToBottom = docHeight - (scrollPosition + windowHeight);
213
- // 当距离底部300px时开始加载
214
- if (distanceToBottom <= 300 && !nextLoading.value) {
215
- bottomReached.value = true;
216
- // 加载下一页
217
- currentPage.value++;
218
- getList();
219
- }
220
- }, 200);
221
- const calcIfAllDeleted = (date: string) => {
222
- const meetingsOfDate = list.value.filter((v) => v.date === date);
223
- return meetingsOfDate.length && meetingsOfDate.every((v) => v.is_delete);
224
- };
225
-
226
- const scrollerScroll = (el: any) => {
227
- const container = el.target;
228
- if (!container) return;
229
- const scrollTop = container.scrollTop; // 已经滚动的距离
230
- const scrollHeight = container.scrollHeight; // 内容总高度
231
- const clientHeight = container.clientHeight; // 容器可视高度
232
- if (scrollTop + clientHeight >= scrollHeight) {
233
- load();
234
- }
235
- };
236
- const updateScroller = () => {
237
- const scrollerContainerEl = scrollerRef.value.getContainerEl();
238
- scrollerContainerEl.addEventListener('scroll', scrollerScroll);
239
- };
240
-
241
- const detailRefs = ref<Record<string, any>>({}); // 会议详情组件实例
242
- const getDetailRefs = (insRef: any, id: number) => {
243
- if (insRef && id) {
244
- detailRefs.value[id] = insRef;
245
- }
246
- };
247
- const copyInfo = async (idx: number | string) => {
248
- const instance = detailRefs.value[idx];
249
- await instance.copyInfo();
250
- message.success({
251
- content: t('common.copySuccess'),
252
- });
253
- };
254
- // -------------------- 取消 --------------------
255
- const cancelVisible = ref(false); // 取消弹窗
256
- const currentRow = ref<MeetingItemT | null>(null); // 当前激活行,用于取消事件
257
- // 打开编辑会议弹窗
258
- const editMeeting = (row: MeetingItemT) => {
259
- emits('edit', row, 'whole');
260
- };
261
- // 打开取消会议弹窗
262
- const cancelMeeting = (row: MeetingItemT) => {
263
- currentRow.value = row;
264
- cancelVisible.value = true;
265
- };
266
- // 确定取消会议
267
- const confirmCancel = async () => {
268
- if (!props.deleteMeetingRequest) {
269
- return;
270
- }
271
- if (!currentRow.value) {
272
- return;
273
- }
274
- try {
275
- dialogLoading.value = true;
276
- const flag = await props.deleteMeetingRequest(currentRow.value.id);
277
- if (typeof flag === 'boolean' && !flag) {
278
- return;
279
- }
280
- cancelVisible.value = false;
281
- message.success({
282
- content: `${ t('meeting.meetingCancel', [currentRow.value.topic]) }`,
283
- });
284
- reloadAll.value = true;
285
- getList();
286
- } finally {
287
- dialogLoading.value = false;
288
- }
289
- };
290
- const handleDialogVisible = ref(false);
291
- const handleDialogType = ref('');
292
- const handleDialogRow = ref<MeetingItemT | null>(null);
293
- const handleOptions = [
294
- {
295
- label: t('meeting.meetingSingle'),
296
- value: 'single',
297
- },
298
- {
299
- label: t('meeting.meetingCycle'),
300
- value: 'whole',
301
- },
302
- ];
303
-
304
- const handleType = ref('single');
305
- const handleItem = (row: MeetingItemT, type: 'edit' | 'cancel') => {
306
- if (row.is_cycle) {
307
- handleDialogRow.value = row;
308
- handleDialogType.value = type;
309
- handleDialogVisible.value = true;
310
- } else {
311
- if (type === 'cancel') {
312
- cancelMeeting(row);
313
- } else {
314
- editMeeting(row);
315
- }
316
- }
317
- };
318
- const cancelHandleItem = () => {
319
- handleDialogVisible.value = false;
320
- handleDialogRow.value = null;
321
- handleDialogType.value = '';
322
- handleType.value = 'single';
323
- };
324
- const confirmHandleItem = async () => {
325
- const row = handleDialogRow.value;
326
- if (!row) {
327
- return;
328
- }
329
- if (handleDialogType.value === 'cancel') {
330
- try {
331
- let flag = undefined;
332
- dialogLoading.value = true;
333
- if (handleType.value === 'single' && row.is_cycle) {
334
- if (!props.cancelSubMeetingRequest) {
335
- return;
336
- }
337
- flag = await props.cancelSubMeetingRequest(row.sub_id);
338
- } else {
339
- if (!props.deleteMeetingRequest) {
340
- return;
341
- }
342
- flag = await props.deleteMeetingRequest(row.id);
343
- }
344
- if (typeof flag === 'boolean' && !flag) {
345
- return;
346
- }
347
- message.success({
348
- content: `${ t('meeting.meetingCancel', [row.topic]) }`,
349
- });
350
- cancelHandleItem();
351
- reloadAll.value = true;
352
- getList();
353
- } finally {
354
- dialogLoading.value = false;
355
- }
356
- } else {
357
- emits('edit', row, handleType.value);
358
- cancelHandleItem();
359
- }
360
- };
361
-
362
- // -------------------- 日历 --------------------
363
- const calendarRef = ref();
364
- const allDateList = computed<string[]>(() => [...new Set(list.value.map((v) => v.date))].sort((a, b) => (dayjs(a).isBefore(dayjs(b)) ? -1 : 1)));
365
- const dateList = computed<string[]>(() =>
366
- [...new Set(list.value.filter((v) => !v.isExpired && !v.is_delete).map((v) => v.date))].sort((a, b) => (dayjs(a).isBefore(dayjs(b)) ? -1 : 1)),
367
- );
368
- const selectedDate = ref();
369
-
370
- const getSelectedDate = () => {
371
- const latest = dateList.value.find((v) => !dayjs(v).isBefore(dayjs(new Date()).format('YYYY-MM-DD')));
372
- if (latest) {
373
- selectedDate.value = latest;
374
- } else if (!selectedDate.value) {
375
- selectedDate.value = dayjs().format('YYYY-MM-DD');
376
- }
377
- calendarRef.value?.pickDay(dayjs(selectedDate.value));
378
- selectedDate.value = dayjs(selectedDate.value).format('YYYY-MM-DD');
379
- // 根据天再计算出需要展开的最近的会议
380
- const needExpand = list.value.find((v) => v.date === selectedDate.value && !v.isExpired && !v.is_delete);
381
- if (needExpand) {
382
- expanded.value = [needExpand.sub_id || needExpand.id];
383
- }
384
- };
385
-
386
- const cellClick = (e: PointerEvent & any, clickable: boolean) => {
387
- if (!clickable || !e.target?.className.includes('date-cell-text')) {
388
- e.stopPropagation();
389
- e.preventDefault();
390
- }
391
- };
392
-
393
- const changeMonth = (val: string) => {
394
- if (!calendarRef.value) return;
395
- currentPage.value = 1;
396
- total.value = null;
397
- window.scrollTo({
398
- top: 0,
399
- behavior: 'smooth',
400
- });
401
- calendarRef.value.selectDate(val);
402
- reloadAll.value = true;
403
- nextTick(() => {
404
- selectedDate.value = dayjs(calendarRef.value.selectedDay).format('YYYY-MM-DD');
405
- getList();
406
- });
407
- };
408
- // -------------------- 列表 --------------------
409
- interface GroupListItemT {
410
- date: string;
411
- list: MeetingItemT[];
412
- }
413
-
414
- const groupList = computed(() => {
415
- return list.value.reduce((prev: GroupListItemT[], cur: MeetingItemT) => {
416
- if (!prev.length) {
417
- return [
418
- {
419
- date: cur.date,
420
- list: [cur],
421
- },
422
- ];
423
- } else {
424
- const last = prev.at(-1);
425
- if (last?.date === cur.date) {
426
- last.list.push(cur);
427
- } else {
428
- prev.push({
429
- date: cur.date,
430
- list: [cur],
431
- });
432
- }
433
- return prev;
434
- }
435
- }, []);
436
- });
437
-
438
- // -------------------- 处理滚动事件 --------------------
439
- const scrollerRef = ref();
440
- watch(
441
- () => selectedDate.value,
442
- () => {
443
- scrollToSelectedDate(selectedDate.value);
444
- },
445
- );
446
- const scrollToSelectedDate = (date: string) => {
447
- const key = dayjs(date).format('YYYY-MM-DD');
448
- const targetEle = document.querySelector(`#group-title-${ key }`);
449
- if (targetEle) {
450
- if (isPhone.value) {
451
- window.scrollTo({
452
- top: (targetEle.parentElement?.offsetTop || 0) - 52,
453
- behavior: 'smooth',
454
- });
455
- } else {
456
- scrollerRef.value?.scrollTo({
457
- top: targetEle.parentElement?.offsetTop || 0,
458
- behavior: 'smooth',
459
- });
460
- }
461
- }
462
- };
463
- onMounted(() => {
464
- getList();
465
- // 添加滚动事件监听
466
- window.addEventListener('scroll', handleScroll);
467
- // 添加resize监听器
468
- window.addEventListener('resize', handleScroll);
469
- });
470
-
471
- onUnmounted(() => {
472
- window.removeEventListener('scroll', handleScroll);
473
- window.removeEventListener('resize', handleScroll);
474
- const scrollerContainerEl = scrollerRef.value?.getContainerEl();
475
- scrollerContainerEl?.removeEventListener('scroll', scrollerScroll);
476
- });
477
-
478
- const formatYearMonth = (date: string) => {
479
- const date2 = dayjs(date ? date : undefined);
480
- if (isEn.value) {
481
- return date2.format('MMMM YYYY');
482
- } else {
483
- return date2.format('YYYY MM月');
484
- }
485
- };
486
- const handleActions = computed<DialogActionT[]>(() => {
487
- return [
488
- {
489
- id: 'confirm',
490
- color: 'primary',
491
- label: t('common.confirm'),
492
- variant: 'solid',
493
- size: 'large',
494
- round: 'pill',
495
- loading: dialogLoading.value,
496
- onClick: () => {
497
- confirmHandleItem();
498
- },
499
- },
500
- {
501
- id: 'cancel',
502
- color: 'primary',
503
- label: t('common.cancel'),
504
- variant: 'outline',
505
- size: 'large',
506
- round: 'pill',
507
- onClick: () => {
508
- cancelHandleItem();
509
- },
510
- },
511
- ];
512
- });
513
- const cancelActions = computed<DialogActionT[]>(() => {
514
- return [
515
- {
516
- id: 'confirm',
517
- color: 'primary',
518
- label: t('common.confirm'),
519
- variant: 'solid',
520
- size: 'large',
521
- round: 'pill',
522
- loading: dialogLoading.value,
523
- onClick: () => {
524
- confirmCancel();
525
- },
526
- },
527
- {
528
- id: 'cancel',
529
- color: 'primary',
530
- label: t('common.cancel'),
531
- variant: 'outline',
532
- size: 'large',
533
- round: 'pill',
534
- onClick: () => {
535
- cancelVisible.value = false;
536
- },
537
- },
538
- ];
539
- });
540
- </script>
541
-
542
- <template>
543
- <div class="o-my-meeting-calendar">
544
- <div class="meeting-list">
545
- <div class="list-calendar-mb">
546
- <span>{{ formatYearMonth(selectedDate) }}</span>
547
- <span>
548
- <OIcon @click="changeMonth('prev-month')"><OIconChevronLeft /></OIcon>
549
- <OIcon @click="changeMonth('next-month')"><OIconChevronRight /></OIcon>
550
- </span>
551
- </div>
552
- <div class="list-calendar">
553
- <ElCalendar ref="calendarRef" v-model="selectedDate">
554
- <template #header>
555
- <span>{{ formatYearMonth(selectedDate) }}</span>
556
- <div>
557
- <OIcon @click="changeMonth('prev-month')">
558
- <OIconChevronLeft />
559
- </OIcon>
560
- <OIcon @click="changeMonth('next-month')">
561
- <OIconChevronRight />
562
- </OIcon>
563
- </div>
564
- </template>
565
- <template #date-cell="{ data }">
566
- <div
567
- @click="(e) => cellClick(e, allDateList.includes(data.day))"
568
- :class="{
569
- 'date-cell': true,
570
- 'is-selected': data.isSelected,
571
- 'is-today': formatDate(data.day) === formatDate(),
572
- clickable: allDateList.includes(data.day),
573
- expired: dayjs(formatDate()).isAfter(dayjs(data.day)),
574
- 'all-deleted': calcIfAllDeleted(data.day),
575
- }"
576
- :style="{
577
- '--dot-bg': `${getConfig(CalendarDataType.MEETING, 'color')}`
578
- }"
579
- >
580
- <div class="date-cell-text">
581
- {{ Number(data.day.split('-')[2]) }}
582
- </div>
583
- </div>
584
- </template>
585
- </ElCalendar>
586
- </div>
587
- <div class="list-wrapper" :class="!list.length ? 'is-empty' : ''">
588
- <OScroller
589
- ref="scrollerRef"
590
- @scrollend="load"
591
- v-if="list.length"
592
- class="scroller-container"
593
- show-type="hover"
594
- >
595
- <div class="list-body">
596
- <OCollapse v-model="expanded" :accordion="isPhone">
597
- <template v-for="(group, idx) in groupList" :key="group.date">
598
- <div class="list-month-change prev-month" v-if="idx === 0" @click="changeMonth('prev-month')">
599
- <OIcon>
600
- <OIconArrowLeft />
601
- </OIcon>
602
- <span>{{ t('meeting.preMonth') }}</span>
603
- </div>
604
- <div class="group-item" :class="idx === groupList.length - 1 && 'last-item'">
605
- <div
606
- :class="{
607
- 'group-bar': true,
608
- 'is-active': dayjs(selectedDate).format('YYYY-MM-DD') === group.date,
609
- 'is-end': group.list.every((row) => row.isExpired),
610
- }"
611
- >
612
- <div class="group-bar-line"></div>
613
- <div class="group-bar-dot"></div>
614
- </div>
615
- <div
616
- :class="{
617
- 'group-title': true,
618
- 'is-end': group.list.every((row) => row.isExpired),
619
- }"
620
- :id="`group-title-${dayjs(new Date(group.date)).format('YYYY-MM-DD')}`"
621
- >
622
- {{ dayjs(group.date).format('MM/DD') }} {{ getWeekFromDate(group.date) }}
623
- </div>
624
- <OCollapseItem
625
- v-for="(row, rowIdx) in group.list"
626
- :key="row.sub_id || row.id"
627
- :value="row.sub_id || row.id"
628
- :class="{
629
- 'last-item': idx === groupList.length - 1 && rowIdx === group.list.length - 1,
630
- 'is-delete': row.is_delete,
631
- 'is-end': row.isExpired,
632
- }"
633
- >
634
- <template #title>
635
- <div class="item-header">
636
- <div class="item-header-left">
637
- <div
638
- class="meeting-icon"
639
- :style="{
640
- backgroundColor: `${row.is_delete ? 'var(--o-color-info4)' : getConfig(CalendarDataType.MEETING, 'color')}`
641
- }"
642
- >
643
- <OIcon>
644
- <component :is="getConfig(CalendarDataType.MEETING, 'icon')" />
645
- </OIcon>
646
- </div>
647
- <div class="header-info">
648
- <div class="meeting-title">
649
- <div v-if="row.is_delete">{{ t('meeting.meetingCancelled') }}</div>
650
- <div class="title-wrapper">
651
- <div class="title-text">{{ row.topic }}</div>
652
- </div>
653
- <div class="tag-wrapper" v-if="row.is_cycle">
654
- <OTag color="primary" variant="outline">{{ t('meeting.cycle') }}</OTag>
655
- </div>
656
- </div>
657
- <div class="meeting-info">
658
- <span>{{ row.dateRange }}</span>
659
- <ODivider direction="v" />
660
- <span>
661
- {{ groupType === MeetingGroupType.GROUP ? t('meeting.groups') : t('meeting.sigs')
662
- }}: {{ row.group_name }}
663
- </span>
664
- </div>
665
- </div>
666
- </div>
667
- <div class="item-header-right" v-if="!row.is_delete">
668
- <OLink
669
- :hover-underline="false"
670
- v-if="!row.isExpired"
671
- target="_blank"
672
- :href="row.join_url"
673
- rel="noopener noreferrer"
674
- >
675
- {{ t('meeting.joinMeeting') }}
676
- <template #suffix>
677
- <OIcon>
678
- <OIconChevronRight></OIconChevronRight>
679
- </OIcon>
680
- </template>
681
- </OLink>
682
- <template v-else>
683
- <OLink
684
- :hover-underline="false"
685
- target="_blank"
686
- v-if="row.etherpad"
687
- :href="row.etherpad"
688
- >
689
- {{ t('meeting.meetingSummary') }}
690
- <template #suffix>
691
- <OIcon>
692
- <OIconChevronRight></OIconChevronRight>
693
- </OIcon>
694
- </template>
695
- </OLink>
696
- <OLink
697
- :hover-underline="false"
698
- target="_blank"
699
- :href="`/${locale}/video/${row.group_name}/${row.mid}/${row.date}`"
700
- v-if="row.hasObsData">
701
- {{ t('meeting.viewRecord') }}
702
- <template #suffix>
703
- <OIcon>
704
- <OIconChevronRight></OIconChevronRight>
705
- </OIcon>
706
- </template>
707
- </OLink>
708
- </template>
709
- </div>
710
- </div>
711
- <OIcon @click.stop="() => copyInfo(row.sub_id || row.id)" class="copy-icon">
712
- <IconCopy />
713
- </OIcon>
714
- </template>
715
- <div class="meeting-detail">
716
- <OMeetingDetail
717
- :show="expanded.includes(row.sub_id || row.id)"
718
- :data="row"
719
- :ref="(insRef) => getDetailRefs(insRef, row.sub_id || row.id)"
720
- from="my"
721
- />
722
- <div class="meeting-btn" v-if="!row.isExpired && !row.is_delete">
723
- <OButton color="normal" variant="text" @click="handleItem(row, 'edit')">
724
- {{ t('meeting.editMeeting') }}
725
- </OButton>
726
- <OButton color="normal" variant="text" @click="handleItem(row, 'cancel')">
727
- {{ t('meeting.cancelMeeting') }}
728
- </OButton>
729
- </div>
730
- </div>
731
- </OCollapseItem>
732
- <div class="height-placeholder"></div>
733
- </div>
734
- <template v-if="idx === groupList.length - 1">
735
- <div class="load-text" v-if="bottomReached">{{ t('common.loading') }}</div>
736
- <div class="list-month-change next-month" @click="changeMonth('next-month')">
737
- <OIcon>
738
- <OIconArrowRight />
739
- </OIcon>
740
- <span>{{ t('meeting.nextMonth') }}</span>
741
- </div>
742
- </template>
743
- </template>
744
- </OCollapse>
745
- </div>
746
- </OScroller>
747
- <slot name="empty" v-else-if="!tableLoading"></slot>
748
- </div>
749
- <ODialog
750
- v-model:visible="handleDialogVisible"
751
- main-class="handle-dialog"
752
- @close="cancelHandleItem"
753
- :actions="handleActions"
754
- >
755
- <template #header>
756
- {{
757
- t('meeting.meetingHandleText', [handleDialogType === 'edit' ? t('meeting.edit') : t('meeting.cancel')])
758
- }}
759
- </template>
760
- <ORadioGroup v-model="handleType">
761
- <ORadio v-for="t in handleOptions" :value="t.value" :key="t.value">{{ t.label }}</ORadio>
762
- </ORadioGroup>
763
- </ODialog>
764
- <ODialog v-model:visible="cancelVisible" main-class="cancel-dialog" :actions="cancelActions">
765
- <template #header>{{ t('meeting.confirmCancel') }}</template>
766
- <div class="dialog-content">{{ t('meeting.confirmCancelDesc', [currentRow?.topic]) }}</div>
767
- </ODialog>
768
- </div>
769
- </div>
770
- </template>
771
-
772
- <style lang="scss">
773
- .o-my-meeting-calendar {
774
- --meeting-card-radius: var(--o-radius-xs);
775
- --meeting-input-radius: var(--o-radius-xs);
776
- --meeting-cell-radius: var(--o-radius-xs);
777
-
778
- .header {
779
- display: flex;
780
- align-items: center;
781
- justify-content: space-between;
782
-
783
- .title {
784
- font-weight: 500;
785
- color: var(--o-color-info1);
786
- @include h2;
787
- }
788
-
789
- .desc {
790
- margin-top: 12px;
791
- color: var(--o-color-info2);
792
- @include tip1;
793
- }
794
- }
795
-
796
- .meeting-list {
797
- display: flex;
798
- flex-wrap: nowrap;
799
- gap: var(--o-gap-4);
800
- height: 100%;
801
- --phone-padding-top: 0;
802
- @include respond('pad_v') {
803
- flex-direction: column;
804
- gap: var(--o-gap-4);
805
- }
806
- @include respond('phone') {
807
- flex-direction: column;
808
- gap: var(--o-gap-3);
809
- --phone-padding-top: 56px;
810
- }
811
-
812
- .o-loading {
813
- .o-layer-mask {
814
- background-color: transparent;
815
- }
816
-
817
- .o-loading-icon {
818
- color: var(--layer-mask);
819
- }
820
- }
821
-
822
- .list-calendar-mb {
823
- display: none;
824
- align-items: center;
825
- justify-content: space-between;
826
- padding: 0 var(--grid--layout-padding);
827
-
828
- span:first-child {
829
- @include display2;
830
- }
831
-
832
- span:last-child {
833
- display: flex;
834
- align-items: center;
835
- }
836
-
837
- .o-icon {
838
- font-size: 24px;
839
- cursor: pointer;
840
-
841
- &:last-child {
842
- margin-left: 24px;
843
- }
844
- }
845
-
846
- @include respond('phone') {
847
- background-color: var(--o-color-fill1);
848
- display: flex;
849
- position: fixed;
850
- height: var(--phone-padding-top);
851
- z-index: 1;
852
- top: var(--layout-header-height);
853
- left: 0;
854
- right: 0;
855
- }
856
- }
857
-
858
- .list-calendar {
859
- flex-shrink: 0;
860
- width: 334px;
861
- background-color: color-mix(in srgb, var(--o-color-control2-light) 40%, transparent);
862
-
863
- @include respond('pad_h') {
864
- .el-calendar {
865
- .el-calendar__body {
866
- padding-left: 12px;
867
- padding-right: 12px;
868
-
869
- .el-calendar-table .date-cell {
870
- height: 40px;
871
- width: 28px;
872
-
873
- .date-cell-text {
874
- line-height: 24px;
875
- @include tip2;
876
- }
877
- }
878
- }
879
- }
880
- }
881
- @include respond('pad_v') {
882
- width: 100%;
883
-
884
- .el-calendar {
885
- .el-calendar__body {
886
- padding-bottom: 0;
887
- }
888
- }
889
- }
890
- @include respond('phone') {
891
- display: none;
892
- }
893
- .el-calendar {
894
- min-height: 460px;
895
- height: calc(100% - 54px);
896
- border-radius: var(--meeting-card-radius);
897
- background-color: transparent;
898
- @include respond('pad_v') {
899
- min-height: fit-content;
900
- }
901
-
902
- .el-calendar__header {
903
- border-bottom: 1px solid var(--o-color-control4);
904
- color: var(--o-color-info1);
905
-
906
- & > span {
907
- font-weight: 500;
908
- @include h1;
909
- }
910
-
911
- & > div {
912
- display: flex;
913
- align-items: center;
914
- gap: var(--o-gap-5);
915
-
916
- .o-icon {
917
- font-size: 24px;
918
- cursor: pointer;
919
-
920
- &:hover {
921
- color: var(--o-color-primary1);
922
- }
923
-
924
- svg path {
925
- fill: currentColor;
926
- }
927
- }
928
- }
929
- }
930
-
931
- .el-calendar__body {
932
- .el-calendar-table {
933
- display: table;
934
-
935
- th {
936
- text-align: left;
937
- border: none;
938
- --o-color-control3-light: transparent;
939
- padding-left: calc(17px - 0.5em);
940
- }
941
-
942
- tr {
943
- --o-color-fill2: transparent;
944
- }
945
-
946
- td {
947
- background-color: transparent !important;
948
- border: none;
949
- text-align: center;
950
- transition: none;
951
- padding: 0;
952
-
953
- .el-calendar-day {
954
- padding: 0;
955
- height: fit-content;
956
- }
957
-
958
- div {
959
- cursor: default !important;
960
- }
961
-
962
- &:hover {
963
- .el-calendar-day {
964
- background-color: transparent;
965
- }
966
- }
967
- }
968
-
969
- .date-cell {
970
- height: 56px;
971
- width: 34px;
972
- position: relative;
973
- cursor: default !important;
974
-
975
- .date-cell-text {
976
- font-size: 14px;
977
- line-height: 34px;
978
- border-radius: var(--meeting-cell-radius);
979
- background-color: var(--o-color-control2-light);
980
- border: 1px solid transparent;
981
- }
982
-
983
- .date-cell-text {
984
- cursor: not-allowed !important;
985
- }
986
-
987
- &.clickable {
988
- .date-cell-text {
989
- cursor: pointer !important;
990
- }
991
-
992
- &:not(.is-selected) {
993
- .date-cell-text:hover {
994
- background-color: var(--o-color-control3-light);
995
- }
996
- }
997
- }
998
-
999
- &::after {
1000
- content: '';
1001
- position: absolute;
1002
- bottom: 5px;
1003
- left: 50%;
1004
- transform: translateX(-50%);
1005
- width: 8px;
1006
- height: 8px;
1007
- border-radius: 50%;
1008
- }
1009
-
1010
- &.is-today {
1011
- .date-cell-text {
1012
- color: var(--o-color-primary1);
1013
- font-weight: bold;
1014
- background-color: var(--o-color-control3-light);
1015
- }
1016
- }
1017
-
1018
- &.is-selected {
1019
- .date-cell-text {
1020
- background-color: var(--o-color-control3-light);
1021
- border: 1px solid var(--o-color-primary1);
1022
- }
1023
- }
1024
-
1025
- &.clickable {
1026
- &::after {
1027
- background-color: var(--dot-bg);
1028
- }
1029
-
1030
- &.expired::after {
1031
- background-color: rgb(var(--o-grey-6));
1032
- }
1033
-
1034
- &.all-deleted::after {
1035
- background-color: rgb(var(--o-grey-6));
1036
- }
1037
- }
1038
- }
1039
-
1040
- }
1041
- }
1042
- }
1043
-
1044
- }
1045
-
1046
- .list-wrapper {
1047
- flex-grow: 1;
1048
- background-color: var(--o-color-fill2);
1049
- --content-height: calc(var(--layout-left-height, 900px) - 4 * var(--o-gap-5) - var(--header-height, 64) * 1px);
1050
-
1051
- @include respond('phone') {
1052
- margin-top: calc(var(--phone-padding-top) - var(--o-gap-4));
1053
- }
1054
- &.is-empty {
1055
- display: flex;
1056
- align-items: center;
1057
- justify-content: center;
1058
- min-height: 600px;
1059
- height: var(--content-height);
1060
- @include respond('<=pad_v') {
1061
- min-height: 200px;
1062
- }
1063
- }
1064
-
1065
-
1066
- .o-scroller {
1067
- .o-scrollbar-rail {
1068
- right: -16px;
1069
- height: 100%;
1070
- }
1071
- }
1072
-
1073
- .scroller-container {
1074
- height: 100%;
1075
- max-height: var(--content-height);
1076
-
1077
- @include respond('phone') {
1078
- max-height: fit-content;
1079
- }
1080
-
1081
- .group-item {
1082
- padding-left: 24px;
1083
- position: relative;
1084
-
1085
- @include respond('phone') {
1086
- padding-left: var(--o-gap-2);
1087
- }
1088
-
1089
- &.last-item {
1090
- flex-grow: 1;
1091
- }
1092
-
1093
- .group-bar {
1094
- position: absolute;
1095
- left: 0;
1096
- width: 16px;
1097
- top: 0;
1098
- bottom: 0;
1099
- overflow: hidden;
1100
-
1101
- --active-color: var(--o-color-primary1);
1102
-
1103
- &::before {
1104
- content: '';
1105
- width: 2px;
1106
- position: absolute;
1107
- top: 0;
1108
- bottom: 0;
1109
- left: 50%;
1110
- transform: translateX(-50%);
1111
- background-color: var(--o-color-control4);
1112
- }
1113
-
1114
- .group-bar-dot {
1115
- width: 16px;
1116
- height: 26px;
1117
- position: relative;
1118
- @include respond('laptop') {
1119
- height: 24px;
1120
- }
1121
- @include respond('pad_h') {
1122
- height: 22px;
1123
- }
1124
- @include respond('<=pad_v') {
1125
- height: 22px;
1126
- }
1127
-
1128
- &::before,
1129
- &::after {
1130
- content: '';
1131
- border-radius: 50%;
1132
- position: absolute;
1133
- top: 50%;
1134
- left: 50%;
1135
- transform: translateY(-50%) translateX(-50%);
1136
- }
1137
-
1138
- &::before {
1139
- width: 16px;
1140
- height: 16px;
1141
- background-color: transparent;
1142
- }
1143
-
1144
- &::after {
1145
- width: 8px;
1146
- height: 8px;
1147
- background-color: var(--active-color);
1148
- }
1149
- }
1150
-
1151
- &.is-active {
1152
- .group-bar-dot {
1153
- &::before {
1154
- background-color: var(--active-color);
1155
- }
1156
-
1157
- &::after {
1158
- background-color: var(--o-color-fill2);
1159
- }
1160
- }
1161
- }
1162
-
1163
- &.is-end {
1164
- --active-color: rgb(222, 222, 227);
1165
- }
1166
- }
1167
-
1168
- .group-title {
1169
- font-weight: 500;
1170
- color: var(--o-color-info1);
1171
- @include text2;
1172
- @include respond('phone') {
1173
- padding-left: var(--o-gap-5);
1174
- }
1175
-
1176
- &.is-end {
1177
- color: var(--o-color-info3);
1178
- }
1179
- }
1180
- }
1181
- }
1182
- }
1183
-
1184
- .list-body {
1185
- height: 100%;
1186
-
1187
- @include respond('phone') {
1188
- height: fit-content;
1189
- padding: var(--o-gap-4) !important;
1190
- }
1191
-
1192
- .list-month-change {
1193
- flex-shrink: 0;
1194
- display: flex;
1195
- align-items: center;
1196
- gap: var(--o-gap-5);
1197
- cursor: pointer;
1198
- --btn-color: var(--o-color-primary1);
1199
- @include hover {
1200
- --btn-color: var(--o-color-primary2);
1201
- }
1202
-
1203
- @include respond('phone') {
1204
- display: none;
1205
- }
1206
-
1207
- &.prev-month {
1208
- margin-bottom: var(--o-gap-6);
1209
- @include respond('<=laptop') {
1210
- margin-bottom: var(--o-gap-5);
1211
- }
1212
- @include respond('<=pad_v') {
1213
- margin-bottom: var(--o-gap-4);
1214
- }
1215
- }
1216
-
1217
- &.next-month {
1218
- margin-top: var(--o-gap-6);
1219
- padding-bottom: var(--o-gap-6);
1220
- @include respond('<=laptop') {
1221
- margin-top: var(--o-gap-5);
1222
- }
1223
- @include respond('<=pad_v') {
1224
- margin-top: var(--o-gap-4);
1225
- padding-bottom: 0;
1226
- }
1227
- }
1228
-
1229
- .o-icon {
1230
- font-size: 24px;
1231
- color: var(--btn-color);
1232
- }
1233
-
1234
- span {
1235
- color: var(--btn-color);
1236
- @include text1;
1237
- }
1238
- }
1239
-
1240
- .o-collapse {
1241
- padding: 0;
1242
- border-radius: 0;
1243
- height: 100%;
1244
- display: flex;
1245
- flex-direction: column;
1246
-
1247
- .o-collapse-item-expanded + .o-collapse-item-expanded {
1248
- margin-top: var(--o-gap-4);
1249
- }
1250
-
1251
- .height-placeholder {
1252
- height: var(--o-gap-4);
1253
- }
1254
-
1255
-
1256
- .o-collapse-item {
1257
- padding: var(--o-gap-4) var(--o-gap-5);
1258
- border-top: none;
1259
- border-radius: var(--meeting-card-radius);
1260
- transition: margin var(--o-easing-standard) var(--o-duration-s);
1261
- --icon-size: 24px;
1262
- @include respond('pad_h') {
1263
- padding: var(--o-gap-3) var(--o-gap-4);
1264
- }
1265
- @include respond('<=pad_v') {
1266
- padding: var(--o-gap-2) var(--o-gap-4);
1267
- }
1268
-
1269
- @include respond('phone') {
1270
- --icon-size: 20px;
1271
- }
1272
-
1273
- &.o-collapse-item-expanded {
1274
- margin-top: var(--o-gap-4);
1275
- @include respond('<=laptop') {
1276
- margin-top: var(--o-gap-3);
1277
- }
1278
- @include respond('<=pad_v') {
1279
- margin-top: var(--o-gap-2);
1280
- }
1281
- }
1282
-
1283
- &:hover {
1284
- .title-text {
1285
- color: var(--o-color-primary1);
1286
- }
1287
-
1288
- .o-collapse-item-title {
1289
- .copy-icon {
1290
- opacity: 1;
1291
- visibility: visible;
1292
- }
1293
- }
1294
- }
1295
-
1296
- &.last-item {
1297
- .o-collapse-item-header {
1298
- border-bottom: none;
1299
- }
1300
- }
1301
-
1302
- &.is-delete,
1303
- &.is-end {
1304
-
1305
- .meeting-title {
1306
- color: var(--o-color-info4);
1307
-
1308
- .title-text {
1309
- color: var(--o-color-info4);
1310
- }
1311
- }
1312
- }
1313
-
1314
- &.o-collapse-item-expanded {
1315
- border-bottom: none;
1316
- background-color: color-mix(in srgb, var(--o-color-control2-light) 40%, transparent) !important;
1317
-
1318
- .o-collapse-item-header {
1319
- padding-bottom: var(--o-gap-2);
1320
- position: relative;
1321
-
1322
- &::after {
1323
- content: '';
1324
- position: absolute;
1325
- left: calc(var(--o-gap-3) + var(--icon-size));
1326
- right: 0;
1327
- bottom: 0;
1328
- height: 1px;
1329
- background-color: var(--o-color-control4);
1330
- @include respond('phone') {
1331
- left: 0;
1332
- }
1333
- }
1334
-
1335
- .o-collapse-item-title {
1336
- .copy-icon {
1337
- opacity: 1;
1338
- visibility: visible;
1339
- }
1340
- }
1341
- }
1342
- }
1343
- }
1344
-
1345
- .o-collapse-item-header {
1346
- border-bottom: none;
1347
- padding-top: 0;
1348
- padding-bottom: 0;
1349
- display: flex;
1350
- align-items: center;
1351
- gap: var(--o-gap-4);
1352
-
1353
- @include respond('laptop') {
1354
- gap: var(--o-gap-3);
1355
- }
1356
-
1357
- @include respond('<=pad') {
1358
- gap: var(--o-gap-2);
1359
- }
1360
-
1361
- .o-collapse-item-icon {
1362
- flex-shrink: 0;
1363
- }
1364
-
1365
- .o-collapse-item-title {
1366
- flex: 1;
1367
- width: 0;
1368
- min-width: 0;
1369
- display: flex;
1370
- align-items: center;
1371
- justify-content: space-between;
1372
- margin-bottom: 0;
1373
- gap: var(--o-gap-4);
1374
-
1375
- .item-header {
1376
- flex: 1;
1377
- min-width: 0;
1378
- }
1379
- .item-header-left {
1380
- display: flex;
1381
- align-items: flex-start;
1382
- gap: var(--o-gap-3);
1383
- width: 100%;
1384
- margin-bottom: var(--o-gap-2);
1385
- @include respond('phone') {
1386
- flex-grow: 1;
1387
- width: 100%;
1388
- align-self: stretch;
1389
- flex-shrink: 0;
1390
- }
1391
- .meeting-icon {
1392
- width: var(--icon-size);
1393
- height: var(--icon-size);
1394
- border-radius: 50%;
1395
- background-color: var(--o-color-primary1);
1396
- color: #fff;
1397
- display: flex;
1398
- align-items: center;
1399
- justify-content: center;
1400
- flex-shrink: 0;
1401
- --icon-size2: var(--icon-size);
1402
- padding: 1px;
1403
-
1404
- .o-icon {
1405
- font-size: calc(var(--icon-size2) - 2px);
1406
- svg path {
1407
- fill: currentColor;
1408
- }
1409
- }
1410
-
1411
- }
1412
-
1413
- .header-info {
1414
- min-width: 0;
1415
- flex: 1;
1416
-
1417
- .meeting-title {
1418
- font-weight: 500;
1419
- display: flex;
1420
- align-items: center;
1421
- margin-bottom: var(--o-gap-2);
1422
- @include text2;
1423
-
1424
- .tag-wrapper {
1425
- flex: 10;
1426
- margin-left: var(--o-gap-2);
1427
-
1428
- .o-tag {
1429
- background-color: var(--o-color-control2-light);
1430
- border: none;
1431
- font-weight: 400;
1432
- }
1433
- }
1434
-
1435
- .title-wrapper {
1436
- flex: 0 1 auto;
1437
- min-width: 0;
1438
- max-width: 100%;
1439
- }
1440
-
1441
- .title-text {
1442
- @include text2;
1443
- @include text-truncate(1);
1444
- @include respond('phone') {
1445
- @include h3;
1446
- }
1447
- }
1448
- }
1449
-
1450
- .meeting-info {
1451
- color: var(--o-color-info3);
1452
- display: flex;
1453
- align-items: center;
1454
- font-weight: 400;
1455
- font-size: 14px;
1456
- line-height: 22px;
1457
- @include respond('<=pad_v') {
1458
- @include tip1;
1459
- }
1460
- @include respond('phone') {
1461
- flex-direction: column;
1462
- align-items: flex-start;
1463
- }
1464
-
1465
- .o-divider {
1466
- @include respond('phone') {
1467
- display: none;
1468
- }
1469
- }
1470
- span:last-child {
1471
- width: 0;
1472
- flex: 1;
1473
- @include text-truncate(1);
1474
- @include respond('phone') {
1475
- width: fit-content;
1476
- }
1477
- }
1478
- }
1479
- }
1480
- }
1481
-
1482
- .item-header-right {
1483
- display: flex;
1484
- align-items: center;
1485
- padding-left: calc(var(--o-gap-3) + var(--icon-size));
1486
- gap: var(--o-gap-4);
1487
- width: 100%;
1488
- font-weight: 400;
1489
-
1490
- .o-link {
1491
- font-size: 14px;
1492
- line-height: 21px;
1493
- --link-color: var(--o-color-info2);
1494
- }
1495
- .o-icon {
1496
- font-size: 16px;
1497
- }
1498
- }
1499
-
1500
- .copy-icon {
1501
- flex-shrink: 0;
1502
- font-size: 24px;
1503
- visibility: hidden;
1504
- opacity: 0;
1505
- color: var(--o-color-info1);
1506
- height: 1em;
1507
- @include respond('<=laptop') {
1508
- font-size: 20px;
1509
- }
1510
- @include respond('<=pad_v') {
1511
- font-size: 24px;
1512
- }
1513
-
1514
- &:hover {
1515
- color: var(--o-color-primary1);
1516
- }
1517
-
1518
-
1519
- svg path {
1520
- fill: currentColor;
1521
- }
1522
- }
1523
- }
1524
- }
1525
-
1526
- .o-collapse-item-body {
1527
- margin-bottom: 0;
1528
- padding: var(--o-gap-2) 0 0;
1529
-
1530
- .meeting-detail {
1531
- padding-left: calc(var(--o-gap-3) + var(--icon-size));
1532
-
1533
- @include respond('phone') {
1534
- padding-left: 0;
1535
- }
1536
-
1537
- .meeting-btn {
1538
- border-top: 1px solid var(--o-color-control4);
1539
- margin-top: var(--o-gap-4);
1540
- padding-top: var(--o-gap-4);
1541
- display: flex;
1542
- align-items: center;
1543
- justify-content: flex-end;
1544
- gap: var(--o-gap-5);
1545
- @include respond('pad_h') {
1546
- margin-top: var(--o-gap-3);
1547
- padding-top: var(--o-gap-3);
1548
- }
1549
- @include respond('<=pad_v') {
1550
- margin-top: var(--o-gap-2);
1551
- padding-top: var(--o-gap-2);
1552
- }
1553
-
1554
- .o-link {
1555
- --link-color: inherit;
1556
- }
1557
- }
1558
- }
1559
- }
1560
-
1561
- .o-btn.o-btn-text {
1562
- padding-left: 0 !important;
1563
- padding-right: 0 !important;
1564
- min-width: auto;
1565
- }
1566
- }
1567
-
1568
- .load-text {
1569
- text-align: center;
1570
- color: var(--o-color-info3);
1571
- @include tip1;
1572
- }
1573
- }
1574
-
1575
- }
1576
-
1577
- @include in-dark {
1578
- .group-bar.is-end {
1579
- --active-color: rgb(65, 65, 68) !important;
1580
- }
1581
- .meeting-list {
1582
-
1583
- .is-today {
1584
- .date-cell-text {
1585
- color: #fff !important;
1586
- }
1587
- }
1588
- }
1589
- }
1590
- }
1591
- </style>
1592
-
1593
- <style lang="scss">
1594
- .handle-dialog {
1595
- width: 450px;
1596
-
1597
- .o-dlg-header {
1598
- margin-bottom: var(--o-gap-5);
1599
- }
1600
-
1601
- .o-dlg-body-content {
1602
- display: flex;
1603
- justify-content: center;
1604
- }
1605
-
1606
- .dialog-footer {
1607
- display: flex;
1608
- justify-content: center;
1609
- margin-top: var(--o-gap-4);
1610
- column-gap: var(--o-gap-4);
1611
- }
1612
- }
1613
-
1614
- .cancel-dialog {
1615
- .dialog-content {
1616
- width: 384px;
1617
- text-align: center;
1618
- }
1619
-
1620
- .dialog-footer {
1621
- display: flex;
1622
- justify-content: center;
1623
- margin-top: var(--o-gap-4);
1624
- column-gap: var(--o-gap-4);
1625
- }
1626
- }
1627
-
1628
- </style>