feat(ui): add notes store

This commit is contained in:
sylenien 2022-09-28 11:08:26 +02:00 committed by Delirium
parent d1a325c413
commit 266a0bef7e
7 changed files with 209 additions and 88 deletions

View file

@ -2,17 +2,16 @@ import React from 'react';
import SessionList from './components/SessionList';
import SessionHeader from './components/SessionHeader';
import NotesList from './components/Notes/NoteList';
import { connect } from 'react-redux'
function SessionListContainer() {
function SessionListContainer({ activeTab }: { activeTab: string }) {
return (
<div className="widget-wrapper">
<SessionHeader />
<div className="border-b" />
{/* <SessionList /> */}
<NotesList />
{activeTab !== 'notes' ? <SessionList /> : <NotesList />}
</div>
);
}
export default SessionListContainer;
export default connect(state => ({ activeTab: state.getIn(['search', 'activeTab', 'type'])}))(SessionListContainer);

View file

@ -11,8 +11,8 @@ enum Tags {
interface Props {
author: string
date: string
tag: Tags
timestamp: number
tags: string[]
isPrivate: boolean
description: string
sessionId: string
@ -25,10 +25,10 @@ function NoteItem(props: Props) {
<div className="flex flex-col">
<div>{props.description}</div>
<div className="flex items-center gap-2">
<div>{props.tag}</div>
<div>{props.tags}</div>
<div className='text-disabled-text flex items-center'>
<span className="text-figmaColors-text-primary mr-1">By </span>
{props.author}, {props.date}
{props.author}, {props.timestamp}
{props.isPrivate ? null : (
<>
<Icon name="user-friends" className="ml-4 mr-1" color="gray-dark" /> Team

View file

@ -2,37 +2,20 @@ import React from 'react';
import { NoContent, Pagination, Icon } from 'UI';
import { sliceListPerPage } from 'App/utils';
import NoteItem from './NoteItem';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
//{ siteId }: { siteId: string }
function NotesList() {
const list = [
{
author: 'nikita@openreplay.com',
date: 'Today, 12.00PM',
tag: 1,
isPrivate: true,
description: 'Testing private note stuff bla bla bla',
sessionId: '123123123',
id: 2,
},
{
author: 'sasha@openreplay.com',
date: 'Tomorrow, 12.00PM',
tag: 0,
isPrivate: false,
description: 'Not Testing team note stuff bla bla bla',
sessionId: '123123123',
id: 1,
},
];
const { notesStore } = useStore()
const store = {
page: 1,
pageSize: 10,
// @ts-ignore
updateKey: (a, b) => 1,
};
React.useEffect(() => {
if (!notesStore.notes.length) {
notesStore.fetchNotes()
}
}, [])
const list = notesStore.notes
console.log(list)
return (
<NoContent
show={list.length === 0}
@ -44,15 +27,15 @@ function NotesList() {
}
>
<div className="mt-3 border-b rounded bg-white">
{sliceListPerPage(list, store.page - 1, store.pageSize).map((note) => (
<React.Fragment key={note.id}>
{sliceListPerPage(list, notesStore.page - 1, notesStore.pageSize).map(note => (
<React.Fragment key={note.noteId}>
<NoteItem
author={note.author}
tag={note.tag}
date={note.date}
isPrivate={note.isPrivate}
description={note.description}
sessionId={note.sessionId}
tags={note.tags}
timestamp={note.timestamp}
isPrivate={note.isPublic}
description={note.message}
sessionId={'123123'} // note.sessionId
/>
</React.Fragment>
))}
@ -60,14 +43,14 @@ function NotesList() {
<div className="w-full flex items-center justify-between pt-4 px-6">
<div className="text-disabled-text">
Showing <span className="font-semibold">{Math.min(list.length, store.pageSize)}</span> out
Showing <span className="font-semibold">{Math.min(list.length, notesStore.pageSize)}</span> out
of <span className="font-semibold">{list.length}</span> notes
</div>
<Pagination
page={store.page}
totalPages={Math.ceil(list.length / store.pageSize)}
onPageChange={(page) => store.updateKey('page', page)}
limit={store.pageSize}
page={notesStore.page}
totalPages={Math.ceil(list.length / notesStore.pageSize)}
onPageChange={(page) => notesStore.changePage(page)}
limit={notesStore.pageSize}
debounceRequest={100}
/>
</div>
@ -75,4 +58,4 @@ function NotesList() {
);
}
export default NotesList;
export default observer(NotesList);

View file

@ -5,56 +5,67 @@ import UserStore from './userStore';
import RoleStore from './roleStore';
import APIClient from 'App/api_client';
import FunnelStore from './funnelStore';
import { dashboardService, metricService, sessionService, userService, auditService, funnelService, errorService } from 'App/services';
import {
dashboardService,
metricService,
sessionService,
userService,
auditService,
funnelService,
errorService,
notesService,
} from 'App/services';
import SettingsStore from './settingsStore';
import AuditStore from './auditStore';
import NotificationStore from './notificationStore';
import ErrorStore from './errorStore';
import SessionStore from './sessionStore';
import NotesStore from './notesStore';
export class RootStore {
dashboardStore: DashboardStore;
metricStore: MetricStore;
funnelStore: FunnelStore;
settingsStore: SettingsStore;
userStore: UserStore;
roleStore: RoleStore;
auditStore: AuditStore;
errorStore: ErrorStore;
notificationStore: NotificationStore
sessionStore: SessionStore;
dashboardStore: DashboardStore;
metricStore: MetricStore;
funnelStore: FunnelStore;
settingsStore: SettingsStore;
userStore: UserStore;
roleStore: RoleStore;
auditStore: AuditStore;
errorStore: ErrorStore;
notificationStore: NotificationStore;
sessionStore: SessionStore;
notesStore: NotesStore;
constructor() {
this.dashboardStore = new DashboardStore();
this.metricStore = new MetricStore();
this.funnelStore = new FunnelStore();
this.settingsStore = new SettingsStore();
this.userStore = new UserStore();
this.roleStore = new RoleStore();
this.auditStore = new AuditStore();
this.errorStore = new ErrorStore();
this.notificationStore = new NotificationStore();
this.sessionStore = new SessionStore();
}
constructor() {
this.dashboardStore = new DashboardStore();
this.metricStore = new MetricStore();
this.funnelStore = new FunnelStore();
this.settingsStore = new SettingsStore();
this.userStore = new UserStore();
this.roleStore = new RoleStore();
this.auditStore = new AuditStore();
this.errorStore = new ErrorStore();
this.notificationStore = new NotificationStore();
this.sessionStore = new SessionStore();
this.notesStore = new NotesStore();
}
initClient() {
const client = new APIClient();
dashboardService.initClient(client)
metricService.initClient(client)
funnelService.initClient(client)
sessionService.initClient(client)
userService.initClient(client)
auditService.initClient(client)
errorService.initClient(client)
}
initClient() {
const client = new APIClient();
dashboardService.initClient(client);
metricService.initClient(client);
funnelService.initClient(client);
sessionService.initClient(client);
userService.initClient(client);
auditService.initClient(client);
errorService.initClient(client);
notesService.initClient(client)
}
}
const StoreContext = React.createContext<RootStore>({} as RootStore);
export const StoreProvider = ({ children, store }: any) => {
return (
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;
};
export const useStore = () => React.useContext(StoreContext);

View file

@ -0,0 +1,72 @@
import { makeAutoObservable } from "mobx"
import { notesService } from "App/services"
import { Note } from 'App/services/NotesService'
interface SessionNotes {
[sessionId: string]: Note[]
}
export default class NotesStore {
notes: Note[] = []
sessionNotes: SessionNotes
loading: boolean
page = 1
pageSize = 15
constructor() {
makeAutoObservable(this)
}
async fetchNotes() {
this.loading = true
try {
const notes = await notesService.getNotes()
this.notes = notes;
} catch (e) {
console.error(e)
} finally {
this.loading = false
}
}
async fetchSessionNotes(sessionId: string) {
this.loading = true
try {
const notes = await notesService.getNotesBySessionId(sessionId)
this.sessionNotes[sessionId] = notes
} catch (e) {
console.error(e)
} finally {
this.loading = false
}
}
async addNote(sessionId: string, note: Note) {
this.loading = true
try {
const addedNote = await notesService.addNote(sessionId, note)
return addedNote
} catch (e) {
console.error(e)
} finally {
this.loading = false
}
}
async deleteNote(noteId: string) {
this.loading = true
try {
const deleted = await notesService.deleteNote(noteId)
return deleted
} catch (e) {
console.error(e)
} finally {
this.loading = false
}
}
changePage(page: number) {
this.page = page
}
}

View file

@ -0,0 +1,54 @@
import APIClient from 'App/api_client';
export interface Note {
message: string
tags: string[]
isPublic: boolean
timestamp: number
noteId?: string
author?: string
}
export default class NotesService {
private client: APIClient;
constructor(client?: APIClient) {
this.client = client ? client : new APIClient();
}
initClient(client?: APIClient) {
this.client = client || new APIClient();
}
getNotes(): Promise<Note[]> {
return this.client.get('/notes').then(r => {
if (r.ok) {
return r.json()
} else {
throw new Error('Error getting notes: ' + r.status)
}
})
}
getNotesBySessionId(sessionID: string): Promise<Note[]> {
return this.client.get(`/sessions/${sessionID}/notes`)
.then(r => r.json())
}
addNote(sessionID: string, note: Note): Promise<Note> {
return this.client.post(`/sessions/${sessionID}/notes`, note)
.then(r => r.json())
}
updateNote(noteID: string, note: Note): Promise<Note> {
return this.client.post(`/notes/${noteID}`, note)
.then(r => r.json())
}
deleteNote(noteID: string) {
return this.client.delete(`/notes/${noteID}`)
.then(r => r.json())
}
}

View file

@ -1,10 +1,11 @@
import DashboardService, { IDashboardService } from "./DashboardService";
import MetricService, { IMetricService } from "./MetricService";
import FunnelService, { IFunnelService } from "./FunnelService";
import DashboardService from "./DashboardService";
import MetricService from "./MetricService";
import FunnelService from "./FunnelService";
import SessionSerivce from "./SessionService";
import UserService from "./UserService";
import AuditService from './AuditService';
import ErrorService from "./ErrorService";
import NotesService from "./NotesService";
export const dashboardService = new DashboardService();
export const metricService = new MetricService();
@ -13,3 +14,4 @@ export const userService = new UserService();
export const funnelService = new FunnelService();
export const auditService = new AuditService();
export const errorService = new ErrorService();
export const notesService = new NotesService();