@tnotesjs/core 0.1.21 → 0.1.23

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 (122) hide show
  1. package/README.md +87 -87
  2. package/dist/{chunk-4MO7F7Q4.js → chunk-BSTQOJVE.js} +1 -1
  3. package/dist/{chunk-SQVHJR2Z.js → chunk-O4DCXHOV.js} +0 -3
  4. package/dist/cli/index.js +2 -2
  5. package/dist/index.js +1 -1
  6. package/dist/vitepress/config/index.js +2 -2
  7. package/package.json +3 -4
  8. package/types/config.ts +60 -61
  9. package/types/index.ts +11 -11
  10. package/types/note.ts +33 -33
  11. package/vitepress/assets/icons/icon__check.svg +3 -3
  12. package/vitepress/assets/icons/icon__clipboard.svg +7 -7
  13. package/vitepress/assets/icons/icon__close.svg +1 -1
  14. package/vitepress/assets/icons/icon__collapse.svg +1 -1
  15. package/vitepress/assets/icons/icon__confirm.svg +1 -1
  16. package/vitepress/assets/icons/icon__copy.svg +4 -4
  17. package/vitepress/assets/icons/icon__focus.svg +1 -1
  18. package/vitepress/assets/icons/icon__fold.svg +3 -3
  19. package/vitepress/assets/icons/icon__folder.svg +1 -1
  20. package/vitepress/assets/icons/icon__fullscreen.svg +1 -1
  21. package/vitepress/assets/icons/icon__fullscreen_exit.svg +1 -1
  22. package/vitepress/assets/icons/icon__github.svg +3 -3
  23. package/vitepress/assets/icons/icon__mindmap.svg +1 -1
  24. package/vitepress/assets/icons/icon__next.svg +1 -1
  25. package/vitepress/assets/icons/icon__number_gray.svg +1 -1
  26. package/vitepress/assets/icons/icon__number_purple.svg +1 -1
  27. package/vitepress/assets/icons/icon__prev.svg +1 -1
  28. package/vitepress/assets/icons/icon__restore.svg +1 -1
  29. package/vitepress/assets/icons/icon__rotate.svg +4 -4
  30. package/vitepress/assets/icons/icon__search.svg +1 -1
  31. package/vitepress/assets/icons/icon__sidebar_collapsed.svg +1 -1
  32. package/vitepress/assets/icons/icon__sidebar_opened.svg +1 -1
  33. package/vitepress/assets/icons/icon__totop.svg +5 -5
  34. package/vitepress/assets/icons/icon__vscode.svg +5 -5
  35. package/vitepress/assets/icons/icon__zoom_fit.svg +1 -1
  36. package/vitepress/assets/icons/icon__zoom_in.svg +1 -1
  37. package/vitepress/assets/icons/icon__zoom_out.svg +1 -1
  38. package/vitepress/assets/icons/icon__zoom_reset.svg +1 -1
  39. package/vitepress/assets/icons/index.ts +39 -39
  40. package/vitepress/components/BilibiliOutsidePlayer/BilibiliOutsidePlayer.vue +20 -20
  41. package/vitepress/components/CodeBlockFullscreen/CodeBlockFullscreen.vue +369 -369
  42. package/vitepress/components/CodeBlockFullscreen/index.ts +209 -213
  43. package/vitepress/components/CodeBlockFullscreen/styles.css +126 -126
  44. package/vitepress/components/Discussions/Discussions.vue +244 -211
  45. package/vitepress/components/EnWordList/EnWordList.vue +663 -543
  46. package/vitepress/components/EnWordList/RightClickMenu.vue +89 -66
  47. package/vitepress/components/Footprints/Footprints.vue +472 -377
  48. package/vitepress/components/Layout/AboutModal.vue +331 -105
  49. package/vitepress/components/Layout/AboutPanel.vue +484 -270
  50. package/vitepress/components/Layout/ContentCollapse.vue +590 -603
  51. package/vitepress/components/Layout/CustomSidebar.vue +817 -817
  52. package/vitepress/components/Layout/DocBeforeControls.vue +351 -149
  53. package/vitepress/components/Layout/DocFooter.vue +233 -233
  54. package/vitepress/components/Layout/ImagePreview.vue +484 -281
  55. package/vitepress/components/Layout/Layout.vue +744 -621
  56. package/vitepress/components/Layout/NavBarSettingsTrigger.vue +0 -2
  57. package/vitepress/components/Layout/NoteStatus.vue +140 -140
  58. package/vitepress/components/Layout/SidebarItems.vue +1083 -1083
  59. package/vitepress/components/Layout/SidebarNavBefore.vue +170 -171
  60. package/vitepress/components/Layout/SidebarResizeHandle.vue +311 -319
  61. package/vitepress/components/Layout/Swiper.vue +167 -167
  62. package/vitepress/components/Layout/ToggleFullContent.vue +47 -35
  63. package/vitepress/components/Layout/ToggleSidebar.vue +37 -26
  64. package/vitepress/components/Layout/composables/useCollapseControl.ts +88 -88
  65. package/vitepress/components/Layout/composables/useNoteConfig.ts +119 -119
  66. package/vitepress/components/Layout/composables/useNoteSave.ts +178 -178
  67. package/vitepress/components/Layout/composables/useNoteValidation.ts +85 -85
  68. package/vitepress/components/Layout/composables/useRedirect.ts +113 -113
  69. package/vitepress/components/Layout/composables/useSidebarLayout.ts +122 -122
  70. package/vitepress/components/Layout/composables/useVSCodeIntegration.ts +85 -85
  71. package/vitepress/components/Layout/homeReadme.data.ts +124 -124
  72. package/vitepress/components/LoadingPage/LoadingPage.vue +1 -6
  73. package/vitepress/components/MarkMap/MarkMap.vue +564 -405
  74. package/vitepress/components/Mermaid/Mermaid.vue +643 -365
  75. package/vitepress/components/NotesTable/NotesTable.vue +174 -98
  76. package/vitepress/components/NotesTable/README.md +67 -67
  77. package/vitepress/components/Settings/Settings.vue +711 -334
  78. package/vitepress/components/Settings/SettingsDialog.vue +1 -11
  79. package/vitepress/components/SidebarCard/MindMapView.vue +484 -484
  80. package/vitepress/components/SidebarCard/NotesTrendChart.vue +108 -108
  81. package/vitepress/components/SidebarCard/SidebarCard.vue +945 -946
  82. package/vitepress/components/Tooltip/Tooltip.vue +70 -70
  83. package/vitepress/components/constants.ts +109 -109
  84. package/vitepress/components/notesConfig.data.ts +73 -73
  85. package/vitepress/components/sidebar.data.ts +59 -59
  86. package/vitepress/components/tnotes-config.data.ts +21 -21
  87. package/vitepress/components/utils.ts +26 -26
  88. package/vitepress/config/index.ts +169 -169
  89. package/vitepress/configs/constants.ts +26 -26
  90. package/vitepress/configs/head.config.ts +25 -25
  91. package/vitepress/configs/index.ts +9 -9
  92. package/vitepress/configs/markdown-it.d.ts +23 -23
  93. package/vitepress/configs/markdown.config.ts +368 -367
  94. package/vitepress/configs/theme.config.ts +108 -108
  95. package/vitepress/plugins/buildProgressPlugin.ts +434 -434
  96. package/vitepress/plugins/getNoteByConfigIdPlugin.ts +107 -107
  97. package/vitepress/plugins/renameNotePlugin.ts +68 -68
  98. package/vitepress/plugins/sidebarStructurePlugin.ts +260 -260
  99. package/vitepress/plugins/updateConfigPlugin.ts +63 -63
  100. package/vitepress/theme/index.ts +137 -137
  101. package/vitepress/theme/styles/base.scss +66 -64
  102. package/vitepress/theme/styles/components/404.scss +31 -31
  103. package/vitepress/theme/styles/components/collapse.scss +172 -172
  104. package/vitepress/theme/styles/components/markmap.scss +101 -101
  105. package/vitepress/theme/styles/components/swiper.scss +255 -255
  106. package/vitepress/theme/styles/index.scss +25 -25
  107. package/vitepress/theme/styles/layout.scss +78 -78
  108. package/vitepress/theme/styles/utilities.scss +39 -39
  109. package/vitepress/theme/styles/vitepress-override.scss +25 -25
  110. package/vitepress/components/Discussions/Discussions.module.scss +0 -32
  111. package/vitepress/components/EnWordList/EnWordList.module.scss +0 -124
  112. package/vitepress/components/EnWordList/RightClickMenu.module.scss +0 -22
  113. package/vitepress/components/Footprints/Footprints.module.scss +0 -93
  114. package/vitepress/components/Layout/AboutModal.module.scss +0 -233
  115. package/vitepress/components/Layout/ImagePreview.module.scss +0 -201
  116. package/vitepress/components/Layout/Layout.module.scss +0 -661
  117. package/vitepress/components/Layout/ToggleFullContent.module.scss +0 -11
  118. package/vitepress/components/Layout/ToggleSidebar.module.scss +0 -11
  119. package/vitepress/components/MarkMap/MarkMap.module.scss +0 -159
  120. package/vitepress/components/Mermaid/Mermaid.module.scss +0 -275
  121. package/vitepress/components/NotesTable/NotesTable.module.scss +0 -77
  122. package/vitepress/components/Settings/Settings.module.scss +0 -375
@@ -1,271 +1,485 @@
1
- <template>
2
- <div
3
- :class="$style.timeModalContent"
4
- role="group"
5
- :aria-label="isHomeReadme ? '知识库提交信息' : '笔记提交信息'"
6
- >
7
- <!-- 笔记编号(仅笔记页显示) -->
8
- <div
9
- :class="$style.timeLine"
10
- v-if="!isHomeReadme && currentNoteId"
11
- title="笔记编号"
12
- >
13
- <div :class="$style.timeLabel">
14
- <strong>🔢 笔记编号</strong>
15
- </div>
16
- <div :class="$style.timeValue">{{ currentNoteId }}</div>
17
- </div>
18
-
19
- <!-- 笔记标题(仅笔记页显示) -->
20
- <div
21
- :class="$style.timeLine"
22
- v-if="!isHomeReadme && currentNoteId"
23
- title="笔记标题"
24
- >
25
- <div :class="$style.timeLabel">
26
- <strong>📝 笔记标题</strong>
27
- </div>
28
- <div :class="$style.timeValue">
29
- <input
30
- v-model="editableNoteTitle"
31
- type="text"
32
- :class="[$style.titleInput, { [$style.error]: titleError }]"
33
- :disabled="!isDev"
34
- @input="onTitleInput"
35
- @blur="onTitleBlur"
36
- placeholder="请输入笔记标题"
37
- />
38
- <div v-if="titleError" :class="$style.errorMessage">
39
- {{ titleError }}
40
- </div>
41
- </div>
42
- </div>
43
-
44
- <!-- 笔记简介(仅笔记页显示) -->
45
- <div
46
- :class="$style.timeLine"
47
- v-if="!isHomeReadme && currentNoteId"
48
- title="笔记简介"
49
- >
50
- <div :class="$style.timeLabel">
51
- <strong>📄 笔记简介</strong>
52
- </div>
53
- <div :class="$style.timeValue">
54
- <textarea
55
- v-model="editableDescription"
56
- :class="$style.descriptionInput"
57
- :disabled="!isDev"
58
- @input="onDescriptionInput"
59
- placeholder="请输入笔记的一句话简介(可选)"
60
- rows="2"
61
- />
62
- </div>
63
- </div>
64
-
65
- <!-- 笔记状态(仅笔记页显示且非开发环境只读) -->
66
- <div
67
- :class="$style.timeLine"
68
- v-if="!isHomeReadme && currentNoteId"
69
- title="笔记状态"
70
- >
71
- <div :class="$style.timeLabel">
72
- <strong>📝 完成状态</strong>
73
- </div>
74
- <div :class="$style.timeValue">
75
- <select
76
- v-model="editableNoteStatus"
77
- :class="$style.statusSelect"
78
- :disabled="!isDev"
79
- @change="onConfigChange"
80
- >
81
- <option :value="true">✅ 已完成</option>
82
- <option :value="false">⏰ 待处理</option>
83
- </select>
84
- </div>
85
- </div>
86
-
87
- <!-- 评论状态(仅笔记页显示且非开发环境只读) -->
88
- <div
89
- :class="$style.timeLine"
90
- v-if="!isHomeReadme && currentNoteId"
91
- title="评论状态"
92
- >
93
- <div :class="$style.timeLabel">
94
- <strong>🫧 评论状态</strong>
95
- </div>
96
- <div :class="$style.timeValue">
97
- <select
98
- v-model="editableDiscussionsEnabled"
99
- :class="$style.statusSelect"
100
- :disabled="!isDev"
101
- @change="onConfigChange"
102
- >
103
- <option :value="true">✅ 开启</option>
104
- <option :value="false">❌ 关闭</option>
105
- </select>
106
- </div>
107
- </div>
108
-
109
- <!-- 首次提交时间 -->
110
- <div :class="$style.timeLine" title="首次提交时间">
111
- <div :class="$style.timeLabel"><strong>⌛️ 首次提交</strong></div>
112
- <div :class="$style.timeValue">
113
- {{ formatOptionalDate(modalCreatedAt) }}
114
- </div>
115
- </div>
116
-
117
- <!-- 最近提交时间 -->
118
- <div :class="$style.timeLine" title="最近提交时间">
119
- <div :class="$style.timeLabel"><strong>⌛️ 最近提交</strong></div>
120
- <div :class="$style.timeValue">
121
- {{ formatOptionalDate(modalUpdatedAt) }}
122
- </div>
123
- </div>
124
-
125
- <!-- GitHub -->
126
- <div
127
- :class="$style.timeLine"
128
- v-if="modalGithubUrl"
129
- :title="
130
- isHomeReadme ? '在 GitHub 中打开知识库' : '在 GitHub 中打开当前笔记'
131
- "
132
- >
133
- <div :class="$style.timeLabel">
134
- <strong>🔗 GitHub</strong>
135
- </div>
136
- <div :class="$style.timeValue">
137
- <a
138
- :href="modalGithubUrl"
139
- target="_blank"
140
- rel="noopener"
141
- :class="$style.githubLink"
142
- >
143
- {{
144
- isHomeReadme ? '在 GitHub 中打开知识库' : '在 GitHub 中打开当前笔记'
145
- }}
146
- </a>
147
- </div>
148
- </div>
149
-
150
- <!-- GitHub Page -->
151
- <div
152
- :class="$style.timeLine"
153
- v-if="modalGithubPageUrl"
154
- :title="
155
- isHomeReadme
156
- ? '在 GitHub Page 中打开知识库'
157
- : '在 GitHub Page 中打开当前笔记'
158
- "
159
- >
160
- <div :class="$style.timeLabel">
161
- <strong>🔗 GitHub Page</strong>
162
- </div>
163
- <div :class="$style.timeValue">
164
- <a
165
- :href="modalGithubPageUrl"
166
- target="_blank"
167
- rel="noopener"
168
- :class="$style.githubLink"
169
- >
170
- {{
171
- isHomeReadme
172
- ? '在 GitHub Page 中打开知识库'
173
- : '在 GitHub Page 中打开当前笔记'
174
- }}
175
- </a>
176
- </div>
177
- </div>
178
-
179
- <!-- 完成进度(仅首页显示) -->
180
- <div
181
- :class="$style.timeLine"
182
- v-if="isHomeReadme && completionPercentage !== null"
183
- title="笔记完成进度"
184
- >
185
- <div :class="$style.timeLabel">
186
- <strong>📊 完成进度</strong>
187
- </div>
188
- <div :class="$style.timeValue">
189
- {{ completionPercentage }}% ({{ doneNotesLen }} / {{ totalNotesLen }})
190
- </div>
191
- </div>
192
- </div>
193
- </template>
194
-
195
- <script setup lang="ts">
1
+ <template>
2
+ <div class="timeModalContent">
3
+ <!-- 笔记编号(仅笔记页显示) -->
4
+ <div
5
+ class="timeLine"
6
+ v-if="!isHomeReadme && currentNoteId"
7
+ title="笔记编号"
8
+ >
9
+ <div class="timeLabel">
10
+ <strong>🔢 笔记编号</strong>
11
+ </div>
12
+ <div class="timeValue">{{ currentNoteId }}</div>
13
+ </div>
14
+
15
+ <!-- 笔记标题(仅笔记页显示) -->
16
+ <div
17
+ class="timeLine"
18
+ v-if="!isHomeReadme && currentNoteId"
19
+ title="笔记标题"
20
+ >
21
+ <div class="timeLabel">
22
+ <strong>📝 笔记标题</strong>
23
+ </div>
24
+ <div class="timeValue">
25
+ <input
26
+ v-model="editableNoteTitle"
27
+ type="text"
28
+ class="titleInput"
29
+ :class="{ error: titleError }"
30
+ :disabled="!isDev"
31
+ @input="onTitleInput"
32
+ @blur="onTitleBlur"
33
+ placeholder="请输入笔记标题"
34
+ />
35
+ <div v-if="titleError" class="errorMessage">
36
+ {{ titleError }}
37
+ </div>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- 笔记简介(仅笔记页显示) -->
42
+ <div
43
+ class="timeLine"
44
+ v-if="!isHomeReadme && currentNoteId"
45
+ title="笔记简介"
46
+ >
47
+ <div class="timeLabel">
48
+ <strong>📄 笔记简介</strong>
49
+ </div>
50
+ <div class="timeValue">
51
+ <textarea
52
+ v-model="editableDescription"
53
+ class="descriptionInput"
54
+ :disabled="!isDev"
55
+ @input="onDescriptionInput"
56
+ placeholder="请输入笔记的一句话简介(可选)"
57
+ rows="2"
58
+ />
59
+ </div>
60
+ </div>
61
+
62
+ <!-- 笔记状态(仅笔记页显示且非开发环境只读) -->
63
+ <div
64
+ class="timeLine"
65
+ v-if="!isHomeReadme && currentNoteId"
66
+ title="笔记状态"
67
+ >
68
+ <div class="timeLabel">
69
+ <strong>📝 完成状态</strong>
70
+ </div>
71
+ <div class="timeValue">
72
+ <select
73
+ v-model="editableNoteStatus"
74
+ class="statusSelect"
75
+ :disabled="!isDev"
76
+ @change="onConfigChange"
77
+ >
78
+ <option :value="true">✅ 已完成</option>
79
+ <option :value="false">⏰ 待处理</option>
80
+ </select>
81
+ </div>
82
+ </div>
83
+
84
+ <!-- 评论状态(仅笔记页显示且非开发环境只读) -->
85
+ <div
86
+ class="timeLine"
87
+ v-if="!isHomeReadme && currentNoteId"
88
+ title="评论状态"
89
+ >
90
+ <div class="timeLabel">
91
+ <strong>🫧 评论状态</strong>
92
+ </div>
93
+ <div class="timeValue">
94
+ <select
95
+ v-model="editableDiscussionsEnabled"
96
+ class="statusSelect"
97
+ :disabled="!isDev"
98
+ @change="onConfigChange"
99
+ >
100
+ <option :value="true">✅ 开启</option>
101
+ <option :value="false">❌ 关闭</option>
102
+ </select>
103
+ </div>
104
+ </div>
105
+
106
+ <!-- 首次提交时间 -->
107
+ <div class="timeLine" title="首次提交时间">
108
+ <div class="timeLabel"><strong>⌛️ 首次提交</strong></div>
109
+ <div class="timeValue">
110
+ {{ formatOptionalDate(modalCreatedAt) }}
111
+ </div>
112
+ </div>
113
+
114
+ <!-- 最近提交时间 -->
115
+ <div class="timeLine" title="最近提交时间">
116
+ <div class="timeLabel"><strong>⌛️ 最近提交</strong></div>
117
+ <div class="timeValue">
118
+ {{ formatOptionalDate(modalUpdatedAt) }}
119
+ </div>
120
+ </div>
121
+
122
+ <!-- GitHub -->
123
+ <div
124
+ class="timeLine"
125
+ v-if="modalGithubUrl"
126
+ :title="
127
+ isHomeReadme ? '在 GitHub 中打开知识库' : '在 GitHub 中打开当前笔记'
128
+ "
129
+ >
130
+ <div class="timeLabel">
131
+ <strong>🔗 GitHub</strong>
132
+ </div>
133
+ <div class="timeValue">
134
+ <a
135
+ :href="modalGithubUrl"
136
+ target="_blank"
137
+ rel="noopener"
138
+ class="githubLink"
139
+ >
140
+ {{
141
+ isHomeReadme ? '在 GitHub 中打开知识库' : '在 GitHub 中打开当前笔记'
142
+ }}
143
+ </a>
144
+ </div>
145
+ </div>
146
+
147
+ <!-- GitHub Page -->
148
+ <div
149
+ class="timeLine"
150
+ v-if="modalGithubPageUrl"
151
+ :title="
152
+ isHomeReadme
153
+ ? '在 GitHub Page 中打开知识库'
154
+ : '在 GitHub Page 中打开当前笔记'
155
+ "
156
+ >
157
+ <div class="timeLabel">
158
+ <strong>🔗 GitHub Page</strong>
159
+ </div>
160
+ <div class="timeValue">
161
+ <a
162
+ :href="modalGithubPageUrl"
163
+ target="_blank"
164
+ rel="noopener"
165
+ class="githubLink"
166
+ >
167
+ {{
168
+ isHomeReadme
169
+ ? '在 GitHub Page 中打开知识库'
170
+ : '在 GitHub Page 中打开当前笔记'
171
+ }}
172
+ </a>
173
+ </div>
174
+ </div>
175
+
176
+ <!-- 完成进度(仅首页显示) -->
177
+ <div
178
+ class="timeLine"
179
+ v-if="isHomeReadme && completionPercentage !== null"
180
+ title="笔记完成进度"
181
+ >
182
+ <div class="timeLabel">
183
+ <strong>📊 完成进度</strong>
184
+ </div>
185
+ <div class="timeValue">
186
+ {{ completionPercentage }}% ({{ doneNotesLen }} / {{ totalNotesLen }})
187
+ </div>
188
+ </div>
189
+ </div>
190
+ </template>
191
+
192
+ <script setup lang="ts">
196
193
  import { computed } from 'vue'
197
-
198
- import { formatDate } from '../utils'
199
-
200
- const props = defineProps<{
201
- isHomeReadme: boolean
202
- currentNoteId: string | null
203
- isDev: boolean
204
- editableNoteTitle: string
205
- editableDescription: string
206
- editableNoteStatus: boolean
207
- editableDiscussionsEnabled: boolean
208
- titleError: string
209
- modalCreatedAt: number | undefined
210
- modalUpdatedAt: number | undefined
211
- modalGithubUrl: string
212
- modalGithubPageUrl: string
213
- completionPercentage: number | null
214
- doneNotesLen: number
215
- totalNotesLen: number
216
- }>()
217
-
218
- const emit = defineEmits<{
219
- 'update:editableNoteTitle': [value: string]
220
- 'update:editableDescription': [value: string]
221
- 'update:editableNoteStatus': [value: boolean]
222
- 'update:editableDiscussionsEnabled': [value: boolean]
223
- 'update:titleError': [value: string]
224
- titleInput: []
225
- titleBlur: []
226
- descriptionInput: []
227
- configChange: []
228
- }>()
229
-
230
- const editableNoteTitle = computed({
231
- get: () => props.editableNoteTitle,
232
- set: (value) => emit('update:editableNoteTitle', value),
233
- })
234
-
235
- const editableDescription = computed({
236
- get: () => props.editableDescription,
237
- set: (value) => emit('update:editableDescription', value),
238
- })
239
-
240
- const editableNoteStatus = computed({
241
- get: () => props.editableNoteStatus,
242
- set: (value) => emit('update:editableNoteStatus', value),
243
- })
244
-
245
- const editableDiscussionsEnabled = computed({
246
- get: () => props.editableDiscussionsEnabled,
247
- set: (value) => emit('update:editableDiscussionsEnabled', value),
248
- })
249
-
250
- function onTitleInput() {
251
- emit('titleInput')
252
- }
253
-
254
- function onTitleBlur() {
255
- emit('titleBlur')
256
- }
257
-
258
- function onDescriptionInput() {
259
- emit('descriptionInput')
260
- }
261
-
262
- function onConfigChange() {
263
- emit('configChange')
264
- }
265
-
266
- function formatOptionalDate(timestamp: number | undefined) {
267
- return timestamp === undefined ? '-' : formatDate(timestamp)
268
- }
269
- </script>
270
-
271
- <style module src="./Layout.module.scss"></style>
194
+
195
+ import { formatDate } from '../utils'
196
+
197
+ const props = defineProps<{
198
+ isHomeReadme: boolean
199
+ currentNoteId: string | null
200
+ isDev: boolean
201
+ editableNoteTitle: string
202
+ editableDescription: string
203
+ editableNoteStatus: boolean
204
+ editableDiscussionsEnabled: boolean
205
+ titleError: string
206
+ modalCreatedAt: number | undefined
207
+ modalUpdatedAt: number | undefined
208
+ modalGithubUrl: string
209
+ modalGithubPageUrl: string
210
+ completionPercentage: number | null
211
+ doneNotesLen: number
212
+ totalNotesLen: number
213
+ }>()
214
+
215
+ const emit = defineEmits<{
216
+ 'update:editableNoteTitle': [value: string]
217
+ 'update:editableDescription': [value: string]
218
+ 'update:editableNoteStatus': [value: boolean]
219
+ 'update:editableDiscussionsEnabled': [value: boolean]
220
+ 'update:titleError': [value: string]
221
+ titleInput: []
222
+ titleBlur: []
223
+ descriptionInput: []
224
+ configChange: []
225
+ }>()
226
+
227
+ const editableNoteTitle = computed({
228
+ get: () => props.editableNoteTitle,
229
+ set: (value) => emit('update:editableNoteTitle', value),
230
+ })
231
+
232
+ const editableDescription = computed({
233
+ get: () => props.editableDescription,
234
+ set: (value) => emit('update:editableDescription', value),
235
+ })
236
+
237
+ const editableNoteStatus = computed({
238
+ get: () => props.editableNoteStatus,
239
+ set: (value) => emit('update:editableNoteStatus', value),
240
+ })
241
+
242
+ const editableDiscussionsEnabled = computed({
243
+ get: () => props.editableDiscussionsEnabled,
244
+ set: (value) => emit('update:editableDiscussionsEnabled', value),
245
+ })
246
+
247
+ function onTitleInput() {
248
+ emit('titleInput')
249
+ }
250
+
251
+ function onTitleBlur() {
252
+ emit('titleBlur')
253
+ }
254
+
255
+ function onDescriptionInput() {
256
+ emit('descriptionInput')
257
+ }
258
+
259
+ function onConfigChange() {
260
+ emit('configChange')
261
+ }
262
+
263
+ function formatOptionalDate(timestamp: number | undefined) {
264
+ return timestamp === undefined ? '-' : formatDate(timestamp)
265
+ }
266
+ </script>
267
+
268
+ <style scoped lang="scss">
269
+ /* time-modal-content: 通用容器 */
270
+ .timeModalContent {
271
+ display: flex;
272
+ flex-direction: column;
273
+ gap: 0.75rem;
274
+ padding: 0.25rem 0;
275
+ font-size: 0.95rem;
276
+
277
+ /* 每一行:移动端默认纵向排列(标签在上,值在下),在宽屏时变成左右两栏 */
278
+ .timeLine {
279
+ display: flex;
280
+ flex-direction: column;
281
+ gap: 0.25rem;
282
+ align-items: flex-start;
283
+ padding: 0.5rem;
284
+ border-radius: 8px;
285
+ transition: background-color 0.2s ease;
286
+
287
+ &:hover {
288
+ background-color: var(--vp-c-bg-soft);
289
+ }
290
+ }
291
+
292
+ /* 标签(左侧) */
293
+ .timeLabel {
294
+ font-weight: 700;
295
+ color: var(--vp-c-text);
296
+ font-size: 0.98rem;
297
+
298
+ strong {
299
+ display: inline-flex;
300
+ align-items: center;
301
+ gap: 0.25rem;
302
+ }
303
+ }
304
+
305
+ /* 值(右侧/下方) */
306
+ .timeValue {
307
+ color: var(--vp-c-text-2);
308
+ font-size: 0.88rem;
309
+ line-height: 1.35;
310
+ word-break: break-word;
311
+ font-family: var(--vp-font-family-mono);
312
+ }
313
+
314
+ /* GitHub 链接样式 */
315
+ .githubLink {
316
+ color: var(--vp-c-brand-1);
317
+ text-decoration: none;
318
+ transition: all 0.2s ease;
319
+ display: inline-flex;
320
+ align-items: center;
321
+ gap: 0.25rem;
322
+
323
+ &:hover {
324
+ color: var(--vp-c-brand-2);
325
+ text-decoration: underline;
326
+ }
327
+ }
328
+
329
+ /* 状态选择框样式 */
330
+ .statusSelect {
331
+ padding: 0.375rem 0.75rem;
332
+ border: 1px solid var(--vp-c-divider);
333
+ border-radius: 6px;
334
+ background-color: var(--vp-c-bg);
335
+ color: var(--vp-c-text-1);
336
+ font-size: 0.875rem;
337
+ font-family: inherit;
338
+ cursor: pointer;
339
+ transition: all 0.2s ease;
340
+ min-width: 120px;
341
+
342
+ &:hover:not(:disabled) {
343
+ border-color: var(--vp-c-brand-1);
344
+ background-color: var(--vp-c-bg-soft);
345
+ }
346
+
347
+ &:focus {
348
+ outline: none;
349
+ border-color: var(--vp-c-brand-1);
350
+ box-shadow: 0 0 0 3px rgba(var(--vp-c-brand-rgb), 0.1);
351
+ }
352
+
353
+ &:disabled {
354
+ opacity: 0.6;
355
+ cursor: not-allowed;
356
+ }
357
+
358
+ option {
359
+ padding: 0.5rem;
360
+ background-color: var(--vp-c-bg);
361
+ color: var(--vp-c-text-1);
362
+ }
363
+ }
364
+
365
+ /* 标题输入框样式 */
366
+ .titleInput {
367
+ width: 100%;
368
+ padding: 0.5rem 0.75rem;
369
+ border: 1px solid var(--vp-c-divider);
370
+ border-radius: 6px;
371
+ background-color: var(--vp-c-bg);
372
+ color: var(--vp-c-text-1);
373
+ font-size: 0.875rem;
374
+ font-family: inherit;
375
+ transition: all 0.2s ease;
376
+
377
+ &:hover:not(:disabled) {
378
+ border-color: var(--vp-c-brand-1);
379
+ background-color: var(--vp-c-bg-soft);
380
+ }
381
+
382
+ &:focus {
383
+ outline: none;
384
+ border-color: var(--vp-c-brand-1);
385
+ box-shadow: 0 0 0 3px rgba(var(--vp-c-brand-rgb), 0.1);
386
+ }
387
+
388
+ &:disabled {
389
+ opacity: 0.6;
390
+ cursor: not-allowed;
391
+ background-color: var(--vp-c-bg-soft);
392
+ }
393
+
394
+ &.error {
395
+ border-color: var(--vp-c-danger-1);
396
+
397
+ &:focus {
398
+ box-shadow: 0 0 0 3px rgba(255, 0, 0, 0.1);
399
+ }
400
+ }
401
+ }
402
+
403
+ /* 错误提示样式 */
404
+ .errorMessage {
405
+ margin-top: 0.25rem;
406
+ color: var(--vp-c-danger-1);
407
+ font-size: 0.75rem;
408
+ }
409
+
410
+ /* 简介文本框样式 */
411
+ .descriptionInput {
412
+ width: 100%;
413
+ padding: 0.5rem 0.75rem;
414
+ border: 1px solid var(--vp-c-divider);
415
+ border-radius: 6px;
416
+ background-color: var(--vp-c-bg);
417
+ color: var(--vp-c-text-1);
418
+ font-size: 0.875rem;
419
+ font-family: inherit;
420
+ line-height: 1.5;
421
+ resize: vertical;
422
+ min-height: 3rem;
423
+ transition: all 0.2s ease;
424
+
425
+ &:hover:not(:disabled) {
426
+ border-color: var(--vp-c-brand-1);
427
+ background-color: var(--vp-c-bg-soft);
428
+ }
429
+
430
+ &:focus {
431
+ outline: none;
432
+ border-color: var(--vp-c-brand-1);
433
+ box-shadow: 0 0 0 3px rgba(var(--vp-c-brand-rgb), 0.1);
434
+ }
435
+
436
+ &:disabled {
437
+ opacity: 0.6;
438
+ cursor: not-allowed;
439
+ background-color: var(--vp-c-bg-soft);
440
+ }
441
+ }
442
+ }
443
+
444
+ /* 宽屏样式:在 >=720px 时,改为左右两栏布局 */
445
+ @media (min-width: 720px) {
446
+ .timeModalContent {
447
+ gap: 1rem;
448
+
449
+ .timeLine {
450
+ flex-direction: row;
451
+ align-items: center;
452
+ justify-content: flex-start;
453
+ gap: 1rem;
454
+ }
455
+
456
+ .timeLabel {
457
+ width: 9.5rem;
458
+ text-align: left;
459
+ font-size: 1rem;
460
+ }
461
+
462
+ .timeValue {
463
+ flex: 1;
464
+ white-space: nowrap;
465
+ overflow: hidden;
466
+ text-overflow: ellipsis;
467
+ }
468
+ }
469
+ }
470
+
471
+ /* 更明显的可触控目标(移动端) */
472
+ @media (max-width: 520px) {
473
+ .timeModalContent {
474
+ gap: 0.9rem;
475
+
476
+ .timeLabel {
477
+ font-size: 1.02rem;
478
+ }
479
+
480
+ .timeValue {
481
+ font-size: 1rem;
482
+ }
483
+ }
484
+ }
485
+ </style>