PDF: separate display name and filename; show filename in picker; fix rename
- Upload dialog now has distinct display name + filename fields, both pre-filled from the uploaded file but independently editable - Rename in file picker shows and edits both display name and filename separately - Filename conflict checked against both KV store and disk (via rename_no_replace) - Display name and filename are fully independent — no longer derived from each other - Add find_pdf_references() helper in storage.mjs for future use - CSS: fp-name-wrap shows display name + dim monospace filename below it; rename mode stacks two inputs; fp-field-label for upload form labels Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
47
server.mjs
47
server.mjs
@@ -526,27 +526,27 @@ app.get('/api/pdfs', (req, res) => {
|
||||
|
||||
app.post('/api/pdfs', pdf_upload.single('file'), (req, res) => {
|
||||
if (!req.file) return fail(res, 'no file uploaded');
|
||||
const display_name = (req.body.display_name?.trim() || req.file.originalname).trim();
|
||||
if (list_pdfs().some(p => p.display_name === display_name)) {
|
||||
const display_name = req.body.display_name?.trim() || req.file.originalname;
|
||||
const filename = sanitize_pdf_filename(req.body.filename?.trim() || req.file.originalname);
|
||||
const all = list_pdfs();
|
||||
if (all.some(p => p.display_name === display_name)) {
|
||||
try { unlinkSync(join('./data/pdfs', req.file.filename)); } catch {}
|
||||
return fail(res, 'a file with that name already exists');
|
||||
return fail(res, 'a file with that display name already exists');
|
||||
}
|
||||
if (all.some(p => p.filename === filename)) {
|
||||
try { unlinkSync(join('./data/pdfs', req.file.filename)); } catch {}
|
||||
return fail(res, 'a file with that filename already exists');
|
||||
}
|
||||
const id = generate_id();
|
||||
const filename = sanitize_pdf_filename(display_name);
|
||||
const temp_path = join('./data/pdfs', req.file.filename);
|
||||
const final_path = join('./data/pdfs', filename);
|
||||
if (!rename_no_replace(temp_path, final_path)) return fail(res, 'a file with that name already exists on disk');
|
||||
if (!rename_no_replace(temp_path, final_path)) {
|
||||
try { unlinkSync(temp_path); } catch {}
|
||||
return fail(res, 'a file with that filename already exists on disk');
|
||||
}
|
||||
const thumb_prefix = join('./data/pdfs', id + '-thumb');
|
||||
const thumb_file = generate_pdf_thumb(final_path, thumb_prefix);
|
||||
const pdf = {
|
||||
id,
|
||||
filename,
|
||||
display_name,
|
||||
original_name: req.file.originalname,
|
||||
size: req.file.size,
|
||||
thumb_filename: thumb_file,
|
||||
uploaded_at: Date.now(),
|
||||
};
|
||||
const pdf = { id, filename, display_name, original_name: req.file.originalname, size: req.file.size, thumb_filename: thumb_file, uploaded_at: Date.now() };
|
||||
set_pdf(pdf);
|
||||
ok(res, { pdf });
|
||||
});
|
||||
@@ -555,16 +555,19 @@ app.put('/api/pdfs/:id', (req, res) => {
|
||||
const pdf = get_pdf(req.params.id);
|
||||
if (!pdf) return fail(res, 'not found', 404);
|
||||
const display_name = req.body.display_name?.trim();
|
||||
const filename = req.body.filename?.trim() ? sanitize_pdf_filename(req.body.filename.trim()) : pdf.filename;
|
||||
if (!display_name) return fail(res, 'display_name is required');
|
||||
if (list_pdfs().some(p => p.display_name === display_name && p.id !== pdf.id)) {
|
||||
return fail(res, 'a file with that name already exists');
|
||||
const all = list_pdfs();
|
||||
if (all.some(p => p.display_name === display_name && p.id !== pdf.id))
|
||||
return fail(res, 'a file with that display name already exists');
|
||||
if (all.some(p => p.filename === filename && p.id !== pdf.id))
|
||||
return fail(res, 'a file with that filename already exists');
|
||||
if (filename !== pdf.filename) {
|
||||
const new_path = join('./data/pdfs', filename);
|
||||
if (!rename_no_replace(join('./data/pdfs', pdf.filename), new_path))
|
||||
return fail(res, 'a file with that filename already exists on disk');
|
||||
}
|
||||
const new_filename = sanitize_pdf_filename(display_name);
|
||||
if (new_filename !== pdf.filename) {
|
||||
const new_path = join('./data/pdfs', new_filename);
|
||||
if (!rename_no_replace(join('./data/pdfs', pdf.filename), new_path)) return fail(res, 'a file with that name already exists on disk');
|
||||
}
|
||||
const updated = { ...pdf, display_name, filename: new_filename };
|
||||
const updated = { ...pdf, display_name, filename };
|
||||
set_pdf(updated);
|
||||
ok(res, { pdf: updated });
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user