Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7c1e6eb
Final sync
NaviAndrei Mar 27, 2026
839cd83
Merge branch 'main' of https://github.com/NaviAndrei/PromptLibrary
NaviAndrei Mar 27, 2026
c9342ae
Merge branch 'main' of https://github.com/NaviAndrei/PromptLibrary
NaviAndrei Mar 27, 2026
dd87efb
build: prepare release v1.1.1 (smart tags, state sync fixes)
NaviAndrei Mar 27, 2026
bc952db
style: fix grid masonry view layout logic
NaviAndrei Mar 27, 2026
84d8fb8
style: increase container width for masonry grid overflow
NaviAndrei Mar 27, 2026
d50292b
style: expand container max-width to 1400px for 3+ column layouts
NaviAndrei Mar 27, 2026
f5d6f79
style: force 3 columns natively using column-count and media queries
NaviAndrei Mar 27, 2026
290f8ae
feat: add global dark mode toggle
NaviAndrei Mar 27, 2026
0812697
Merge remote-tracking branch 'origin/main' into feature/dark-mode
NaviAndrei Mar 27, 2026
223af2a
feat: improve multi-tag autocomplete in PromptForm
NaviAndrei Mar 27, 2026
0d4550c
feat: Smart Workspaces, Variable Injector, Version History with LCS diff
NaviAndrei Mar 27, 2026
c8e63a6
fix: resolve merge conflicts between main and dark mode features
NaviAndrei Mar 27, 2026
b4442a8
chore: translate full project to English (UI, Docs, Comments)
NaviAndrei Mar 27, 2026
0d6928c
fix(workspace): resolve linter error in delete handler and finalize E…
NaviAndrei Mar 27, 2026
5c1099e
Update src/App.tsx
NaviAndrei Mar 27, 2026
a7fa78c
fix: address PR accessibility, key collisions, and async copy issues …
NaviAndrei Mar 27, 2026
75f5812
fix(app): ensure workspace consistency and optimize stats UI (English…
NaviAndrei Mar 27, 2026
46eca91
fix: optimize workspace lookup in list and fix small typo in form
NaviAndrei Mar 27, 2026
bbbe858
fix: memoize diff view, cap LCS lines, fix snapshot timestamp for sta…
NaviAndrei Mar 27, 2026
f9e8f0b
i18n: translate all Romanian UI text and comments to English
NaviAndrei Mar 28, 2026
e89b415
merge: resolve index.css conflict — keep EN translations over RO comm…
NaviAndrei Mar 28, 2026
1ec97d3
chore: release v1.2.5 - Added IndexedDB, PWA Offline Sync, and FlexSe…
NaviAndrei Mar 28, 2026
17ac822
fix(ci): resolve vite-plugin-pwa peer dependency conflict with Vite 8
NaviAndrei Mar 28, 2026
4028c50
fix: production build optimizations and IndexedDB schema refinement
NaviAndrei Mar 28, 2026
f75f457
fix: resolve all type errors and Vite 8 Rolldown build compatibility
NaviAndrei Mar 28, 2026
db0718e
fix(lint): remove unused eslint-disable directive in SearchService.ts
NaviAndrei Mar 28, 2026
e693078
Merge branch 'main' into release/v1.2.5
NaviAndrei Mar 28, 2026
d91a61d
fix: add legacyKey param to useIndexedDB to preserve prompt-history m…
Copilot Mar 28, 2026
82296b6
fix: incremental search index updates and real browser quota in Stora…
Copilot Mar 28, 2026
007e057
fix(hooks): add legacyKey to useEffect dependency array to satisfy ex…
NaviAndrei Mar 28, 2026
e4f4883
fix: improve regex to detect complex variable syntax
NaviAndrei Apr 3, 2026
fcbf9b7
Merge branch 'main' into release/v1.2.5
NaviAndrei Apr 3, 2026
27d66ea
chore: release v1.2.6
NaviAndrei Apr 3, 2026
9b75f25
fix(ui): use variable hints as input placeholders
NaviAndrei Apr 3, 2026
e834331
fix(ui): add independent scrollbar to sidebar
NaviAndrei Apr 3, 2026
821d3a4
chore: release v1.2.8 - Sidebar UX improvements
NaviAndrei Apr 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.2.8] - 2026-04-03

### Changed 🎨
- **Sidebar UX**: Adăugat scrollable container independent și scrollbar minimalist pentru coloana stângă (Workspaces, Tags, Templates), prevenind scroll-ul întregii pagini pe liste lungi.

## [1.2.7] - 2026-04-03

### Fixed 🛠️
- Adăugat suport pentru extragerea textului `hint` din variabile și utilizarea acestuia ca `placeholder` dinamic în interfața grafică (`VariableInjector`).

## [1.2.6] - 2026-04-03

### Fixed 🛠️
- Imbunătățit regex-ul din `VariableInjector` și `TemplateManager` pentru a detecta impecabil variabile cu sintaxă complexă (ex: `{{VAR=hint cu caractere speciale}}`).
- Rezolvat conflictele de compilare (Vite 8 Rolldown) și fixat tipabilitățile TypeScript din zona de căutare hibridă FlexSearch.
- Fixat dependențele peer conflictuale la integrarea modulului `vite-plugin-pwa` offline.
- Adăugat suport pentru persistența datelor migratoare `prompt-history` printr-un fix minor de compatibilitate pentru hook-urile React (`useIndexedDB`).
Comment on lines +22 to +24
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 1.2.6 changelog entry lists multiple fixes (Vite/Rolldown compile conflicts, FlexSearch typings, peer deps, IndexedDB hook compatibility) that are not part of this PR diff. Please ensure each changelog entry matches the actual code included in the corresponding version (move/remove items as needed), and keep language consistent with the rest of the changelog.

Suggested change
- Rezolvat conflictele de compilare (Vite 8 Rolldown) și fixat tipabilitățile TypeScript din zona de căutare hibridă FlexSearch.
- Fixat dependențele peer conflictuale la integrarea modulului `vite-plugin-pwa` offline.
- Adăugat suport pentru persistența datelor migratoare `prompt-history` printr-un fix minor de compatibilitate pentru hook-urile React (`useIndexedDB`).

Copilot uses AI. Check for mistakes.

## [1.2.5] - 2026-03-28

### Added 🚀
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "prompt-library",
"private": false,
"description": "A modern, sleek web application for managing AI prompts. Built with React, TypeScript, and Vite.",
"version": "1.2.5",
"version": "1.2.8",
"author": "Ivan Andrei (NaviAndrei)",
Comment on lines 3 to 6
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR title indicates a v1.2.5 release, but package.json is bumping to 1.2.8. Please align the PR title/release branch naming and the version/changelog so the release automation and tagging are consistent.

Copilot uses AI. Check for mistakes.
"license": "MIT",
"type": "module",
Expand Down
4 changes: 2 additions & 2 deletions src/components/TemplateManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export function TemplateManager({ onSelectTemplate }: TemplateManagerProps) {
return;
}

// Simple regex to extract variables from the template body
const variables = Array.from(form.templateBody.matchAll(/\{\{(\w+)(?::\w+)?(?::[^}]+)?\}\}/g)).map(m => m[1]);
// Permissive regex to extract variables from the template body (supporting {{var}}, {{var=hint}}, {{var:type}})
const variables = Array.from(form.templateBody.matchAll(/\{\{([\w\s-]+)(?:[:=][^}]+)?\}\}/g)).map(m => m[1].trim());

const newTemplate: PromptTemplate = {
id: crypto.randomUUID(),
Expand Down
34 changes: 26 additions & 8 deletions src/components/VariableInjector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ interface VariableInfo {
name: string;
type: string;
raw: string;
hint?: string;
}

interface VariablePreset {
Expand All @@ -34,22 +35,36 @@ const TYPE_MAP: Record<string, string> = {

// Detects all unique variables of type {{name:type:options}} from text
function extractVariables(text: string): (VariableInfo & { options?: string[] })[] {
const regex = /\{\{(\w+)(?::(\w+))?(?::([^}]+))?\}\}/g;
// Permissive regex to support {{var}}, {{var:type}}, {{var:select:a,b}}, and {{var=hint}}
const regex = /\{\{([\w\s-]+)(?:[:=]([^}]+))?\}\}/g;
const seen = new Set<string>();
const variables: (VariableInfo & { options?: string[] })[] = [];

let match;
while ((match = regex.exec(text)) !== null) {
const name = match[1];
const typeHint = (match[2] || 'text').toLowerCase();
const optionsRaw = match[3];
const name = match[1].trim();
const fullHint = (match[2] || '').trim();

if (!seen.has(name)) {
seen.add(name);

// Extract type and options if colon syntax is used
let typeHint = 'text';
let optionsRaw = '';

if (fullHint.includes(':')) {
const parts = fullHint.split(':');
typeHint = parts[0].toLowerCase();
optionsRaw = parts.slice(1).join(':');
} else if (fullHint && !fullHint.includes('=') && TYPE_MAP[fullHint.toLowerCase()]) {
Comment on lines +55 to +59
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extractVariables treats any fullHint containing ':' as type/options syntax, even when the variable used '=' hint syntax (e.g. {{var=Hint: with colon}}). This causes the hint to be mis-parsed and dropped. Consider capturing the delimiter in the regex (':' vs '=') and only parsing type/options when the delimiter is ':', leaving '=' hints intact even if they contain colons.

Copilot uses AI. Check for mistakes.
// If it's a recognized type (e.g. {{date:date}}), use it
typeHint = fullHint.toLowerCase();
}
const info: VariableInfo & { options?: string[] } = {
name,
type: TYPE_MAP[typeHint] || 'text',
raw: match[0],
hint: fullHint && !TYPE_MAP[fullHint.toLowerCase()] && !fullHint.includes(':') ? fullHint : undefined,
};

if (typeHint === 'select' && optionsRaw) {
Expand All @@ -62,10 +77,13 @@ function extractVariables(text: string): (VariableInfo & { options?: string[] })
return variables;
}

// Replaces all occurrences of {{variable}} or {{variable:type}} with the corresponding value
function injectVariables(text: string, values: Record<string, string>): string {
return text.replace(/\{\{(\w+)(?::(\w+))?(?::([^}]+))?\}\}/g, (_, name) => {
return values[name] !== undefined && values[name] !== '' ? values[name] : `{{${name}}}`;
const regex = /\{\{([\w\s-]+)(?:[:=]([^}]+))?\}\}/g;
return text.replace(regex, (fullMatch, name) => {
const trimmedName = name.trim();
return values[trimmedName] !== undefined && values[trimmedName] !== ''
? values[trimmedName]
: fullMatch;
});
}

Expand Down Expand Up @@ -187,7 +205,7 @@ export function VariableInjector({ body }: VariableInjectorProps) {
<input
type={v.type}
className={`variable-input ${v.type === 'number' ? 'variable-input-number' : ''}`}
placeholder={`Value for ${v.name}`}
placeholder={v.hint || `Value for ${v.name}`}
value={values[v.name] || ''}
onChange={e => handleChange(v.name, e.target.value)}
aria-label={`Enter value for variable ${v.name}`}
Expand Down
18 changes: 17 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,23 @@ button {
display: flex;
flex-direction: column;
gap: 1.5rem;
min-height: calc(100vh - 4rem);
max-height: calc(100vh - 4rem);
overflow-y: auto;
}

/* Custom minimal scrollbar for sidebar */
.sidebar::-webkit-scrollbar {
width: 6px;
}
.sidebar::-webkit-scrollbar-track {
background: transparent;
}
.sidebar::-webkit-scrollbar-thumb {
background-color: var(--border-color);
border-radius: var(--radius-md);
}
.sidebar::-webkit-scrollbar-thumb:hover {
background-color: var(--text-muted);
}

.sidebar-header {
Expand Down
Loading