Skip to content

Commit 68e1ed8

Browse files
committed
feat: show edit snippet view when user clicks on a snippet
1 parent b98cf3b commit 68e1ed8

File tree

7 files changed

+555
-9
lines changed

7 files changed

+555
-9
lines changed

src/extensionsIntegrated/CustomSnippets/htmlContent/snippets-panel.html

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,51 @@
110110
<button disabled>Save</button>
111111
</div>
112112
</div>
113+
114+
<!--this view will open up when user clicks on a snippet item to edit it-->
115+
<div id="custom-snippets-edit" class="custom-snippets-edit hidden">
116+
<div class="form-row">
117+
<div id="edit-abbr-box-wrapper">
118+
<label for="edit-abbr-box"
119+
title="Enter a short abbreviation (e.g., 'clg', 'fn', 'div'). This is what you'll type to trigger the snippet."
120+
data-placement="top">
121+
Abbreviation:
122+
</label>
123+
<input id="edit-abbr-box" type="text" placeholder="clg" autocomplete="off" />
124+
</div>
125+
126+
<div id="edit-desc-box-wrapper">
127+
<label for="edit-desc-box"
128+
title="Brief description of what this snippet does. Leave empty if no description needed."
129+
data-placement="top">
130+
Description (optional):
131+
</label>
132+
<input id="edit-desc-box" type="text" placeholder="console log shortcut (optional)" autocomplete="off" />
133+
</div>
134+
</div>
135+
136+
<div id="edit-template-text-box-wrapper">
137+
<label for="edit-template-text-box"
138+
title="The actual code that will be inserted. Use ${cursor} to set cursor position after insertion."
139+
data-placement="top">
140+
Template Text:
141+
</label>
142+
<textarea id="edit-template-text-box" placeholder="console.log(${cursor});" autocomplete="off"></textarea>
143+
</div>
144+
145+
<div id="edit-file-extn-box-wrapper">
146+
<label for="edit-file-extn-box"
147+
title="Specify file types where this snippet should be available (e.g., '.js', '.html', '.css'). Leave empty to make it available for all files."
148+
data-placement="top">
149+
File Extension (optional):
150+
</label>
151+
<input id="edit-file-extn-box" type="text" placeholder="Leave empty for all files, or specify like .js, .html" autocomplete="off" />
152+
</div>
153+
154+
<div id="edit-snippet-buttons">
155+
<button id="reset-snippet-btn">Reset</button>
156+
<button id="save-edit-snippet-btn" disabled>Save</button>
157+
</div>
158+
</div>
113159
</div>
114160
</div>

src/extensionsIntegrated/CustomSnippets/main.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ define(function (require, exports, module) {
108108
const $backToListMenuBtn = $("#back-to-list-menu-btn");
109109
const $filterInput = $("#filter-snippets-input");
110110

111+
const $editAbbrInput = $("#edit-abbr-box");
112+
const $editTemplateInput = $("#edit-template-text-box");
113+
const $editFileExtnInput = $("#edit-file-extn-box");
114+
const $saveEditSnippetBtn = $("#save-edit-snippet-btn");
115+
const $resetSnippetBtn = $("#reset-snippet-btn");
116+
111117
$addSnippetBtn.on("click", function () {
112118
UIHelper.showAddSnippetMenu();
113119
});
@@ -142,6 +148,27 @@ define(function (require, exports, module) {
142148
Helper.handleFileExtensionPaste(e, $(this));
143149
});
144150

151+
$editAbbrInput.on("input", Helper.toggleEditSaveButtonDisability);
152+
$editTemplateInput.on("input", Helper.toggleEditSaveButtonDisability);
153+
154+
$editFileExtnInput.on("input", function () {
155+
Helper.handleFileExtensionInput($(this));
156+
});
157+
$editFileExtnInput.on("keypress", function (e) {
158+
Helper.handleFileExtensionKeypress(e, this);
159+
});
160+
$editFileExtnInput.on("paste", function (e) {
161+
Helper.handleFileExtensionPaste(e, $(this));
162+
});
163+
164+
$saveEditSnippetBtn.on("click", function () {
165+
Driver.handleEditSaveBtnClick();
166+
});
167+
168+
$resetSnippetBtn.on("click", function () {
169+
Driver.handleResetBtnClick();
170+
});
171+
145172
// filter input event handler
146173
$filterInput.on("keyup input", function (event) {
147174
// if user presses 'esc' we clear the input field

src/extensionsIntegrated/CustomSnippets/src/UIHelper.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,14 @@ define(function (require, exports, module) {
6464
*/
6565
function showSnippetListMenu() {
6666
const $addSnippetMenu = $("#custom-snippets-add-new");
67+
const $editSnippetMenu = $("#custom-snippets-edit");
6768
const $snippetListMenu = $("#custom-snippets-list");
6869
const $backToListMenuBtn = $("#back-to-list-menu-btn");
6970
const $addNewSnippetBtn = $("#add-new-snippet-btn");
7071
const $filterSnippetsPanel = $("#filter-snippets-panel");
7172

7273
$addSnippetMenu.addClass("hidden");
74+
$editSnippetMenu.addClass("hidden");
7375
$snippetListMenu.removeClass("hidden");
7476

7577
$backToListMenuBtn.addClass("hidden");
@@ -79,6 +81,28 @@ define(function (require, exports, module) {
7981
$("#filter-snippets-input").val("");
8082
}
8183

84+
/**
85+
* This function is responsible to show the edit snippet menu
86+
* edit snippet menu is the menu which allows users to edit an existing snippet
87+
* this is called when user clicks on a snippet item (excluding delete button)
88+
*/
89+
function showEditSnippetMenu() {
90+
const $addSnippetMenu = $("#custom-snippets-add-new");
91+
const $editSnippetMenu = $("#custom-snippets-edit");
92+
const $snippetListMenu = $("#custom-snippets-list");
93+
const $backToListMenuBtn = $("#back-to-list-menu-btn");
94+
const $addNewSnippetBtn = $("#add-new-snippet-btn");
95+
const $filterSnippetsPanel = $("#filter-snippets-panel");
96+
97+
$addSnippetMenu.addClass("hidden");
98+
$editSnippetMenu.removeClass("hidden");
99+
$snippetListMenu.addClass("hidden");
100+
101+
$backToListMenuBtn.removeClass("hidden");
102+
$addNewSnippetBtn.addClass("hidden");
103+
$filterSnippetsPanel.addClass("hidden");
104+
}
105+
82106
/**
83107
* Shows an error message when a snippet with the same abbreviation already exists
84108
* and user is trying to add a new one
@@ -135,6 +159,7 @@ define(function (require, exports, module) {
135159
exports.clearSnippetsList = clearSnippetsList;
136160
exports.showAddSnippetMenu = showAddSnippetMenu;
137161
exports.showSnippetListMenu = showSnippetListMenu;
162+
exports.showEditSnippetMenu = showEditSnippetMenu;
138163
exports.showDuplicateAbbreviationError = showDuplicateAbbreviationError;
139164
exports.showSnippetsListHeader = showSnippetsListHeader;
140165
exports.hideSnippetsListHeader = hideSnippetsListHeader;

src/extensionsIntegrated/CustomSnippets/src/driver.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,57 @@ define(function (require, exports, module) {
2727
}
2828
}
2929

30+
/**
31+
* This function handles the save button click for editing a snippet
32+
*/
33+
function handleEditSaveBtnClick() {
34+
const editedData = Helper.getEditSnippetData();
35+
const $editView = $("#custom-snippets-edit");
36+
const originalSnippet = $editView.data("originalSnippet");
37+
const snippetIndex = $editView.data("snippetIndex");
38+
39+
// check if abbreviation changed and if new abbreviation already exists
40+
if (editedData.abbreviation !== originalSnippet.abbreviation) {
41+
const existingSnippet = Global.SnippetHintsList.find(
42+
(snippet) => snippet.abbreviation === editedData.abbreviation
43+
);
44+
if (existingSnippet) {
45+
UIHelper.showDuplicateAbbreviationError(editedData.abbreviation);
46+
return;
47+
}
48+
}
49+
50+
// update the snippet in the list
51+
if (snippetIndex !== -1) {
52+
Global.SnippetHintsList[snippetIndex] = editedData;
53+
SnippetsState.saveSnippetsToState();
54+
55+
// clear the stored data
56+
$editView.removeData("originalSnippet");
57+
$editView.removeData("snippetIndex");
58+
59+
// go back to snippets list
60+
UIHelper.showSnippetListMenu();
61+
SnippetsList.showSnippetsList();
62+
}
63+
}
64+
65+
/**
66+
* This function handles the reset button click for editing a snippet
67+
* It restores the original snippet data in the edit form
68+
*/
69+
function handleResetBtnClick() {
70+
const $editView = $("#custom-snippets-edit");
71+
const originalSnippet = $editView.data("originalSnippet");
72+
73+
if (originalSnippet) {
74+
// restore original data in the form
75+
Helper.populateEditForm(originalSnippet);
76+
// update save button state
77+
Helper.toggleEditSaveButtonDisability();
78+
}
79+
}
80+
3081
/**
3182
* This function is to check whether we can add the new snippet to the snippets list
3283
* because we don't want to add the new snippet if a snippet already exists with the same abbreviation
@@ -152,5 +203,7 @@ define(function (require, exports, module) {
152203

153204
exports.getWordBeforeCursor = getWordBeforeCursor;
154205
exports.handleSaveBtnClick = handleSaveBtnClick;
206+
exports.handleEditSaveBtnClick = handleEditSaveBtnClick;
207+
exports.handleResetBtnClick = handleResetBtnClick;
155208
exports.prependCustomSnippets = prependCustomSnippets;
156209
});

src/extensionsIntegrated/CustomSnippets/src/helper.js

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,62 @@ define(function (require, exports, module) {
180180
$("#file-extn-box").val("");
181181
}
182182

183+
/**
184+
* This function populates the edit form with snippet data
185+
* @param {Object} snippetData - The snippet object to edit
186+
*/
187+
function populateEditForm(snippetData) {
188+
$("#edit-abbr-box").val(snippetData.abbreviation);
189+
$("#edit-desc-box").val(snippetData.description || "");
190+
$("#edit-template-text-box").val(snippetData.templateText);
191+
$("#edit-file-extn-box").val(snippetData.fileExtension === "all" ? "" : snippetData.fileExtension);
192+
}
193+
194+
/**
195+
* This function is responsible to get the snippet data from all the edit form input fields
196+
* @returns {object} - a snippet object
197+
*/
198+
function getEditSnippetData() {
199+
// get the values from all the edit input fields
200+
const abbreviation = $("#edit-abbr-box").val().trim();
201+
const description = $("#edit-desc-box").val().trim();
202+
const templateText = $("#edit-template-text-box").val().trim();
203+
const fileExtension = $("#edit-file-extn-box").val().trim();
204+
205+
return {
206+
abbreviation: abbreviation,
207+
description: description || "", // allow empty description
208+
templateText: templateText,
209+
fileExtension: fileExtension || "all" // default to "all" if empty
210+
};
211+
}
212+
213+
/**
214+
* This function is responsible to enable/disable the save button in edit mode
215+
*/
216+
function toggleEditSaveButtonDisability() {
217+
// abbreviation and template text are required fields
218+
const $abbrInput = $("#edit-abbr-box");
219+
const $templateInput = $("#edit-template-text-box");
220+
221+
const $saveBtn = $("#save-edit-snippet-btn");
222+
223+
// make sure that the required fields has some value
224+
const hasAbbr = $abbrInput.val().trim().length > 0;
225+
const hasTemplate = $templateInput.val().trim().length > 0;
226+
$saveBtn.prop("disabled", !(hasAbbr && hasTemplate));
227+
}
228+
229+
/**
230+
* This function clears all the edit form input fields
231+
*/
232+
function clearEditInputFields() {
233+
$("#edit-abbr-box").val("");
234+
$("#edit-desc-box").val("");
235+
$("#edit-template-text-box").val("");
236+
$("#edit-file-extn-box").val("");
237+
}
238+
183239
/**
184240
* Updates the snippets count which is displayed in the toolbar at the left side
185241
* @private
@@ -216,7 +272,13 @@ define(function (require, exports, module) {
216272
let value = $input.val();
217273
const sanitizedValue = sanitizeFileExtensionInput(value);
218274
$input.val(sanitizedValue);
219-
toggleSaveButtonDisability();
275+
276+
// determine which save button to toggle based on input field
277+
if ($input.attr("id") === "edit-file-extn-box") {
278+
toggleEditSaveButtonDisability();
279+
} else {
280+
toggleSaveButtonDisability();
281+
}
220282
}
221283

222284
/**
@@ -268,7 +330,12 @@ define(function (require, exports, module) {
268330
const newPos = start + sanitized.length;
269331
input.setSelectionRange(newPos, newPos);
270332

271-
toggleSaveButtonDisability();
333+
// determine which save button to toggle based on input field
334+
if ($input.attr("id") === "edit-file-extn-box") {
335+
toggleEditSaveButtonDisability();
336+
} else {
337+
toggleSaveButtonDisability();
338+
}
272339
}
273340

274341
exports.toggleSaveButtonDisability = toggleSaveButtonDisability;
@@ -284,4 +351,8 @@ define(function (require, exports, module) {
284351
exports.handleFileExtensionInput = handleFileExtensionInput;
285352
exports.handleFileExtensionKeypress = handleFileExtensionKeypress;
286353
exports.handleFileExtensionPaste = handleFileExtensionPaste;
354+
exports.populateEditForm = populateEditForm;
355+
exports.getEditSnippetData = getEditSnippetData;
356+
exports.toggleEditSaveButtonDisability = toggleEditSaveButtonDisability;
357+
exports.clearEditInputFields = clearEditInputFields;
287358
});

src/extensionsIntegrated/CustomSnippets/src/snippetsList.js

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ define(function (require, exports, module) {
2020
function _createSnippetItem(snippetItem) {
2121
// the main snippet item container,
2222
// all the items like abbr, description and all that will be appended into this
23-
const $snippetItem = $("<div>").attr("data-abbr", snippetItem.abbreviation).attr("id", "snippet-item");
23+
const $snippetItem = $("<div>").attr("data-abbr", snippetItem.abbreviation).addClass("snippet-item");
2424

2525
const $snippetAbbr = $("<div>")
2626
.text(snippetItem.abbreviation)
@@ -138,7 +138,7 @@ define(function (require, exports, module) {
138138
*/
139139
function deleteSnippet() {
140140
// get the element
141-
const $snippetItem = $(this).closest("#snippet-item");
141+
const $snippetItem = $(this).closest(".snippet-item");
142142
const snippetItem = $snippetItem.data("snippet"); // this gives the actual object with all the keys and vals
143143

144144
const index = Global.SnippetHintsList.findIndex((s) => s.abbreviation === snippetItem.abbreviation);
@@ -157,14 +157,48 @@ define(function (require, exports, module) {
157157
* @private
158158
*/
159159
function _registerHandlers() {
160-
const $deleteSnippetBtn = $(".delete-snippet-btn");
160+
const $snippetsListWrapper = $("#snippets-list-wrapper");
161161

162-
$deleteSnippetBtn.off("click");
163-
$deleteSnippetBtn.on("click", function () {
162+
$snippetsListWrapper.off("click.deleteSnippet");
163+
$snippetsListWrapper.on("click.deleteSnippet", ".delete-snippet-btn", function (e) {
164+
e.stopPropagation(); // prevent triggering the edit handler
164165
deleteSnippet.call(this);
165166
});
167+
168+
// Use event delegation for snippet item clicks to enable editing
169+
$snippetsListWrapper.off("click.editSnippet");
170+
$snippetsListWrapper.on("click.editSnippet", ".snippet-item", function (e) {
171+
// don't trigger edit if clicking on delete button
172+
if ($(e.target).closest(".delete-snippet-btn").length === 0) {
173+
editSnippet.call(this);
174+
}
175+
});
176+
}
177+
178+
/**
179+
* This function handles editing a snippet when the snippet item is clicked
180+
*/
181+
function editSnippet() {
182+
// get the snippet data from the clicked item
183+
const $snippetItem = $(this).closest(".snippet-item");
184+
const snippetItem = $snippetItem.data("snippet");
185+
186+
// populate the edit form with current snippet data
187+
Helper.populateEditForm(snippetItem);
188+
189+
// store the original data for reset functionality
190+
$("#custom-snippets-edit").data("originalSnippet", snippetItem);
191+
$("#custom-snippets-edit").data("snippetIndex",
192+
Global.SnippetHintsList.findIndex(s => s.abbreviation === snippetItem.abbreviation));
193+
194+
// show the edit form
195+
UIHelper.showEditSnippetMenu();
196+
197+
// enable the save button based on current data
198+
Helper.toggleEditSaveButtonDisability();
166199
}
167200

168201
exports.showSnippetsList = showSnippetsList;
169202
exports.deleteSnippet = deleteSnippet;
203+
exports.editSnippet = editSnippet;
170204
});

0 commit comments

Comments
 (0)