feature: Include Format when Renaming (#143)

- New: Field inside format general tab to enable include format in rename
- New: Database migration that adds format renames table
- New: Queries to get / update rename status for a format
- Update: Format compiler checks for rename entries and add include rename field when found
- Update: Parsing improvements for incoming commit messages
This commit is contained in:
santiagosayshey
2025-02-18 01:49:38 +10:30
committed by GitHub
parent f6ad7485b1
commit 0729ac0a62
10 changed files with 230 additions and 40 deletions

View File

@@ -8,10 +8,12 @@ const FormatGeneralTab = ({
description,
tags,
error,
includeInRename,
onNameChange,
onDescriptionChange,
onAddTag,
onRemoveTag
onRemoveTag,
onIncludeInRenameChange
}) => {
const [newTag, setNewTag] = useState('');
@@ -41,13 +43,36 @@ const FormatGeneralTab = ({
<div className='space-y-8'>
{/* Name Input */}
<div className='space-y-2'>
<div className='space-y-1'>
<label className='text-sm font-medium text-gray-700 dark:text-gray-300'>
Format Name
</label>
<p className='text-xs text-gray-500 dark:text-gray-400'>
Give your format a descriptive name
</p>
<div className='flex justify-between items-start'>
<div className='space-y-1'>
<label className='text-sm font-medium text-gray-700 dark:text-gray-300'>
Format Name
</label>
<p className='text-xs text-gray-500 dark:text-gray-400'>
Give your format a descriptive name
</p>
</div>
<div className='flex flex-col items-end space-y-1'>
<label className='flex items-center space-x-2 text-sm font-medium text-gray-700 dark:text-gray-300 cursor-pointer'>
<input
type='checkbox'
checked={includeInRename}
onChange={e =>
onIncludeInRenameChange(
e.target.checked
)
}
className='rounded border-gray-300 dark:border-gray-600
text-blue-500 focus:ring-blue-500
h-4 w-4 cursor-pointer
transition-colors duration-200'
/>
<span>Include Custom Format When Renaming</span>
</label>
<p className='text-xs text-gray-500 dark:text-gray-400'>
Include this format's name in renamed files
</p>
</div>
</div>
<input
type='text'
@@ -166,10 +191,12 @@ FormatGeneralTab.propTypes = {
description: PropTypes.string.isRequired,
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
error: PropTypes.string,
includeInRename: PropTypes.bool.isRequired,
onNameChange: PropTypes.func.isRequired,
onDescriptionChange: PropTypes.func.isRequired,
onAddTag: PropTypes.func.isRequired,
onRemoveTag: PropTypes.func.isRequired
onRemoveTag: PropTypes.func.isRequired,
onIncludeInRenameChange: PropTypes.func.isRequired
};
export default FormatGeneralTab;

View File

@@ -27,7 +27,9 @@ const FormatModal = ({
onConditionsChange,
onTestsChange,
onActiveTabChange,
onRunTests
onRunTests,
includeInRename,
onIncludeInRenameChange
}) => {
const tabs = [
{id: 'general', label: 'General'},
@@ -95,12 +97,14 @@ const FormatModal = ({
description={description}
tags={tags}
error={error}
includeInRename={includeInRename}
onNameChange={onNameChange}
onDescriptionChange={onDescriptionChange}
onAddTag={tag => onTagsChange([...tags, tag])}
onRemoveTag={tag =>
onTagsChange(tags.filter(t => t !== tag))
}
onIncludeInRenameChange={onIncludeInRenameChange}
/>
)}
{activeTab === 'conditions' && (
@@ -145,7 +149,9 @@ FormatModal.propTypes = {
onConditionsChange: PropTypes.func.isRequired,
onTestsChange: PropTypes.func.isRequired,
onActiveTabChange: PropTypes.func.isRequired,
onRunTests: PropTypes.func.isRequired
onRunTests: PropTypes.func.isRequired,
includeInRename: PropTypes.bool.isRequired,
onIncludeInRenameChange: PropTypes.func.isRequired
};
export default FormatModal;

View File

@@ -118,6 +118,7 @@ function FormatPage() {
activeTab,
isDeleting,
isRunningTests,
includeInRename,
setName,
setDescription,
setTags,
@@ -125,6 +126,7 @@ function FormatPage() {
setTests,
setActiveTab,
setIsDeleting,
setIncludeInRename,
initializeForm,
handleSave,
handleRunTests,
@@ -408,6 +410,8 @@ function FormatPage() {
onRunTests={handleRunTests}
onSave={handleSave}
onDelete={handleDelete}
includeInRename={includeInRename}
onIncludeInRenameChange={setIncludeInRename}
/>
<ImportModal

View File

@@ -1,11 +1,28 @@
import React from 'react';
import PropTypes from 'prop-types';
import {GitCommit, Info} from 'lucide-react';
import Tooltip from '@ui/Tooltip';
const DiffCommit = ({commitMessage}) => {
const {subject, body} = commitMessage;
const renderLine = (line, index) => {
// Just handle basic bullet points (* or -)
if (line.startsWith('* ') || line.startsWith('- ')) {
return (
<div key={index} className='flex items-center py-0.5'>
<span className='mr-2 h-1 w-1 flex-shrink-0 rounded-full bg-gray-400' />
<span>{line.slice(2)}</span>
</div>
);
}
return (
<div key={index} className='py-0.5'>
{line}
</div>
);
};
return (
<div className='overflow-hidden rounded-lg border border-gray-700'>
<table className='w-full'>
@@ -31,18 +48,12 @@ const DiffCommit = ({commitMessage}) => {
{body && (
<tr className='bg-gray-900'>
<td className='py-3 px-4'>
<div className='text-gray-300 text-sm whitespace-pre-wrap'>
{body.split('\n').map((line, index) => (
<div
key={index}
className={`${
line.startsWith('- ')
? 'ml-4'
: ''
}`}>
{line}
</div>
))}
<div className='text-gray-300 text-sm'>
{body
.split('\n')
.map((line, index) =>
renderLine(line, index)
)}
</div>
</td>
</tr>
@@ -53,11 +64,4 @@ const DiffCommit = ({commitMessage}) => {
);
};
DiffCommit.propTypes = {
commitMessage: PropTypes.shape({
subject: PropTypes.string.isRequired,
body: PropTypes.string
})
};
export default DiffCommit;

View File

@@ -12,6 +12,7 @@ export const useFormatModal = (initialFormat, onSuccess) => {
const [conditions, setConditions] = useState([]);
const [tests, setTests] = useState([]);
const [isCloning, setIsCloning] = useState(false);
const [includeInRename, setIncludeInRename] = useState(false);
// Enhanced UI state with field-specific errors
const [formErrors, setFormErrors] = useState({
@@ -78,6 +79,7 @@ export const useFormatModal = (initialFormat, onSuccess) => {
setTags([]);
setConditions([]);
setTests([]);
setIncludeInRename(false);
setFormErrors({name: '', conditions: '', tests: '', general: ''});
setIsDeleting(false);
setIsCloning(false);
@@ -92,6 +94,7 @@ export const useFormatModal = (initialFormat, onSuccess) => {
setTags(format.tags || []);
setConditions(format.conditions || []);
setTests(format.tests || []);
setIncludeInRename(format.metadata?.includeInRename || false);
setIsCloning(cloning || false);
}, 0);
}
@@ -181,7 +184,10 @@ export const useFormatModal = (initialFormat, onSuccess) => {
description,
tags,
conditions,
tests
tests,
metadata: {
includeInRename
}
};
if (initialFormat && !isCloning) {
@@ -284,6 +290,7 @@ export const useFormatModal = (initialFormat, onSuccess) => {
tags,
conditions,
tests,
includeInRename,
// UI state
formErrors,
activeTab,
@@ -298,6 +305,7 @@ export const useFormatModal = (initialFormat, onSuccess) => {
setTests,
setActiveTab,
setIsDeleting,
setIncludeInRename,
// Main handlers
initializeForm,
handleSave,