1+ import { getSessionCurrent } from "../../../../src/api/session-api-client.js" ;
12import {
23 createServerRepositoryClient ,
34 readServerToolConstants ,
@@ -16,14 +17,17 @@ const repository = createTagsToolApiRepository();
1617
1718const elements = {
1819 add : document . querySelector ( "[data-tags-add]" ) ,
20+ activeProject : document . querySelector ( "[data-tags-active-project]" ) ,
21+ assignedCount : document . querySelector ( "[data-tags-assigned-count]" ) ,
22+ assignedLabels : document . querySelector ( "[data-tags-assigned-labels]" ) ,
1923 count : document . querySelector ( "[data-tags-count]" ) ,
2024 log : document . querySelector ( "[data-tags-log]" ) ,
2125 outputStatus : document . querySelector ( "[data-tags-output-status]" ) ,
26+ refresh : document . querySelector ( "[data-tags-refresh]" ) ,
2227 selected : document . querySelector ( "[data-tags-selected]" ) ,
2328 status : document . querySelector ( "[data-tags-status]" ) ,
2429 table : document . querySelector ( "[data-tags-table]" ) ,
2530 tableCounts : document . querySelector ( "[data-tags-table-counts]" ) ,
26- usageCount : document . querySelector ( "[data-tags-usage-count]" ) ,
2731} ;
2832
2933let editingTagId = "" ;
@@ -63,20 +67,42 @@ function createInput(value, label, datasetName) {
6367function editingValues ( row ) {
6468 return {
6569 description : row . querySelector ( "[data-tags-description-input]" ) ?. value || "" ,
66- name : row . querySelector ( "[data-tags-name-input]" ) ?. value || "" ,
70+ label : row . querySelector ( "[data-tags-name-input]" ) ?. value || "" ,
6771 } ;
6872}
6973
74+ function currentSession ( ) {
75+ try {
76+ return getSessionCurrent ( ) ;
77+ } catch {
78+ return { authenticated : false } ;
79+ }
80+ }
81+
82+ function redirectGuestWriteAction ( ) {
83+ if ( currentSession ( ) ?. authenticated === true ) {
84+ return false ;
85+ }
86+ setText ( elements . log , "Sign in before saving project tags." ) ;
87+ window . location . href = new URL ( "/account/sign-in.html" , window . location . href ) . href ;
88+ return true ;
89+ }
90+
91+ function tagLabel ( tag ) {
92+ return tag ?. label || tag ?. name || "" ;
93+ }
94+
7095function createEditRow ( tag = null ) {
7196 const row = document . createElement ( "tr" ) ;
7297 row . dataset . tagsEditingRow = tag ?. id || "__new__" ;
7398
7499 const nameCell = document . createElement ( "td" ) ;
75- nameCell . append ( createInput ( tag ?. name || "" , "Tag Name " , "tagsNameInput" ) ) ;
100+ nameCell . append ( createInput ( tagLabel ( tag ) , "Tag Label " , "tagsNameInput" ) ) ;
76101
77102 const descriptionCell = document . createElement ( "td" ) ;
78103 descriptionCell . append ( createInput ( tag ?. description || "" , "Description" , "tagsDescriptionInput" ) ) ;
79104
105+ const assignedCell = createCell ( tag ?. assigned ? "Yes" : "No" ) ;
80106 const usageCell = createCell ( tag ? String ( tag . usageCount || 0 ) : "0" ) ;
81107
82108 const actionsCell = document . createElement ( "td" ) ;
@@ -88,15 +114,15 @@ function createEditRow(tag = null) {
88114 ) ;
89115 actionsCell . append ( actions ) ;
90116
91- row . append ( nameCell , descriptionCell , usageCell , actionsCell ) ;
117+ row . append ( nameCell , descriptionCell , assignedCell , usageCell , actionsCell ) ;
92118 return row ;
93119}
94120
95121function createUsageCountButton ( tag ) {
96122 const cell = document . createElement ( "td" ) ;
97123 const button = createButton ( String ( tag . usageCount || 0 ) , "tagsToggleUsage" , tag . id ) ;
98124 button . setAttribute ( "aria-expanded" , String ( expandedTagId === tag . id ) ) ;
99- button . setAttribute ( "aria-label" , `Show usage for ${ tag . name } ` ) ;
125+ button . setAttribute ( "aria-label" , `Show usage for ${ tagLabel ( tag ) } ` ) ;
100126 cell . append ( button ) ;
101127 return cell ;
102128}
@@ -113,14 +139,18 @@ function createTagRow(tag) {
113139 const actions = document . createElement ( "div" ) ;
114140 actions . className = "action-group action-group--tight" ;
115141 actions . append (
142+ tag . assigned
143+ ? createButton ( "Remove" , "tagsRemove" , tag . id )
144+ : createButton ( "Assign" , "tagsAssign" , tag . id ) ,
116145 createButton ( "Edit" , "tagsEdit" , tag . id ) ,
117146 createButton ( "Trash" , "tagsDelete" , tag . id )
118147 ) ;
119148 actionsCell . append ( actions ) ;
120149
121150 row . append (
122- createCell ( tag . name ) ,
151+ createCell ( tagLabel ( tag ) ) ,
123152 createCell ( tag . description || "No description" ) ,
153+ createCell ( tag . assigned ? "Yes" : "No" ) ,
124154 createUsageCountButton ( tag ) ,
125155 actionsCell
126156 ) ;
@@ -132,14 +162,14 @@ function createUsageRow(tag) {
132162 row . dataset . tagsUsageRow = tag . id ;
133163
134164 const cell = document . createElement ( "td" ) ;
135- cell . colSpan = 4 ;
165+ cell . colSpan = 5 ;
136166
137167 const wrapper = document . createElement ( "div" ) ;
138168 wrapper . className = "table-wrapper" ;
139169
140170 const table = document . createElement ( "table" ) ;
141171 table . className = "data-table" ;
142- table . setAttribute ( "aria-label" , `${ tag . name } usage` ) ;
172+ table . setAttribute ( "aria-label" , `${ tagLabel ( tag ) } usage` ) ;
143173
144174 const head = document . createElement ( "thead" ) ;
145175 const headRow = document . createElement ( "tr" ) ;
@@ -151,7 +181,9 @@ function createUsageRow(tag) {
151181 const emptyRow = document . createElement ( "tr" ) ;
152182 const emptyCell = document . createElement ( "td" ) ;
153183 emptyCell . colSpan = 2 ;
154- emptyCell . textContent = "No usage yet." ;
184+ emptyCell . textContent = tag . assigned
185+ ? "Assigned to the active project."
186+ : "No usage yet." ;
155187 emptyRow . append ( emptyCell ) ;
156188 body . append ( emptyRow ) ;
157189 } else {
@@ -182,7 +214,7 @@ function renderTable(snapshot) {
182214 if ( ! snapshot . tags . length && editingTagId !== "__new__" ) {
183215 const row = document . createElement ( "tr" ) ;
184216 const cell = document . createElement ( "td" ) ;
185- cell . colSpan = 4 ;
217+ cell . colSpan = 5 ;
186218 cell . textContent = "No tags added yet." ;
187219 row . append ( cell ) ;
188220 elements . table . append ( row ) ;
@@ -212,11 +244,13 @@ function renderTableCounts(snapshot) {
212244
213245function render ( ) {
214246 const snapshot = repository . getSnapshot ( ) ;
215- const usageCount = snapshot . tags . reduce ( ( total , tag ) => total + tag . usageCount , 0 ) ;
247+ const assignedLabels = snapshot . assignedTags . map ( tagLabel ) . join ( ", " ) || "None" ;
216248 setText ( elements . status , snapshot . status ) ;
217249 setText ( elements . outputStatus , snapshot . status ) ;
250+ setText ( elements . activeProject , snapshot . activeProject ?. name || "No active project" ) ;
251+ setText ( elements . assignedCount , String ( snapshot . assignedTags . length ) ) ;
252+ setText ( elements . assignedLabels , assignedLabels ) ;
218253 setText ( elements . count , String ( snapshot . tags . length ) ) ;
219- setText ( elements . usageCount , String ( usageCount ) ) ;
220254 setText ( elements . selected , selectedTagName ) ;
221255 if ( elements . add ) {
222256 elements . add . disabled = editingTagId === "__new__" ;
@@ -229,15 +263,22 @@ elements.add?.addEventListener("click", () => {
229263 editingTagId = "__new__" ;
230264 expandedTagId = "" ;
231265 selectedTagName = "New tag" ;
232- setText ( elements . log , "Adding a workspace tag." ) ;
266+ setText ( elements . log , "Adding a project tag." ) ;
267+ render ( ) ;
268+ } ) ;
269+
270+ elements . refresh ?. addEventListener ( "click" , ( ) => {
271+ setText ( elements . log , "Project tags refreshed from the API." ) ;
233272 render ( ) ;
234273} ) ;
235274
236275elements . table ?. addEventListener ( "click" , ( event ) => {
276+ const assign = event . target . closest ( "[data-tags-assign]" ) ;
237277 const edit = event . target . closest ( "[data-tags-edit]" ) ;
238278 const save = event . target . closest ( "[data-tags-save]" ) ;
239279 const cancel = event . target . closest ( "[data-tags-cancel]" ) ;
240280 const deleteButton = event . target . closest ( "[data-tags-delete]" ) ;
281+ const remove = event . target . closest ( "[data-tags-remove]" ) ;
241282 const toggleUsage = event . target . closest ( "[data-tags-toggle-usage]" ) ;
242283
243284 if ( toggleUsage ) {
@@ -248,6 +289,28 @@ elements.table?.addEventListener("click", (event) => {
248289 return ;
249290 }
250291
292+ if ( assign ) {
293+ if ( redirectGuestWriteAction ( ) ) {
294+ return ;
295+ }
296+ const result = repository . assignTagToProject ( assign . dataset . tagsAssign ) ;
297+ selectedTagName = tagLabel ( result . tag ) || selectedTagName ;
298+ setText ( elements . log , result . message ) ;
299+ render ( ) ;
300+ return ;
301+ }
302+
303+ if ( remove ) {
304+ if ( redirectGuestWriteAction ( ) ) {
305+ return ;
306+ }
307+ const result = repository . removeTagFromProject ( remove . dataset . tagsRemove ) ;
308+ selectedTagName = tagLabel ( result . tag ) || selectedTagName ;
309+ setText ( elements . log , result . message ) ;
310+ render ( ) ;
311+ return ;
312+ }
313+
251314 if ( edit ) {
252315 editingTagId = edit . dataset . tagsEdit ;
253316 expandedTagId = "" ;
@@ -266,21 +329,27 @@ elements.table?.addEventListener("click", (event) => {
266329 }
267330
268331 if ( save ) {
332+ if ( redirectGuestWriteAction ( ) ) {
333+ return ;
334+ }
269335 const row = save . closest ( "[data-tags-editing-row]" ) ;
270336 const values = editingValues ( row ) ;
271337 const result = save . dataset . tagsSave === "__new__"
272338 ? repository . addTag ( values )
273339 : repository . updateTag ( save . dataset . tagsSave , values ) ;
274340 if ( result . added || result . updated ) {
275341 editingTagId = "" ;
276- selectedTagName = result . tag ?. name || "None" ;
342+ selectedTagName = tagLabel ( result . tag ) || "None" ;
277343 }
278344 setText ( elements . log , result . message ) ;
279345 render ( ) ;
280346 return ;
281347 }
282348
283349 if ( deleteButton ) {
350+ if ( redirectGuestWriteAction ( ) ) {
351+ return ;
352+ }
284353 const result = repository . deleteTag ( deleteButton . dataset . tagsDelete ) ;
285354 if ( result . deleted ) {
286355 editingTagId = "" ;
0 commit comments