@liujitcn/kratos-admin-system 0.0.1 → 0.0.17

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.
@@ -25,14 +25,6 @@
25
25
  <span class="document-tree-node" :class="`is-${data.kind}`" :title="data.path || data.label">
26
26
  <el-icon v-if="data.kind === 'document'" class="document-tree-node__icon"><Document /></el-icon>
27
27
  <span class="document-tree-node__label">{{ data.label }}</span>
28
- <time
29
- v-if="data.kind === 'document' && data.document?.updated_at"
30
- class="document-tree-node__updated-at"
31
- :datetime="data.document.updated_at"
32
- :title="data.document.updated_at"
33
- >
34
- {{ formatDocumentUpdatedAt(data.document.updated_at) }}
35
- </time>
36
28
  <code v-if="data.kind === 'project'">{{ data.projectKey }}</code>
37
29
  </span>
38
30
  </template>
@@ -47,24 +39,25 @@
47
39
  <el-skeleton :rows="10" animated />
48
40
  </div>
49
41
  <template v-else-if="selectedDocument">
42
+ <header class="reader-header">
43
+ <div class="reader-header__identity">
44
+ <el-icon><Document /></el-icon>
45
+ <div class="reader-header__title">
46
+ <strong>{{ selectedDocumentName }}</strong>
47
+ <span :title="selectedDocument.path">{{ selectedDocument.project_name }} / {{ selectedDocument.path }}</span>
48
+ </div>
49
+ </div>
50
+ <time v-if="selectedDocumentUpdatedAt" :datetime="selectedDocumentUpdatedAt" :title="selectedDocumentUpdatedAt">
51
+ 更新于 {{ formatDocumentUpdatedAt(selectedDocumentUpdatedAt) }}
52
+ </time>
53
+ </header>
50
54
  <div ref="readerScrollRef" v-loading="detailLoading" class="reader-scroll">
51
- <div ref="markdownRef" @click="handleMarkdownClick">
52
- <MarkdownRenderer
53
- class="project-markdown"
54
- :markdown="selectedDocument.content"
55
- :allow-html="false"
56
- :sanitize="true"
57
- :enable-breaks="true"
58
- :enable-latex="false"
59
- :enable-animate="false"
60
- :enable-shiki="false"
61
- :enable-mermaid="false"
55
+ <div ref="markdownRef" class="project-markdown" @click="handleMarkdownClick">
56
+ <MarkdownPreview
57
+ id="project-doc-preview"
58
+ class="project-markdown__preview"
59
+ :model-value="selectedDocument.content"
62
60
  :is-dark="globalStore.isDark"
63
- :show-code-block-header="true"
64
- :sticky-code-block-header="false"
65
- :enable-code-line-number="false"
66
- code-max-height="480px"
67
- :style="markdownRootStyle"
68
61
  />
69
62
  </div>
70
63
  </div>
@@ -79,8 +72,8 @@
79
72
  import { computed, nextTick, onMounted, ref, watch } from "vue";
80
73
  import { Search } from "@element-plus/icons-vue";
81
74
  import type { TreeNodeData } from "element-plus";
82
- import { MarkdownRenderer } from "x-markdown-vue";
83
- import "x-markdown-vue/style";
75
+ import MarkdownPreview from "@liujitcn/kratos-admin-core/components/MarkdownPreview/index.vue";
76
+ import { useGlobalStore } from "@liujitcn/kratos-admin-core/stores/runtime";
84
77
  import { defProjectDocumentService } from "@liujitcn/kratos-admin-system/api/system/project_document";
85
78
  import type {
86
79
  ProjectDocument,
@@ -88,7 +81,6 @@ import type {
88
81
  ProjectDocumentListItem,
89
82
  ProjectDocumentProject
90
83
  } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/project_document";
91
- import { useGlobalStore } from "@liujitcn/kratos-admin-core/stores/runtime";
92
84
 
93
85
  defineOptions({
94
86
  name: "ProjectDocument",
@@ -129,11 +121,6 @@ const detailRequestToken = ref(0);
129
121
  const documentTreeRef = ref<InstanceType<typeof ElTree>>();
130
122
  const markdownRef = ref<HTMLElement>();
131
123
  const readerScrollRef = ref<HTMLElement>();
132
- const markdownRootStyle = {
133
- padding: "0",
134
- color: "inherit",
135
- backgroundColor: "transparent"
136
- };
137
124
  const documentUpdatedAtFormatter = new Intl.DateTimeFormat("zh-CN", {
138
125
  month: "2-digit",
139
126
  day: "2-digit",
@@ -160,6 +147,10 @@ const filteredDocumentCount = computed(() => {
160
147
  ).length;
161
148
  });
162
149
  const selectedDocumentNodeKey = computed(() => (selectedDocumentId.value ? buildDocumentNodeKey(selectedDocumentId.value) : ""));
150
+ const selectedDocumentName = computed(() => selectedDocument.value?.path.split("/").at(-1) ?? "");
151
+ const selectedDocumentUpdatedAt = computed(
152
+ () => documents.value.find(node => node.document?.id === selectedDocumentId.value)?.document?.updated_at ?? ""
153
+ );
163
154
 
164
155
  /** 加载项目文档目录并恢复当前选择。 */
165
156
  async function loadDocuments() {
@@ -370,7 +361,6 @@ onMounted(() => {
370
361
  color: var(--admin-page-text-primary);
371
362
  background: var(--el-bg-color-page);
372
363
  }
373
-
374
364
  .project-doc-shell {
375
365
  display: grid;
376
366
  flex: 1;
@@ -383,179 +373,186 @@ onMounted(() => {
383
373
  border-radius: var(--admin-page-radius);
384
374
  box-shadow: var(--admin-page-shadow);
385
375
  }
386
-
387
376
  .document-navigation,
388
377
  .document-reader {
389
378
  display: flex;
379
+ flex-direction: column;
390
380
  min-width: 0;
391
381
  min-height: 0;
392
- flex-direction: column;
393
382
  overflow: hidden;
394
383
  }
395
-
396
384
  .document-navigation {
397
385
  border-right: 1px solid var(--admin-page-divider);
398
386
  }
399
-
400
387
  .navigation-header {
401
388
  display: flex;
402
- align-items: center;
403
389
  gap: 12px;
390
+ align-items: center;
404
391
  padding: 16px;
405
392
  border-bottom: 1px solid var(--admin-page-divider);
406
393
  }
407
-
408
394
  .document-count {
409
395
  flex: 0 0 auto;
410
396
  font-size: 12px;
411
397
  color: var(--admin-page-text-secondary);
412
398
  white-space: nowrap;
413
399
  }
414
-
415
400
  .document-tree-scroll {
416
401
  flex: 1;
417
402
  min-height: 0;
418
403
  padding: 8px;
419
404
  overflow-y: auto;
420
405
  }
421
-
422
406
  .document-tree {
423
407
  min-width: 100%;
424
408
  color: var(--admin-page-text-primary);
425
409
  background: transparent;
410
+
426
411
  --el-tree-node-hover-bg-color: var(--el-fill-color-light);
427
412
  }
428
-
429
413
  .document-tree :deep(.el-tree-node__content) {
430
414
  height: 34px;
431
415
  padding-right: 8px;
432
416
  border-radius: 4px;
433
417
  }
434
-
435
418
  .document-tree :deep(.el-tree-node.is-current > .el-tree-node__content) {
436
419
  color: var(--el-color-primary);
437
420
  background: var(--admin-page-accent-soft-bg);
438
421
  box-shadow: inset 3px 0 0 var(--el-color-primary);
439
422
  }
440
-
441
423
  .document-tree-node {
442
424
  display: flex;
443
425
  flex: 1;
444
- min-width: 0;
445
- align-items: center;
446
426
  gap: 7px;
427
+ align-items: center;
428
+ min-width: 0;
447
429
  overflow: hidden;
448
430
  }
449
-
450
431
  .document-tree-node__icon {
451
432
  flex: 0 0 auto;
452
433
  font-size: 15px;
453
434
  color: var(--admin-page-text-secondary);
454
435
  }
455
-
456
436
  .document-tree-node__label {
457
437
  min-width: 0;
458
438
  overflow: hidden;
459
439
  text-overflow: ellipsis;
460
440
  white-space: nowrap;
461
441
  }
462
-
463
442
  .document-tree-node.is-project .document-tree-node__label {
464
443
  font-weight: 650;
465
444
  }
466
-
467
445
  .document-tree-node.is-directory .document-tree-node__label {
468
446
  font-weight: 550;
469
447
  }
470
-
471
- .document-tree-node code,
472
- .document-tree-node__updated-at {
448
+ .document-tree-node code {
473
449
  flex: 0 0 auto;
474
450
  margin-left: auto;
475
451
  font-size: 11px;
476
452
  color: var(--admin-page-text-secondary);
477
453
  }
478
-
479
- .document-tree-node__updated-at {
454
+ .reader-header {
455
+ box-sizing: border-box;
456
+ display: flex;
457
+ gap: 20px;
458
+ align-items: center;
459
+ justify-content: space-between;
460
+ min-height: 64px;
461
+ padding: 10px 24px;
462
+ border-bottom: 1px solid var(--admin-page-divider);
463
+ }
464
+ .reader-header__identity {
465
+ display: flex;
466
+ gap: 10px;
467
+ align-items: center;
468
+ min-width: 0;
469
+ }
470
+ .reader-header__identity > :deep(.el-icon) {
471
+ flex: 0 0 auto;
472
+ font-size: 18px;
473
+ color: var(--el-color-primary);
474
+ }
475
+ .reader-header__title {
476
+ display: flex;
477
+ flex-direction: column;
478
+ gap: 3px;
479
+ min-width: 0;
480
+ }
481
+ .reader-header__title strong,
482
+ .reader-header__title span {
483
+ overflow: hidden;
484
+ text-overflow: ellipsis;
485
+ white-space: nowrap;
486
+ }
487
+ .reader-header__title strong {
488
+ font-size: 15px;
489
+ color: var(--admin-page-text-primary);
490
+ }
491
+ .reader-header__title span,
492
+ .reader-header time {
493
+ font-size: 12px;
494
+ color: var(--admin-page-text-secondary);
495
+ }
496
+ .reader-header time {
497
+ flex: 0 0 auto;
480
498
  font-variant-numeric: tabular-nums;
481
499
  white-space: nowrap;
482
500
  }
483
-
484
501
  .reader-scroll {
485
502
  flex: 1;
486
503
  min-height: 0;
487
- padding: 24px;
504
+ padding: 28px clamp(24px, 4vw, 52px) 40px;
488
505
  overflow-y: auto;
506
+ scrollbar-gutter: stable;
489
507
  }
490
-
491
508
  .project-markdown {
492
509
  width: 100%;
493
- max-width: 100%;
510
+ max-width: 1040px;
511
+ margin: 0 auto;
494
512
  overflow-wrap: anywhere;
495
513
  }
496
-
497
- .project-markdown :deep(.x-md-core > :first-child) {
498
- margin-top: 0;
499
- }
500
-
501
- .project-markdown :deep(.x-md-core > :last-child) {
502
- margin-bottom: 0;
503
- }
504
-
505
- .project-markdown :deep(h1),
506
- .project-markdown :deep(h2),
507
- .project-markdown :deep(h3),
508
- .project-markdown :deep(h4),
509
- .project-markdown :deep(h5),
510
- .project-markdown :deep(h6) {
511
- color: var(--admin-page-text-primary);
512
- scroll-margin-top: 16px;
513
- }
514
-
515
- .project-markdown :deep(a) {
516
- color: var(--el-color-primary);
517
- }
518
-
519
- .project-markdown :deep(blockquote) {
520
- border-left-color: var(--el-border-color);
521
- }
522
-
523
- .project-markdown :deep(table) {
524
- display: block;
525
- max-width: 100%;
526
- overflow-x: auto;
527
- }
528
-
529
514
  .reader-loading {
530
515
  padding: 24px;
531
516
  }
532
517
 
533
- @media (max-width: 900px) {
518
+ @media (width <= 900px) {
534
519
  .project-doc-shell {
535
520
  grid-template-columns: 280px minmax(0, 1fr);
536
521
  }
537
522
  }
538
523
 
539
- @media (max-width: 720px) {
524
+ @media (width <= 720px) {
540
525
  .project-doc-shell {
541
526
  display: flex;
542
527
  flex-direction: column;
543
528
  }
544
-
545
529
  .document-navigation {
546
- height: 320px;
547
530
  flex: 0 0 auto;
531
+ height: 240px;
548
532
  border-right: 0;
549
533
  border-bottom: 1px solid var(--admin-page-divider);
550
534
  }
551
-
552
535
  .document-reader {
553
- min-height: 520px;
536
+ flex: 1;
537
+ min-height: 0;
554
538
  }
555
-
556
539
  .reader-scroll {
540
+ padding-top: 24px;
541
+ padding-right: 16px;
542
+ padding-left: 16px;
543
+ }
544
+ .reader-header {
557
545
  padding-right: 16px;
558
546
  padding-left: 16px;
559
547
  }
548
+ .reader-header time {
549
+ display: none;
550
+ }
551
+ .project-markdown :deep(h1) {
552
+ font-size: 26px;
553
+ }
554
+ .project-markdown :deep(h2) {
555
+ font-size: 21px;
556
+ }
560
557
  }
561
558
  </style>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@liujitcn/kratos-admin-system",
3
3
  "private": false,
4
- "version": "0.0.1",
4
+ "version": "0.0.17",
5
5
  "type": "module",
6
6
  "description": "kratos-admin system management module",
7
7
  "license": "MIT",
@@ -12,12 +12,10 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@microsoft/fetch-event-source": "^2.0.1",
15
- "@shikijs/core": "^3.23.0",
16
15
  "sortablejs": "^1.15.2",
17
16
  "swagger-ui-dist": "^5.32.9",
18
17
  "vue-element-plus-x": "^2.0.3",
19
- "x-markdown-vue": "^0.0.200",
20
- "@liujitcn/kratos-admin-core": "0.0.1"
18
+ "@liujitcn/kratos-admin-core": "0.0.17"
21
19
  },
22
20
  "peerDependencies": {
23
21
  "@element-plus/icons-vue": "^2.3.1",
@@ -1 +0,0 @@
1
- declare module "x-markdown-vue/style";