Cover Files rename conflict feedback

This commit is contained in:
mirivlad 2026-07-01 18:58:31 +08:00
parent 029bb7a1a8
commit 74c627f706
2 changed files with 26 additions and 1 deletions

View File

@ -114,6 +114,24 @@ test.describe('G: Files Plugin', () => {
await expect(page.locator('[data-file-name="bad"]')).toHaveCount(0); await expect(page.locator('[data-file-name="bad"]')).toHaveCount(0);
}); });
test('files explorer shows inline rename conflict errors', async ({ page }) => {
await page.locator('.wt-label').filter({ hasText: 'Project' }).click();
await openFilesTool(page);
await expect(page.locator('.files-breadcrumb')).toContainText('Project', { timeout: 10000 });
await page.locator('[data-file-name="project-only.txt"]').click();
await page.locator('[data-files-action="rename"]').click();
await page.locator('[data-files-rename-input]').fill('Notes');
await page.locator('[data-files-rename-confirm]').click();
await expect(page.locator('[data-files-rename-error]')).toBeVisible();
await expect(page.locator('[data-files-rename-error]')).toContainText('already exists');
await expect(page.locator('[data-files-rename-input]')).toBeVisible();
await expect(page.locator('[data-files-rename-input]')).toHaveValue('Notes');
await expect(page.locator('[data-file-name="project-only.txt"]')).toBeVisible();
await expect(page.locator('[data-file-name="Notes"]')).toBeVisible();
});
test('files explorer shows inline create validation errors', async ({ page }) => { test('files explorer shows inline create validation errors', async ({ page }) => {
await page.locator('.wt-label').filter({ hasText: 'Project' }).click(); await page.locator('.wt-label').filter({ hasText: 'Project' }).click();
await openFilesTool(page); await openFilesTool(page);

View File

@ -749,6 +749,10 @@
function parent(path) { path = clean(path); var i = path.lastIndexOf('/'); return i < 0 ? '' : path.slice(0, i); } function parent(path) { path = clean(path); var i = path.lastIndexOf('/'); return i < 0 ? '' : path.slice(0, i); }
function ext(name) { var i = String(name || '').lastIndexOf('.'); return i > 0 ? name.slice(i + 1).toLowerCase() : ''; } function ext(name) { var i = String(name || '').lastIndexOf('.'); return i > 0 ? name.slice(i + 1).toLowerCase() : ''; }
function base(path) { path = clean(path); var i = path.lastIndexOf('/'); return i < 0 ? path : path.slice(i + 1); } function base(path) { path = clean(path); var i = path.lastIndexOf('/'); return i < 0 ? path : path.slice(i + 1); }
function isConflictError(err) {
var message = (err && err.message) ? err.message : String(err || '');
return /conflict|already exists|exists/i.test(message);
}
function formatDate(value) { function formatDate(value) {
if (!value) return ''; if (!value) return '';
var date = new Date(value); var date = new Date(value);
@ -1064,7 +1068,10 @@
if (newName === '.' || newName === '..' || newName[0] === ' ' || newName[newName.length - 1] === ' ' || newName[newName.length - 1] === '.') { setRenameError('Invalid name'); return; } if (newName === '.' || newName === '..' || newName[0] === ' ' || newName[newName.length - 1] === ' ' || newName[newName.length - 1] === '.') { setRenameError('Invalid name'); return; }
var to = parent(renaming.relativePath); var to = parent(renaming.relativePath);
to = to ? to + '/' + newName : newName; to = to ? to + '/' + newName : newName;
api.files.move(renaming.relativePath, to, { overwrite: false }).then(function () { cancelRename(); load(); }).catch(function (err) { setRenameError('Error: ' + ((err && err.message) ? err.message : String(err))); }); api.files.move(renaming.relativePath, to, { overwrite: false }).then(function () { cancelRename(); load(); }).catch(function (err) {
if (isConflictError(err)) { setRenameError('A file with that name already exists'); return; }
setRenameError('Error: ' + ((err && err.message) ? err.message : String(err)));
});
} }
function confirmModal(message, options) { function confirmModal(message, options) {
options = options || {}; options = options || {};