feat: create project
This commit is contained in:
parent
0ca3f06c8b
commit
59cc371d50
Binary file not shown.
@ -1,4 +1,8 @@
|
|||||||
package session
|
package session
|
||||||
|
|
||||||
type Organization struct {
|
type Organization struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
LogoPath string
|
||||||
|
Users []User
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,21 +1,23 @@
|
|||||||
package session
|
package session
|
||||||
|
|
||||||
type session struct {
|
type Session struct {
|
||||||
Project Project
|
Project Project
|
||||||
Organization Organization
|
Organization Organization
|
||||||
User User
|
User User
|
||||||
}
|
}
|
||||||
|
|
||||||
var sessionInstance *session
|
var sessionInstance *Session
|
||||||
|
|
||||||
func GetInstance() *session {
|
func GetInstance() *Session {
|
||||||
if sessionInstance == nil {
|
if sessionInstance == nil {
|
||||||
sessionInstance = &session{}
|
sessionInstance = &Session{}
|
||||||
}
|
}
|
||||||
return sessionInstance
|
return sessionInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitializeModule(newSession session) *session {
|
func InitializeModule(newSession Session) *Session {
|
||||||
sessionInstance = &newSession
|
if sessionInstance == nil {
|
||||||
|
sessionInstance = &newSession
|
||||||
|
}
|
||||||
return sessionInstance
|
return sessionInstance
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
package session
|
package session
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Id string
|
Id string
|
||||||
FirstName string
|
FirstName string
|
||||||
LastName string
|
LastName string
|
||||||
Avatar string
|
AvatarPath string
|
||||||
|
AuthToken string
|
||||||
}
|
}
|
||||||
|
|||||||
153
frontend/components/project/Main.tsx
Normal file
153
frontend/components/project/Main.tsx
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { Popover, Transition } from '@headlessui/react'
|
||||||
|
import { ChevronDownIcon, FolderArrowDownIcon, FolderOpenIcon, FolderPlusIcon } from '@heroicons/react/20/solid'
|
||||||
|
import { Fragment, useState } from 'react'
|
||||||
|
import { useProject } from '../../context/Project/provider'
|
||||||
|
import NewProjectModal from './NewProjectModal'
|
||||||
|
|
||||||
|
|
||||||
|
const MainProject = () => {
|
||||||
|
const [isNewProjectModalOpen, setIsNewProjectModalOpen] = useState(false)
|
||||||
|
const [canPopoverBeOpen, setCanPopoverBeOpen] = useState(true)
|
||||||
|
const { createNewProject } = useProject()
|
||||||
|
|
||||||
|
const buttonOptions = [
|
||||||
|
{
|
||||||
|
name: 'New',
|
||||||
|
description: 'Create a new Project',
|
||||||
|
icon: <FolderPlusIcon className='w-10 h-10 stroke-slate-600' />,
|
||||||
|
onClick: () => {
|
||||||
|
setIsNewProjectModalOpen(true)
|
||||||
|
setCanPopoverBeOpen(false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Open',
|
||||||
|
description: 'Open a local Project',
|
||||||
|
icon: <FolderOpenIcon className='w-10 h-9 stroke-slate-600' />,
|
||||||
|
onClick: () => {
|
||||||
|
setCanPopoverBeOpen(false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Connect',
|
||||||
|
description: 'Connected to a hosted Project',
|
||||||
|
icon: <FolderArrowDownIcon className='w-10 h-9 stroke-slate-600' />,
|
||||||
|
onClick: () => {
|
||||||
|
setCanPopoverBeOpen(false)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const onCreateNewProjectHandler = (projectName: string) => {
|
||||||
|
setIsNewProjectModalOpen(false)
|
||||||
|
setCanPopoverBeOpen(true)
|
||||||
|
createNewProject(projectName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <main className=" text-gray-100 h-screen overflow-y-scroll">
|
||||||
|
|
||||||
|
{isNewProjectModalOpen ? <NewProjectModal onCreateNewProjectHandler={onCreateNewProjectHandler} /> : ''}
|
||||||
|
|
||||||
|
<div className="py-20 px-6 sm:px-6 sm:py-32 lg:px-8">
|
||||||
|
<div className="mx-auto max-w-2xl text-center">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
className=" h-10 inline-block"
|
||||||
|
src='/images/logo.svg'
|
||||||
|
alt="T"
|
||||||
|
/>
|
||||||
|
<h3 className="inline-block">extualize</h3>
|
||||||
|
</div>
|
||||||
|
<h2 className="text-4xl font-bold tracking-tight text-gray-200">
|
||||||
|
Digitize, Translate, and Manage
|
||||||
|
<br />
|
||||||
|
Your Physical Documents
|
||||||
|
</h2>
|
||||||
|
<p className="mx-auto mt-6 max-w-xl text-lg leading-8 text-gray-300">
|
||||||
|
Incididunt sint fugiat pariatur cupidatat consectetur sit cillum anim id veniam aliqua proident excepteur
|
||||||
|
commodo do ea.
|
||||||
|
</p>
|
||||||
|
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||||
|
<Popover className="relative">
|
||||||
|
{({ open }) => <>
|
||||||
|
<Popover.Button
|
||||||
|
className={`
|
||||||
|
${open ? '' : 'text-opacity-90'}
|
||||||
|
group inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-base font-medium text-white hover:text-opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75`}
|
||||||
|
>
|
||||||
|
<span>Select Project</span>
|
||||||
|
<ChevronDownIcon
|
||||||
|
className={`${open ? '' : 'text-opacity-70'}
|
||||||
|
ml-2 h-5 w-5 text-orange-300 transition duration-150 ease-in-out group-hover:text-opacity-80`}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</Popover.Button>
|
||||||
|
<Transition
|
||||||
|
as={Fragment}
|
||||||
|
enter="transition ease-out duration-200"
|
||||||
|
enterFrom="opacity-0 translate-y-1"
|
||||||
|
enterTo="opacity-100 translate-y-0"
|
||||||
|
leave="transition ease-in duration-150"
|
||||||
|
leaveFrom="opacity-100 translate-y-0"
|
||||||
|
leaveTo="opacity-0 translate-y-1"
|
||||||
|
>
|
||||||
|
{canPopoverBeOpen ? (
|
||||||
|
<Popover.Panel className="absolute left-1/2 z-10 mt-3 w-[420px] -translate-x-1/2 transform px-4 sm:px-0">
|
||||||
|
<div className="overflow-hidden rounded-lg shadow-lg ring-1 ring-black ring-opacity-5">
|
||||||
|
<div className="relative bg-white py-7">
|
||||||
|
{buttonOptions.map((item) => (
|
||||||
|
<a
|
||||||
|
key={item.name}
|
||||||
|
onClick={item.onClick}
|
||||||
|
className="cursor-pointer -m-3 flex w-[400px] mx-auto text-left rounded-lg py-2 px-8 transition duration-150 ease-in-out hover:bg-gray-50 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
|
||||||
|
>
|
||||||
|
<div className=" text-white sm:h-12 sm:w-12">
|
||||||
|
{item.icon}
|
||||||
|
</div>
|
||||||
|
<div className="ml-4">
|
||||||
|
<p className="text-sm font-medium text-gray-900">
|
||||||
|
{item.name}
|
||||||
|
</p>
|
||||||
|
<p className="text-sm text-gray-500">
|
||||||
|
{item.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="bg-gray-50 p-4">
|
||||||
|
<a
|
||||||
|
href="##"
|
||||||
|
className="flow-root rounded-md px-2 py-2 transition duration-150 ease-in-out hover:bg-gray-100 focus:outline-none focus-visible:ring focus-visible:ring-orange-500 focus-visible:ring-opacity-50"
|
||||||
|
>
|
||||||
|
<span className="flex items-center">
|
||||||
|
<span className="text-sm font-medium text-gray-900">
|
||||||
|
Documentation
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span className="block text-sm text-gray-500">
|
||||||
|
Start integrating products and tools
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Popover.Panel>
|
||||||
|
) : <Popover.Panel></Popover.Panel>
|
||||||
|
}
|
||||||
|
</Transition>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</Popover>
|
||||||
|
<a href="#" className="text-base font-semibold leading-7 text-gray-400">
|
||||||
|
Learn More <span aria-hidden="true">→</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MainProject
|
||||||
48
frontend/components/project/NewProjectModal.tsx
Normal file
48
frontend/components/project/NewProjectModal.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import { useRef } from 'react'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
onCreateNewProjectHandler: (projectName: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const NewProjectModal = (props: Props) => {
|
||||||
|
const projectNameRef = useRef<HTMLInputElement>(null)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className=" p-8 absolute top-2/4 -translate-y-1/2 left-2/4 -translate-x-1/2 z-50 bg-white shadow sm:rounded-lg">
|
||||||
|
<div className="px-4 py-5 sm:p-6">
|
||||||
|
<h3 className="text-lg font-medium leading-6 text-gray-900">Name Your New Project</h3>
|
||||||
|
<div className="mt-2 max-w-xl text-sm text-gray-500">
|
||||||
|
<p>A unique name will be best. This <b>can</b> be changed later.</p>
|
||||||
|
</div>
|
||||||
|
<form className="mt-5 sm:flex sm:items-center">
|
||||||
|
<div className="w-full sm:max-w-xs">
|
||||||
|
<label htmlFor="name" className="sr-only">
|
||||||
|
Project Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
id="name"
|
||||||
|
autoFocus
|
||||||
|
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm text-gray-900"
|
||||||
|
placeholder="New Project"
|
||||||
|
ref={projectNameRef}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
onClick={() => {
|
||||||
|
if (!projectNameRef.current?.value) return
|
||||||
|
props.onCreateNewProjectHandler(projectNameRef.current?.value)
|
||||||
|
}}
|
||||||
|
className="mt-3 inline-flex w-full items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm"
|
||||||
|
>
|
||||||
|
Start
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewProjectModal
|
||||||
@ -74,6 +74,7 @@ function Sidebar() {
|
|||||||
setSelectedAreaId,
|
setSelectedAreaId,
|
||||||
selectedDocumentId,
|
selectedDocumentId,
|
||||||
setSelectedDocumentId,
|
setSelectedDocumentId,
|
||||||
|
currentSession,
|
||||||
} = useProject()
|
} = useProject()
|
||||||
|
|
||||||
const navigation = getNavigationProps(documents, groups)
|
const navigation = getNavigationProps(documents, groups)
|
||||||
@ -388,11 +389,8 @@ function Sidebar() {
|
|||||||
<div className="hidden md:fixed md:inset-y-0 md:flex md:w-64 md:flex-col">
|
<div className="hidden md:fixed md:inset-y-0 md:flex md:w-64 md:flex-col">
|
||||||
<div className="flex min-h-0 flex-1 flex-col bg-gray-800 bg-opacity-25">
|
<div className="flex min-h-0 flex-1 flex-col bg-gray-800 bg-opacity-25">
|
||||||
<div className="flex h-16 flex-shrink-0 items-center bg-gray-900 px-4 bg-opacity-25">
|
<div className="flex h-16 flex-shrink-0 items-center bg-gray-900 px-4 bg-opacity-25">
|
||||||
<img
|
<img className="h-8 w-auto" src='/images/logo.svg' alt="Textualize" />
|
||||||
className="h-8 w-auto"
|
<h1 className='text-gray-100 text-xl ml-2'>{currentSession.project.name}</h1>
|
||||||
src='/images/logo.svg'
|
|
||||||
alt="Textualize"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 flex-col overflow-y-auto">
|
<div className="flex flex-1 flex-col overflow-y-auto">
|
||||||
{renderNavigationItems()}
|
{renderNavigationItems()}
|
||||||
|
|||||||
@ -17,9 +17,9 @@ const TextEditor = () => {
|
|||||||
const [isPreviewOpen, setIsPreviewOpen] = useState(false)
|
const [isPreviewOpen, setIsPreviewOpen] = useState(false)
|
||||||
const [modifiedEditorValue, setModifiedEditorValue] = useState('')
|
const [modifiedEditorValue, setModifiedEditorValue] = useState('')
|
||||||
|
|
||||||
const handleEditorDidMount: DiffOnMount = async (editor, _) => {
|
const handleEditorDidMount: DiffOnMount = async (editor, monaco) => {
|
||||||
const currentDocumentId = selectedDocumentId
|
const currentDocumentId = selectedDocumentId
|
||||||
|
|
||||||
editorInteractions = createDiffEditorInteractions(editor)
|
editorInteractions = createDiffEditorInteractions(editor)
|
||||||
const modifiedEditor = editor.getModifiedEditor()
|
const modifiedEditor = editor.getModifiedEditor()
|
||||||
const originalEditor = editor.getOriginalEditor()
|
const originalEditor = editor.getOriginalEditor()
|
||||||
@ -84,6 +84,10 @@ const TextEditor = () => {
|
|||||||
language='markdown'
|
language='markdown'
|
||||||
height={`${editorHeight}px`}
|
height={`${editorHeight}px`}
|
||||||
onMount={handleEditorDidMount}
|
onMount={handleEditorDidMount}
|
||||||
|
options={{
|
||||||
|
renderMarginRevertIcon: true,
|
||||||
|
enableSplitViewResizing: false,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isPreviewOpen ? <TextPreview markdown={modifiedEditorValue} height={editorHeight} /> : ''}
|
{isPreviewOpen ? <TextPreview markdown={modifiedEditorValue} height={editorHeight} /> : ''}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ type Props = { markdown: string, height: number }
|
|||||||
|
|
||||||
const TextPreview = (props: Props) => (
|
const TextPreview = (props: Props) => (
|
||||||
<div
|
<div
|
||||||
className='absolute w-1/2 top-[30px] bg-white overflow-y-scroll p-0 m-0'
|
className='absolute w-[calc(50%-14px)] top-[30px] bg-white overflow-y-scroll p-4 m-0'
|
||||||
style={{ 'height': `${props.height}px` }}>
|
style={{ 'height': `${props.height}px` }}>
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
components={{
|
components={{
|
||||||
|
|||||||
@ -18,7 +18,9 @@ const makeDefaultProject = (): ProjectContextType => ({
|
|||||||
requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise.resolve(new ipc.UserMarkdown()),
|
requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise.resolve(new ipc.UserMarkdown()),
|
||||||
getUserMarkdownByDocumentId: (documentId) => Promise.resolve(new ipc.UserMarkdown),
|
getUserMarkdownByDocumentId: (documentId) => Promise.resolve(new ipc.UserMarkdown),
|
||||||
setSelectedAreaId: (id) => {},
|
setSelectedAreaId: (id) => {},
|
||||||
setSelectedDocumentId: (id) => {}
|
setSelectedDocumentId: (id) => {},
|
||||||
|
currentSession: new ipc.Session(),
|
||||||
|
createNewProject: (name: string) => Promise.resolve(new ipc.Session()),
|
||||||
})
|
})
|
||||||
|
|
||||||
export default makeDefaultProject
|
export default makeDefaultProject
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { createContext, ReactNode, useContext, useEffect, useState } from 'react'
|
import { createContext, ReactNode, useContext, useEffect, useState } from 'react'
|
||||||
import { GetDocuments, GetProcessedAreasByDocumentId, GetUserMarkdownByDocumentId, RequestAddArea, RequestAddDocument, RequestAddDocumentGroup, RequestAddProcessedArea, RequestUpdateArea, RequestUpdateDocumentUserMarkdown } from '../../wailsjs/wailsjs/go/ipc/Channel'
|
import { CreateNewProject, GetCurrentSession, GetDocuments, GetProcessedAreasByDocumentId, GetUserMarkdownByDocumentId, RequestAddArea, RequestAddDocument, RequestAddDocumentGroup, RequestAddProcessedArea, RequestUpdateArea, RequestUpdateDocumentUserMarkdown } from '../../wailsjs/wailsjs/go/ipc/Channel'
|
||||||
import { ipc } from '../../wailsjs/wailsjs/go/models'
|
import { ipc } from '../../wailsjs/wailsjs/go/models'
|
||||||
import { AddAreaProps, AreaProps, ProjectContextType, ProjectProps } from './types'
|
import { AddAreaProps, AreaProps, ProjectContextType, ProjectProps } from './types'
|
||||||
import makeDefaultProject from './makeDefaultProject'
|
import makeDefaultProject from './makeDefaultProject'
|
||||||
@ -18,6 +18,7 @@ export function ProjectProvider({ children, projectProps }: Props) {
|
|||||||
const [ groups, setGroups ] = useState<ipc.Group[]>(projectProps.groups)
|
const [ groups, setGroups ] = useState<ipc.Group[]>(projectProps.groups)
|
||||||
const [ selectedAreaId, setSelectedAreaId ] = useState<string>('')
|
const [ selectedAreaId, setSelectedAreaId ] = useState<string>('')
|
||||||
const [selectedDocumentId, setSelectedDocumentId] = useState<string>('')
|
const [selectedDocumentId, setSelectedDocumentId] = useState<string>('')
|
||||||
|
const [currentSession, setCurrentSession] = useState<ipc.Session>(new ipc.Session())
|
||||||
|
|
||||||
const updateDocuments = async () => {
|
const updateDocuments = async () => {
|
||||||
GetDocuments().then(response => {
|
GetDocuments().then(response => {
|
||||||
@ -92,6 +93,19 @@ export function ProjectProvider({ children, projectProps }: Props) {
|
|||||||
|
|
||||||
const requestAddProcessedArea = async (processedArea: ipc.ProcessedArea) => await RequestAddProcessedArea(processedArea)
|
const requestAddProcessedArea = async (processedArea: ipc.ProcessedArea) => await RequestAddProcessedArea(processedArea)
|
||||||
|
|
||||||
|
const updateSession = async () => {
|
||||||
|
GetCurrentSession().then(response => {
|
||||||
|
if (response) setCurrentSession(response)
|
||||||
|
Promise.resolve(response)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const createNewProject = async (name: string) => {
|
||||||
|
const sessionResponse = await CreateNewProject(name)
|
||||||
|
await updateSession()
|
||||||
|
return sessionResponse
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!documents.length && !groups.length) updateDocuments()
|
if (!documents.length && !groups.length) updateDocuments()
|
||||||
}, [documents.length, groups.length])
|
}, [documents.length, groups.length])
|
||||||
@ -114,6 +128,8 @@ export function ProjectProvider({ children, projectProps }: Props) {
|
|||||||
requestAddProcessedArea,
|
requestAddProcessedArea,
|
||||||
requestUpdateDocumentUserMarkdown,
|
requestUpdateDocumentUserMarkdown,
|
||||||
getUserMarkdownByDocumentId,
|
getUserMarkdownByDocumentId,
|
||||||
|
currentSession,
|
||||||
|
createNewProject,
|
||||||
}
|
}
|
||||||
|
|
||||||
return <ProjectContext.Provider value={value}>
|
return <ProjectContext.Provider value={value}>
|
||||||
|
|||||||
@ -27,8 +27,10 @@ export type ProjectContextType = {
|
|||||||
requestAddDocumentGroup: (groupName: string) => Promise<ipc.Group>
|
requestAddDocumentGroup: (groupName: string) => Promise<ipc.Group>
|
||||||
requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise<ipc.UserMarkdown>
|
requestUpdateDocumentUserMarkdown: (documentId: string, markdown: string) => Promise<ipc.UserMarkdown>
|
||||||
getUserMarkdownByDocumentId: (documentId: string) => Promise<ipc.UserMarkdown>
|
getUserMarkdownByDocumentId: (documentId: string) => Promise<ipc.UserMarkdown>
|
||||||
selectedAreaId: string,
|
selectedAreaId: string
|
||||||
setSelectedAreaId: (id: string) => void,
|
setSelectedAreaId: (id: string) => void
|
||||||
selectedDocumentId: string
|
selectedDocumentId: string
|
||||||
setSelectedDocumentId: (id: string) => void
|
setSelectedDocumentId: (id: string) => void
|
||||||
|
currentSession: ipc.Session
|
||||||
|
createNewProject: (name: string) => Promise<ipc.Session>
|
||||||
} & ProjectProps
|
} & ProjectProps
|
||||||
7
frontend/package-lock.json
generated
7
frontend/package-lock.json
generated
@ -12,7 +12,6 @@
|
|||||||
"@heroicons/react": "^2.0.13",
|
"@heroicons/react": "^2.0.13",
|
||||||
"@monaco-editor/react": "^4.4.6",
|
"@monaco-editor/react": "^4.4.6",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"monaco-editor": "^0.34.1",
|
|
||||||
"next": "^13.1.1",
|
"next": "^13.1.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
@ -3589,7 +3588,8 @@
|
|||||||
"node_modules/monaco-editor": {
|
"node_modules/monaco-editor": {
|
||||||
"version": "0.34.1",
|
"version": "0.34.1",
|
||||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz",
|
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz",
|
||||||
"integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ=="
|
"integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ==",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/mri": {
|
"node_modules/mri": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@ -7576,7 +7576,8 @@
|
|||||||
"monaco-editor": {
|
"monaco-editor": {
|
||||||
"version": "0.34.1",
|
"version": "0.34.1",
|
||||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz",
|
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz",
|
||||||
"integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ=="
|
"integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ==",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"mri": {
|
"mri": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
"@heroicons/react": "^2.0.13",
|
"@heroicons/react": "^2.0.13",
|
||||||
"@monaco-editor/react": "^4.4.6",
|
"@monaco-editor/react": "^4.4.6",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"monaco-editor": "^0.34.1",
|
|
||||||
"next": "^13.1.1",
|
"next": "^13.1.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
963e9c454713999e77f8d595ec4cc5ea
|
db04e8c6f18963bc94c89200059f2f38
|
||||||
@ -1,22 +1,24 @@
|
|||||||
import { NextPage } from 'next'
|
import { NextPage } from 'next'
|
||||||
import { useState } from 'react'
|
|
||||||
import MainHead from '../components/head'
|
import MainHead from '../components/head'
|
||||||
|
import MainProject from '../components/project/Main'
|
||||||
import MainWorkspace from '../components/workspace/Main'
|
import MainWorkspace from '../components/workspace/Main'
|
||||||
import Navigation from '../components/workspace/Navigation'
|
import Navigation from '../components/workspace/Navigation'
|
||||||
|
import { useProject } from '../context/Project/provider'
|
||||||
enum workspaces {
|
|
||||||
PROCESSOR = 'PROCESSOR',
|
|
||||||
TEXTEDITOR = 'TEXTEDITOR'
|
|
||||||
}
|
|
||||||
|
|
||||||
const Home: NextPage = () => {
|
const Home: NextPage = () => {
|
||||||
const [ selectedWorkSpace, setSelectedWorkSpace ] = useState(workspaces.PROCESSOR)
|
|
||||||
|
const { currentSession } = useProject()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MainHead />
|
<MainHead />
|
||||||
<Navigation />
|
{!currentSession?.project?.id
|
||||||
<MainWorkspace selectedWorkSpace={selectedWorkSpace} />
|
? <MainProject />
|
||||||
|
: <>
|
||||||
|
<Navigation />
|
||||||
|
<MainWorkspace />
|
||||||
|
</>
|
||||||
|
}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
4
frontend/wailsjs/wailsjs/go/ipc/Channel.d.ts
vendored
4
frontend/wailsjs/wailsjs/go/ipc/Channel.d.ts
vendored
@ -2,6 +2,10 @@
|
|||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
import {ipc} from '../models';
|
import {ipc} from '../models';
|
||||||
|
|
||||||
|
export function CreateNewProject(arg1:string):Promise<ipc.Session>;
|
||||||
|
|
||||||
|
export function GetCurrentSession():Promise<ipc.Session>;
|
||||||
|
|
||||||
export function GetDocumentById(arg1:string):Promise<ipc.Document>;
|
export function GetDocumentById(arg1:string):Promise<ipc.Document>;
|
||||||
|
|
||||||
export function GetDocuments():Promise<ipc.GetDocumentsResponse>;
|
export function GetDocuments():Promise<ipc.GetDocumentsResponse>;
|
||||||
|
|||||||
@ -2,6 +2,14 @@
|
|||||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||||
// This file is automatically generated. DO NOT EDIT
|
// This file is automatically generated. DO NOT EDIT
|
||||||
|
|
||||||
|
export function CreateNewProject(arg1) {
|
||||||
|
return window['go']['ipc']['Channel']['CreateNewProject'](arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GetCurrentSession() {
|
||||||
|
return window['go']['ipc']['Channel']['GetCurrentSession']();
|
||||||
|
}
|
||||||
|
|
||||||
export function GetDocumentById(arg1) {
|
export function GetDocumentById(arg1) {
|
||||||
return window['go']['ipc']['Channel']['GetDocumentById'](arg1);
|
return window['go']['ipc']['Channel']['GetDocumentById'](arg1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,6 @@ export namespace ipc {
|
|||||||
path: string;
|
path: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
areas: Area[];
|
areas: Area[];
|
||||||
modifiedMarkdown: string;
|
|
||||||
|
|
||||||
static createFrom(source: any = {}) {
|
static createFrom(source: any = {}) {
|
||||||
return new Document(source);
|
return new Document(source);
|
||||||
@ -43,7 +42,6 @@ export namespace ipc {
|
|||||||
this.path = source["path"];
|
this.path = source["path"];
|
||||||
this.projectId = source["projectId"];
|
this.projectId = source["projectId"];
|
||||||
this.areas = this.convertValues(source["areas"], Area);
|
this.areas = this.convertValues(source["areas"], Area);
|
||||||
this.modifiedMarkdown = source["modifiedMarkdown"];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||||
@ -115,6 +113,62 @@ export namespace ipc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class User {
|
||||||
|
id: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
avatarPath: string;
|
||||||
|
authToken: string;
|
||||||
|
|
||||||
|
static createFrom(source: any = {}) {
|
||||||
|
return new User(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(source: any = {}) {
|
||||||
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
|
this.id = source["id"];
|
||||||
|
this.firstName = source["firstName"];
|
||||||
|
this.lastName = source["lastName"];
|
||||||
|
this.avatarPath = source["avatarPath"];
|
||||||
|
this.authToken = source["authToken"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class Organization {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
logoPath: string;
|
||||||
|
users: User[];
|
||||||
|
|
||||||
|
static createFrom(source: any = {}) {
|
||||||
|
return new Organization(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(source: any = {}) {
|
||||||
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
|
this.id = source["id"];
|
||||||
|
this.name = source["name"];
|
||||||
|
this.logoPath = source["logoPath"];
|
||||||
|
this.users = this.convertValues(source["users"], User);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||||
|
if (!a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (a.slice) {
|
||||||
|
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||||
|
} else if ("object" === typeof a) {
|
||||||
|
if (asMap) {
|
||||||
|
for (const key of Object.keys(a)) {
|
||||||
|
a[key] = new classs(a[key]);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return new classs(a);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
export class ProcessedBoundingBox {
|
export class ProcessedBoundingBox {
|
||||||
x0: number;
|
x0: number;
|
||||||
y0: number;
|
y0: number;
|
||||||
@ -277,6 +331,55 @@ export namespace ipc {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class Project {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
static createFrom(source: any = {}) {
|
||||||
|
return new Project(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(source: any = {}) {
|
||||||
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
|
this.id = source["id"];
|
||||||
|
this.name = source["name"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class Session {
|
||||||
|
project: Project;
|
||||||
|
organization: Organization;
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
static createFrom(source: any = {}) {
|
||||||
|
return new Session(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(source: any = {}) {
|
||||||
|
if ('string' === typeof source) source = JSON.parse(source);
|
||||||
|
this.project = this.convertValues(source["project"], Project);
|
||||||
|
this.organization = this.convertValues(source["organization"], Organization);
|
||||||
|
this.user = this.convertValues(source["user"], User);
|
||||||
|
}
|
||||||
|
|
||||||
|
convertValues(a: any, classs: any, asMap: boolean = false): any {
|
||||||
|
if (!a) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (a.slice) {
|
||||||
|
return (a as any[]).map(elem => this.convertValues(elem, classs));
|
||||||
|
} else if ("object" === typeof a) {
|
||||||
|
if (asMap) {
|
||||||
|
for (const key of Object.keys(a)) {
|
||||||
|
a[key] = new classs(a[key]);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return new classs(a);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class UserMarkdown {
|
export class UserMarkdown {
|
||||||
id: string;
|
id: string;
|
||||||
documentId: string;
|
documentId: string;
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package ipc
|
|||||||
import (
|
import (
|
||||||
app "textualize/core/App"
|
app "textualize/core/App"
|
||||||
document "textualize/core/Document"
|
document "textualize/core/Document"
|
||||||
|
session "textualize/core/Session"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||||
@ -18,14 +19,7 @@ func (c *Channel) GetDocumentById(id string) Document {
|
|||||||
var jsonAreas []Area
|
var jsonAreas []Area
|
||||||
|
|
||||||
for _, a := range foundDocument.Areas {
|
for _, a := range foundDocument.Areas {
|
||||||
jsonAreas = append(jsonAreas, Area{
|
jsonAreas = append(jsonAreas, Area(a))
|
||||||
Id: a.Id,
|
|
||||||
Name: a.Name,
|
|
||||||
StartX: a.StartX,
|
|
||||||
StartY: a.StartY,
|
|
||||||
EndX: a.EndX,
|
|
||||||
EndY: a.EndY,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
response := Document{
|
response := Document{
|
||||||
Id: foundDocument.Id,
|
Id: foundDocument.Id,
|
||||||
@ -50,14 +44,7 @@ func (c *Channel) GetDocuments() GetDocumentsResponse {
|
|||||||
for _, d := range documents {
|
for _, d := range documents {
|
||||||
jsonAreas := make([]Area, 0)
|
jsonAreas := make([]Area, 0)
|
||||||
for _, a := range d.Areas {
|
for _, a := range d.Areas {
|
||||||
jsonAreas = append(jsonAreas, Area{
|
jsonAreas = append(jsonAreas, Area(a))
|
||||||
Id: a.Id,
|
|
||||||
Name: a.Name,
|
|
||||||
StartX: a.StartX,
|
|
||||||
StartY: a.StartY,
|
|
||||||
EndX: a.EndX,
|
|
||||||
EndY: a.EndY,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonDocument := Document{
|
jsonDocument := Document{
|
||||||
@ -105,7 +92,7 @@ func (c *Channel) RequestAddDocument(groupId string, documentName string) Docume
|
|||||||
Name: documentName,
|
Name: documentName,
|
||||||
Path: filePath,
|
Path: filePath,
|
||||||
GroupId: groupId,
|
GroupId: groupId,
|
||||||
ProjectId: "something else", // TODO: Change me
|
ProjectId: session.GetInstance().Project.Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
document.GetDocumentCollection().AddDocument(newDocument)
|
document.GetDocumentCollection().AddDocument(newDocument)
|
||||||
@ -163,7 +150,7 @@ func (c *Channel) RequestAddDocumentGroup(name string) Group {
|
|||||||
newGroup := document.Group{
|
newGroup := document.Group{
|
||||||
Id: uuid.NewString(),
|
Id: uuid.NewString(),
|
||||||
Name: name,
|
Name: name,
|
||||||
ProjectId: "something else", // TODO: change me
|
ProjectId: session.GetInstance().Project.Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
document.GetGroupCollection().AddDocumentGroup(newGroup)
|
document.GetGroupCollection().AddDocumentGroup(newGroup)
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
package ipc
|
package ipc
|
||||||
|
|
||||||
type Document struct {
|
type Document struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
GroupId string `json:"groupId"`
|
GroupId string `json:"groupId"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
ProjectId string `json:"projectId"`
|
ProjectId string `json:"projectId"`
|
||||||
Areas []Area `json:"areas"`
|
Areas []Area `json:"areas"`
|
||||||
ModifiedMarkdown string `json:"modifiedMarkdown"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DocumentCollection struct {
|
type DocumentCollection struct {
|
||||||
@ -79,3 +78,29 @@ type UserMarkdown struct {
|
|||||||
type UserMarkdownCollection struct {
|
type UserMarkdownCollection struct {
|
||||||
Values []UserMarkdown `json:"values"`
|
Values []UserMarkdown `json:"values"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
FirstName string `json:"firstName"`
|
||||||
|
LastName string `json:"lastName"`
|
||||||
|
AvatarPath string `json:"avatarPath"`
|
||||||
|
AuthToken string `json:"authToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Organization struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
LogoPath string `json:"logoPath"`
|
||||||
|
Users []User `json:"users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
Id string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Session struct {
|
||||||
|
Project Project `json:"project"`
|
||||||
|
Organization Organization `json:"organization"`
|
||||||
|
User User `json:"user"`
|
||||||
|
}
|
||||||
|
|||||||
38
ipc/Session.go
Normal file
38
ipc/Session.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package ipc
|
||||||
|
|
||||||
|
import (
|
||||||
|
session "textualize/core/Session"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Channel) GetCurrentSession() Session {
|
||||||
|
currentSession := session.GetInstance()
|
||||||
|
|
||||||
|
var sessionUsers []User
|
||||||
|
for _, u := range currentSession.Organization.Users {
|
||||||
|
sessionUsers = append(sessionUsers, User(u))
|
||||||
|
}
|
||||||
|
|
||||||
|
return Session{
|
||||||
|
Project: Project(currentSession.Project),
|
||||||
|
User: User(currentSession.User),
|
||||||
|
Organization: Organization{
|
||||||
|
Id: currentSession.Organization.Id,
|
||||||
|
Name: currentSession.Project.Name,
|
||||||
|
LogoPath: currentSession.Organization.LogoPath,
|
||||||
|
Users: sessionUsers,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Channel) CreateNewProject(name string) Session {
|
||||||
|
currentSession := session.GetInstance()
|
||||||
|
|
||||||
|
currentSession.Project = session.Project{
|
||||||
|
Id: uuid.NewString(),
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.GetCurrentSession()
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user