feat: /:code/:variant URL для вариантов опти + валидация имени варианта
- Роут GET /:code/:variant → редирект на /projects/:uuid (case-insensitive) - Валидация имени варианта: только URL-безопасные символы [A-Za-z0-9._-] (бэкенд validateProjectVariantName + клиентская проверка в обеих формах) - Подсказки в UI: «Используется в URL: /КОД/Вариант» Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -207,9 +207,11 @@
|
||||
</div>
|
||||
<div>
|
||||
<label for="new-variant-value" class="block text-sm font-medium text-gray-700 mb-1">Вариант</label>
|
||||
<input id="new-variant-value" type="text" placeholder="Например: Lenovo"
|
||||
<input id="new-variant-value" type="text" placeholder="Например: B200"
|
||||
pattern="[A-Za-z0-9._-]+"
|
||||
title="Только буквы, цифры, дефис, точка, подчёркивание"
|
||||
class="w-full px-3 py-2 border rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<div class="text-xs text-gray-500 mt-1">Оставьте пустым для main нельзя — нужно уникальное значение.</div>
|
||||
<div class="text-xs text-gray-500 mt-1">Буквы, цифры, дефис, точка, подчёркивание. Используется в URL: /КОД/Вариант.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 flex justify-end gap-2">
|
||||
@@ -842,6 +844,10 @@ async function createNewVariant() {
|
||||
showToast('Укажите вариант', 'error');
|
||||
return;
|
||||
}
|
||||
if (!/^[A-Za-z0-9._-]+$/.test(variant)) {
|
||||
showToast('Имя варианта содержит недопустимые символы. Разрешены: буквы, цифры, дефис, точка, подчёркивание.', 'error');
|
||||
return;
|
||||
}
|
||||
const payload = {
|
||||
code: code,
|
||||
variant: variant,
|
||||
|
||||
Reference in New Issue
Block a user