Skip to content

Commit

Permalink
Merge pull request #47 from labscommunity/feat/create-edit-file
Browse files Browse the repository at this point in the history
feat: Support creating and editing file
  • Loading branch information
kranthicodes authored Jan 2, 2024
2 parents 687987c + b0c52b1 commit 6246d78
Show file tree
Hide file tree
Showing 13 changed files with 802 additions and 82 deletions.
12 changes: 12 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,23 @@
list-style: revert;
}

.cm-theme .cm-editor {
height: 100% !important;
}

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
.tooltip {
@apply invisible absolute;
}

.has-tooltip:hover .tooltip {
@apply visible z-50;
}

input[type='number']::-webkit-inner-spin-button,
input[type='number']::-webkit-outer-spin-button {
-webkit-appearance: none;
Expand Down
5 changes: 3 additions & 2 deletions src/pages/pull/read/tabs/files/FileCompareComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EditorState } from '@codemirror/state'
import { langs } from '@uiw/codemirror-extensions-langs'
import { githubLight } from '@uiw/codemirror-theme-github'
import { EditorView } from 'codemirror'
import { useEffect, useState } from 'react'
import CodeMirrorMerge from 'react-codemirror-merge'
Expand Down Expand Up @@ -49,14 +50,14 @@ export default function FileCompareComponent({ fileStatus, base, compare, repoId
const Modified = CodeMirrorMerge.Modified

return (
<div className="w-full flex flex-col border-gray-300 border-[1px] rounded-t-xl">
<div className="w-full flex flex-col border-gray-300 border-[1px] rounded-t-xl mb-4">
<div className="flex font-medium bg-gray-200 text-gray-900 px-4 py-3 border-b-[1px] border-gray-300 rounded-t-xl overflow-hidden">
{fileStatus[0]}
</div>
<CodeMirrorMerge
collapseUnchanged={{}}
className="bg-white"
theme={'dark'}
theme={githubLight}
orientation="a-b"
highlightChanges={true}
>
Expand Down
179 changes: 179 additions & 0 deletions src/pages/repository/components/tabs/code-tab/CommitFilesModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import { Dialog, Transition } from '@headlessui/react'
import { yupResolver } from '@hookform/resolvers/yup'
import clsx from 'clsx'
import React, { Fragment } from 'react'
import { FileWithPath } from 'react-dropzone'
import { useForm } from 'react-hook-form'
import toast from 'react-hot-toast'
import SVG from 'react-inlinesvg'
import { useParams } from 'react-router-dom'
import * as yup from 'yup'

import CloseCrossIcon from '@/assets/icons/close-cross.svg'
import { Button } from '@/components/common/buttons'
import CostEstimatesToolTip from '@/components/CostEstimatesToolTip'
import { withAsync } from '@/helpers/withAsync'
import { fsWithName } from '@/lib/git/helpers/fsWithName'
import { packGitRepo } from '@/lib/git/helpers/zipUtils'
import useCommit from '@/pages/repository/hooks/useCommit'
import { useGlobalStore } from '@/stores/globalStore'

type NewBranchModal = {
setIsOpen: (val: boolean) => void
isOpen: boolean
files: FileWithPath[]
setIsCommited: React.Dispatch<React.SetStateAction<boolean>>
}

const schema = yup
.object({
commit: yup.string().required('Commit message is required.')
})
.required()

export default function CommitFilesModal({ setIsOpen, setIsCommited, isOpen, files }: NewBranchModal) {
const {
register,
handleSubmit,
setValue,
formState: { errors }
} = useForm({
resolver: yupResolver(schema),
defaultValues: { commit: `Update ${files?.[0]?.name ?? ''}` }
})

const { addFiles } = useCommit()
const { id } = useParams()
const [userRepo, address, isCreateNewFile] = useGlobalStore((state) => [
state.repoCoreState.selectedRepo.repo,
state.authState.address,
state.repoCoreState.git.isCreateNewFile
])

const [fileSizes, setFileSizes] = React.useState<number[]>([])
const [repoBlobSize, setRepoBlobSize] = React.useState<number>(0)
const [isSubmitting, setIsSubmitting] = React.useState(false)

React.useEffect(() => {
if (files.length > 0) {
files.forEach((file) => setFileSizes((prev) => [...prev, file.size]))
setValue('commit', `${isCreateNewFile ? 'Add' : 'Update'} ${files?.[0]?.name ?? ''}`)
if (!repoBlobSize) captureRepoBlobSize()
}
}, [files])

function closeModal() {
setIsOpen(false)
}

async function handleCommitSubmit(data: yup.InferType<typeof schema>) {
if (files.length > 0 && userRepo) {
setIsSubmitting(true)

const { error } = await withAsync(() =>
addFiles({
files,
id: id!,
message: data.commit,
name: userRepo.name,
owner: address!,
defaultBranch: userRepo.defaultBranch || 'master'
})
)

if (!error) {
setIsCommited(true)
closeModal()
} else {
toast.error('Failed to commit changes')
}
setIsSubmitting(false)
} else {
toast.error('Please select atleast one file.')
}
}

async function captureRepoBlobSize() {
if (!userRepo) return
const fs = fsWithName(id!)
const dir = `/${userRepo.id}`

const blob = await packGitRepo({ fs, dir })

if (blob && blob.size) {
setRepoBlobSize(blob.size)
}
}

return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>

<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="w-full max-w-[368px] transform rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<div className="w-full flex justify-between align-middle">
<Dialog.Title as="h3" className="text-xl font-medium text-gray-900">
Commit changes
</Dialog.Title>
<SVG onClick={closeModal} src={CloseCrossIcon} className="w-6 h-6 cursor-pointer" />
</div>
<div className="mt-3 flex flex-col">
<div>
<label htmlFor="title" className="mb-1 block font-medium text-sm text-gray-600">
Commit message
</label>
<input
type="text"
{...register('commit')}
className={clsx(
'bg-white border-[1px] text-gray-900 text-base rounded-lg hover:shadow-[0px_2px_4px_0px_rgba(0,0,0,0.10)] focus:border-primary-500 focus:border-[1.5px] block w-full px-3 py-[10px] outline-none',
errors.commit ? 'border-red-500' : 'border-gray-300'
)}
placeholder="Example: Add README.md file"
/>
{errors.commit && <p className="text-red-500 text-sm italic mt-2">{errors.commit?.message}</p>}
</div>
</div>
<div className="mt-3">
<CostEstimatesToolTip fileSizes={[...fileSizes, repoBlobSize]} />
</div>
<div className="mt-6">
<Button
disabled={Object.keys(errors).length > 0 || isSubmitting}
isLoading={isSubmitting}
className="w-full justify-center font-medium"
onClick={handleSubmit(handleCommitSubmit)}
variant="primary-solid"
>
Commit changes
</Button>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
)
}
Loading

0 comments on commit 6246d78

Please sign in to comment.