-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- added note history page - added NoteHistory domain and application services - added noteHistory repository
- Loading branch information
Showing
11 changed files
with
309 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import type { MaybeRefOrGetter, Ref } from 'vue'; | ||
import { computed, onMounted, ref, toValue } from 'vue'; | ||
import type { NoteHistoryRecord, NoteHistoryMeta } from '@/domain/entities/History'; | ||
import type { Note } from '@/domain/entities/Note'; | ||
import { noteHistoryService } from '@/domain'; | ||
|
||
interface UseNoteHistoryComposableState { | ||
noteHistory: Ref<NoteHistoryMeta[] | null>; | ||
} | ||
|
||
interface UseNoteHistoryComposableOptions { | ||
noteId: MaybeRefOrGetter<NoteHistoryRecord['noteId'] | null>; | ||
} | ||
|
||
export default function useNoteHistory(options: UseNoteHistoryComposableOptions): UseNoteHistoryComposableState { | ||
const noteHistory = ref<NoteHistoryMeta[] | null>(null); | ||
|
||
const currentNoteId = computed(() => toValue(options.noteId)); | ||
|
||
async function loadNoteHistory(noteId: Note['id']): Promise<void> { | ||
noteHistory.value = await noteHistoryService.loadNoteHistory(noteId); | ||
} | ||
|
||
onMounted(() => { | ||
if (currentNoteId.value !== null) { | ||
void loadNoteHistory(currentNoteId.value); | ||
} | ||
}); | ||
|
||
return { | ||
noteHistory: noteHistory, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import type EditorTool from './EditorTool'; | ||
import type { Note } from './Note'; | ||
import type { User } from './User'; | ||
|
||
interface UserMeta { | ||
/** | ||
* Name of the user | ||
*/ | ||
name: User['name']; | ||
|
||
/** | ||
* Photo of the user | ||
*/ | ||
photo: User['photo']; | ||
}; | ||
|
||
export interface NoteHistoryRecord { | ||
/** | ||
* Unique identified of note history record | ||
*/ | ||
id: number; | ||
|
||
/** | ||
* Id of the note whose content history is stored | ||
*/ | ||
noteId: Note['id']; | ||
|
||
/** | ||
* User that updated note content | ||
*/ | ||
userId: User['id']; | ||
|
||
/** | ||
* Timestamp of note update | ||
*/ | ||
createdAt: string; | ||
|
||
/** | ||
* Version of note content | ||
*/ | ||
content: Note['content']; | ||
|
||
/** | ||
* Note tools of current version of note content | ||
*/ | ||
tools: EditorTool[]; | ||
} | ||
|
||
/** | ||
* Meta data of the note history record | ||
* Used for presentation of the note history record in web | ||
*/ | ||
export type NoteHistoryMeta = Omit<NoteHistoryRecord, 'content' | 'noteId' | 'tools'> & { | ||
/** | ||
* Meta data of the user who did changes | ||
* Used for note history metadata presentation | ||
*/ | ||
user: UserMeta; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import type { NoteHistoryMeta } from './entities/History'; | ||
import type { Note } from './entities/Note'; | ||
|
||
export default interface NoteHistoryRepositoryInterface { | ||
/** | ||
* Loads note history meta for note history preview | ||
* @param noteId - id of the note | ||
*/ | ||
loadNoteHistory(noteId: Note['id']): Promise<NoteHistoryMeta[]>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import type { NoteHistoryMeta } from './entities/History'; | ||
import type { Note } from './entities/Note'; | ||
import type NoteHistoryRepository from './noteHistory.repository.interface'; | ||
|
||
export default class NoteHistoryService { | ||
private readonly noteHistoryRepository: NoteHistoryRepository; | ||
|
||
constructor(historyRepository: NoteHistoryRepository) { | ||
this.noteHistoryRepository = historyRepository; | ||
} | ||
|
||
public async loadNoteHistory(noteId: Note['id']): Promise<NoteHistoryMeta[]> { | ||
return await this.noteHistoryRepository.loadNoteHistory(noteId); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import type NoteHistoryRepositoryInterface from '@/domain/noteHistory.repository.interface'; | ||
import type NotesApiTransport from './transport/notes-api'; | ||
import type { Note } from '@/domain/entities/Note'; | ||
import type { NoteHistoryMeta } from '@/domain/entities/History'; | ||
|
||
export default class NoteHistoryRepository implements NoteHistoryRepositoryInterface { | ||
private readonly transport: NotesApiTransport; | ||
|
||
constructor(notesApiTransport: NotesApiTransport) { | ||
this.transport = notesApiTransport; | ||
} | ||
|
||
public async loadNoteHistory(noteId: Note['id']): Promise<NoteHistoryMeta[]> { | ||
console.log('noteIID', noteId); | ||
const response = await this.transport.get<{ noteHistoryMeta: NoteHistoryMeta[] }>(`/note/${noteId}/history`); | ||
|
||
console.log('resssssss', response); | ||
|
||
return response.noteHistoryMeta; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export function parseDate(date: Date): string { | ||
// Массив с названиями месяцев | ||
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; | ||
|
||
// Получаем название месяца | ||
const month = months[date.getUTCMonth()]; | ||
|
||
// Получаем день | ||
const day = date.getUTCDate(); | ||
|
||
// Получаем часы и минуты, добавляем ведущий ноль при необходимости | ||
const hours = date.getUTCHours().toString() | ||
.padStart(2, '0'); | ||
const minutes = date.getUTCMinutes().toString() | ||
.padStart(2, '0'); | ||
|
||
// Формируем итоговую строку | ||
return `${month} ${day}, ${hours}:${minutes}`; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
<template> | ||
<ThreeColsLayout data-dimensions="large"> | ||
<div :class="$style['history']"> | ||
<div :class="$style['history__page-header']"> | ||
<Heading | ||
:level="1" | ||
:class="$style['title']" | ||
> | ||
{{ noteTitle }} | ||
</Heading> | ||
<Heading | ||
:level="2" | ||
:class="$style['subtle']" | ||
> | ||
{{ t('history.title') }} | ||
</Heading> | ||
</div> | ||
|
||
<div :class="$style['history__container']"> | ||
<Container | ||
:class="$style['history-items']" | ||
> | ||
<Row | ||
v-for="(historyRecord, index) in noteHistory" | ||
:key="historyRecord.id" | ||
:title="historyRecord.user.name" | ||
:subtitle="parseDate(new Date(historyRecord.createdAt))" | ||
:has-delimiter="noteHistory !== null && index !== noteHistory?.length - 1" | ||
:class="$style['history-items__row']" | ||
> | ||
<template #left> | ||
<Avatar | ||
:src="historyRecord.user.photo" | ||
:username="historyRecord.user.name" | ||
/> | ||
</template> | ||
<template #right> | ||
<Button | ||
secondary | ||
icon="Search" | ||
> | ||
{{ t('history.view') }} | ||
</Button> | ||
</template> | ||
</Row> | ||
</Container> | ||
</div> | ||
</div> | ||
</ThreeColsLayout> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { Heading, Container, Row, Avatar, Button } from 'codex-ui/vue'; | ||
import ThreeColsLayout from '../layouts/ThreeColsLayout.vue'; | ||
import useNoteHistory from '@/application/services/useNoteHistory'; | ||
import { parseDate } from '@/infrastructure/utils/parseDate'; | ||
const props = defineProps({ | ||
noteId: Note['id'], | ||
}); | ||
const { noteHistory } = useNoteHistory({ noteId: props.noteId }); | ||
import { useI18n } from 'vue-i18n'; | ||
import Note from './Note.vue'; | ||
const { t } = useI18n(); | ||
const noteTitle = 'HELLO WORLD HISTORY'; | ||
</script> | ||
<style lang="postcss" module> | ||
.history { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-start; | ||
&__page-header { | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: flex-start; | ||
gap: var(--spacing-s); | ||
align-self: stretch; | ||
padding: var(--spacing-xxl) var(--h-padding) 0; | ||
} | ||
&__container { | ||
display: flex; | ||
padding: var(--spacing-xxl) 0; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: flex-start; | ||
gap: var(--spacing-ml); | ||
align-self: stretch; | ||
} | ||
} | ||
.history-items { | ||
width: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-start; | ||
&__row { | ||
align-self: stretch; | ||
color: var(--text); | ||
} | ||
} | ||
.title { | ||
color: var(--base--text); | ||
} | ||
.subtle { | ||
color: var(--base--text-secondary); | ||
} | ||
</style> |