Skip to content

Commit fefdb03

Browse files
authored
Merge pull request #319 from intersystems/otherDevUsername
Show other developer's username in Web UI's workspace
2 parents 8e6e140 + a2ce4f8 commit fefdb03

File tree

5 files changed

+116
-45
lines changed

5 files changed

+116
-45
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
- Don't automatically stage files added to source control (#303)
1616
- Performance improvements (#269, #315)
1717
- Checkout of branches whose names contain slashes via Web UI no longer fails (#295)
18+
- Display other developer's username in Web UI's Workspace when hovering over the name of a file they changed (#304)
1819

1920
## [2.3.0] - 2023-12-06
2021

cls/SourceControl/Git/Change.cls

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ ClassMethod RemoveUncommitted(FileList, Display = 1, Revert = 0, ActiveCommit =
4444
set changeSourceClass=##class(%Studio.SourceControl.Interface).SourceControlClassGet()
4545
}
4646
if ('$get(^SYS("SourceControl","ChangeConfig","KeepHistory")))||(Revert) {
47-
set sc=..%DeleteId(obj.%Id())
47+
if (obj.ChangedBy = $username) {
48+
set sc=..%DeleteId(obj.%Id())
49+
}
4850
} else {
4951
if $get(CommitCCR)'="" set obj.CCR=CommitCCR
5052
set obj.P4Issued=$zdatetime($h,3)
@@ -77,6 +79,29 @@ ClassMethod IsUncommitted(Filename, ByRef ID) As %Boolean
7779
}
7880
}
7981

82+
ClassMethod GetOtherDeveloperChanges() As %Boolean
83+
{
84+
set numEntries = 0
85+
set fileToOtherDevelopers = {}
86+
set query = "Select ItemFile, ChangedBy FROM SourceControl_Git.Change WHERE CHARINDEX('SourceControl.Git', Name)>0 AND Committed = '0' AND ChangedBy <> ?"
87+
set statement = ##class(%SQL.Statement).%New()
88+
set status = statement.%Prepare(query)
89+
$$$ThrowOnError(status)
90+
set rset = statement.%Execute($username)
91+
if (rset.%SQLCODE < 0) {
92+
throw ##class(%Exception.SQL).CreateFromSQLCODE(rset.%SQLCODE,rset.%Message)
93+
}
94+
while rset.%Next(.sc) {
95+
$$$ThrowOnError(sc)
96+
set filePath = "cls\"_$EXTRACT(rset.ItemFile, $FIND(rset.ItemFile,"cls\"),$LENGTH(rset.ItemFile))
97+
set otherDevelopers = fileToOtherDevelopers.%Get(filePath, [])
98+
do otherDevelopers.%Push(rset.ChangedBy)
99+
do fileToOtherDevelopers.%Set(filePath, otherDevelopers)
100+
}
101+
$$$ThrowOnError(sc)
102+
return fileToOtherDevelopers
103+
}
104+
80105
/// Goes through Uncommitted queue and removes any items of action 'edit' or 'add' which are ReadOnly or non-existent on the filesystem
81106
ClassMethod RefreshUncommitted(Display = 0, IncludeRevert = 0, Output gitFiles, Force As %Boolean = 0) As %Status
82107
{
@@ -192,4 +217,3 @@ Storage Default
192217
}
193218

194219
}
195-

cls/SourceControl/Git/WebUIDriver.cls

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,24 +183,26 @@ ClassMethod Uncommitted() As %SystemBase
183183
set output = ""
184184
set key = ""
185185

186-
set array = []
187-
set key = ""
186+
set editedByCurrentUser = []
187+
set fileToOtherDevelopers = {}
188188
for {
189189
set key = $order(files(key),1,fileData)
190190
quit:key=""
191191
// Check that current user has files(key) uncommitted and only %Push if they do
192192
set filename = ##class(Utils).FullExternalName(key)
193193
if (($ISVALIDNUM(key)) && (files(key) '= "")){
194-
do array.%Push($listget(fileData,2))
194+
do editedByCurrentUser.%Push($listget(fileData,2))
195195
}
196196
else{
197197
set sc=##class(SourceControl.Git.Change).GetUncommitted(filename,.tAction,.tInternalName,.UncommittedUser,.tSource,.UncommittedLastUpdated)
198198
if ($$$ISOK(sc)) && ($data(tAction)&&(UncommittedUser=$username)) {
199-
do array.%Push($listget(fileData,2))
199+
do editedByCurrentUser.%Push($listget(fileData,2))
200200
}
201201
}
202202
}
203-
quit array
203+
do fileToOtherDevelopers.%Set("current user's changes", editedByCurrentUser)
204+
do fileToOtherDevelopers.%Set("other users' changes", ##class(SourceControl.Git.Change).GetOtherDeveloperChanges())
205+
quit fileToOtherDevelopers
204206
}
205207

206208
ClassMethod GetURLPrefix(%request As %CSP.Request, URL As %String) As %String

git-webui/release/share/git-webui/webui/js/git-webui.js

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ webui.SideBarView = function(mainView, noEventHandlers) {
414414
var flag = 0;
415415
webui.git("status -u --porcelain", function(data) {
416416
$.get("api/uncommitted", function (uncommitted) {
417-
var uncommittedItems = JSON.parse(uncommitted);
417+
var uncommittedItems = JSON.parse(uncommitted)["current user's changes"];
418418
var col = 1
419419
webui.splitLines(data).forEach(function(line) {
420420
var status = line[col];
@@ -488,7 +488,7 @@ webui.SideBarView = function(mainView, noEventHandlers) {
488488
var flag = 0;
489489
webui.git("status -u --porcelain", function(data) {
490490
$.get("api/uncommitted", function (uncommitted) {
491-
var uncommittedItems = JSON.parse(uncommitted);
491+
var uncommittedItems = JSON.parse(uncommitted)["current user's changes"];
492492
var col = 1
493493
webui.splitLines(data).forEach(function(line) {
494494
var status = line[col];
@@ -2143,13 +2143,30 @@ webui.ChangedFilesView = function(workspaceView, type, label) {
21432143
var col = type == "working-copy" ? 1 : 0;
21442144
webui.git("status -u --porcelain", function(data) {
21452145
$.get("api/uncommitted", function (uncommitted) {
2146-
var uncommittedItems = JSON.parse(uncommitted);
2146+
var uncommittedItems = JSON.parse(uncommitted)["current user's changes"];
2147+
var otherDeveloperUncommittedItems = JSON.parse(uncommitted)["other users' changes"];
21472148
self.filesCount = 0;
21482149
var filePaths = [];
2150+
function addItemToFileList(fileList, otherDeveloperUsername, model) {
2151+
var isForCurrentUser = otherDeveloperUsername === ""? true : false;
2152+
var cssClass = isForCurrentUser ? 'list-group-item available' : 'list-group-item unavailable';
2153+
if(isForCurrentUser){
2154+
var item = $('<a class="'+cssClass+'">').prependTo(fileList)[0];
2155+
}
2156+
else{
2157+
var item = $('<a class="'+cssClass+'" data-toggle="tooltip" title='+otherDeveloperUsername+'>'+
2158+
webui.peopleIcon).appendTo(fileList)[0];
2159+
}
2160+
item.model = model;
2161+
item.appendChild(document.createTextNode(model));
2162+
if (isForCurrentUser) {
2163+
$(item).click(self.select);
2164+
$(item).dblclick(self.process);
2165+
}
2166+
}
21492167
webui.splitLines(data).forEach(function(line) {
21502168
var indexStatus = line[0];
21512169
var workingTreeStatus = line[1];
2152-
var status = line[col];
21532170
line = line.substring(3);
21542171
var splitted = line.split(" -> ");
21552172
var model;
@@ -2159,40 +2176,47 @@ webui.ChangedFilesView = function(workspaceView, type, label) {
21592176
model = line;
21602177
}
21612178
filePaths.push(model);
2179+
21622180
if (workingTreeStatus === "D") {
21632181
localStorage.removeItem(model);
21642182
}
2165-
if (col == 0 && indexStatus != " " && indexStatus != "?" && localStorage.getItem(model) !== null || col == 1 && workingTreeStatus != " " && workingTreeStatus != "D" && localStorage.getItem(model) === null) {
2183+
2184+
var isNotStaged= workingTreeStatus != "D" && workingTreeStatus != " " && localStorage.getItem(model) === null;
2185+
var addUnstagedFile = col == 1 && isNotStaged;
2186+
var addStagedFile = col == 0 && indexStatus != " " && indexStatus != "?" && localStorage.getItem(model) !== null;
2187+
if (addUnstagedFile || addStagedFile) {
21662188
++self.filesCount;
21672189
var isForCurrentUser;
21682190
if(model.indexOf(" ") > -1){
21692191
isForCurrentUser = (uncommittedItems.indexOf(model.substring(1, model.length-1)) > -1);
21702192
} else {
21712193
isForCurrentUser = (uncommittedItems.indexOf(model) > -1);
21722194
}
2173-
var cssClass = isForCurrentUser ? 'list-group-item available' : 'list-group-item unavailable';
2174-
2175-
if(isForCurrentUser){
2176-
var item = $('<a class="'+cssClass+'">').prependTo(fileList)[0];
2177-
}
2178-
else{
2179-
var item = $('<a class="'+cssClass+'">'+
2180-
webui.peopleIcon).appendTo(fileList)[0];
2181-
}
2182-
item.model = model;
2183-
item.status = status;
2184-
item.appendChild(document.createTextNode(line));
2185-
$(item).click(self.select);
2195+
21862196
if (isForCurrentUser) {
2187-
$(item).dblclick(self.process);
2197+
addItemToFileList(fileList, "", model);
21882198
}
21892199
}
21902200
});
2201+
2202+
for (const otherDeveloperItem of Object.keys(otherDeveloperUncommittedItems)) {
2203+
for (const otherDeveloperUsername of otherDeveloperUncommittedItems[otherDeveloperItem]) {
2204+
if (col==1) {
2205+
addItemToFileList(fileList, otherDeveloperUsername, otherDeveloperItem);
2206+
}
2207+
}
2208+
}
2209+
2210+
$(function () {
2211+
$('[data-toggle="tooltip"]').tooltip()
2212+
});
2213+
21912214
Object.keys(localStorage).filter(function (key) {
21922215
return !filePaths.includes(key);
21932216
}).map(function (key) {
21942217
localStorage.removeItem(key);
21952218
});
2219+
21962220
if (selectedIndex !== null && selectedIndex >= fileList.childElementCount) {
21972221
selectedIndex = fileList.childElementCount - 1;
21982222
if (selectedIndex == -1) {

git-webui/src/share/git-webui/webui/js/git-webui.js

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ webui.SideBarView = function(mainView, noEventHandlers) {
414414
var flag = 0;
415415
webui.git("status -u --porcelain", function(data) {
416416
$.get("api/uncommitted", function (uncommitted) {
417-
var uncommittedItems = JSON.parse(uncommitted);
417+
var uncommittedItems = JSON.parse(uncommitted)["current user's changes"];
418418
var col = 1
419419
webui.splitLines(data).forEach(function(line) {
420420
var status = line[col];
@@ -488,7 +488,7 @@ webui.SideBarView = function(mainView, noEventHandlers) {
488488
var flag = 0;
489489
webui.git("status -u --porcelain", function(data) {
490490
$.get("api/uncommitted", function (uncommitted) {
491-
var uncommittedItems = JSON.parse(uncommitted);
491+
var uncommittedItems = JSON.parse(uncommitted)["current user's changes"];
492492
var col = 1
493493
webui.splitLines(data).forEach(function(line) {
494494
var status = line[col];
@@ -2143,13 +2143,30 @@ webui.ChangedFilesView = function(workspaceView, type, label) {
21432143
var col = type == "working-copy" ? 1 : 0;
21442144
webui.git("status -u --porcelain", function(data) {
21452145
$.get("api/uncommitted", function (uncommitted) {
2146-
var uncommittedItems = JSON.parse(uncommitted);
2146+
var uncommittedItems = JSON.parse(uncommitted)["current user's changes"];
2147+
var otherDeveloperUncommittedItems = JSON.parse(uncommitted)["other users' changes"];
21472148
self.filesCount = 0;
21482149
var filePaths = [];
2150+
function addItemToFileList(fileList, otherDeveloperUsername, model) {
2151+
var isForCurrentUser = otherDeveloperUsername === ""? true : false;
2152+
var cssClass = isForCurrentUser ? 'list-group-item available' : 'list-group-item unavailable';
2153+
if(isForCurrentUser){
2154+
var item = $('<a class="'+cssClass+'">').prependTo(fileList)[0];
2155+
}
2156+
else{
2157+
var item = $('<a class="'+cssClass+'" data-toggle="tooltip" title='+otherDeveloperUsername+'>'+
2158+
webui.peopleIcon).appendTo(fileList)[0];
2159+
}
2160+
item.model = model;
2161+
item.appendChild(document.createTextNode(model));
2162+
if (isForCurrentUser) {
2163+
$(item).click(self.select);
2164+
$(item).dblclick(self.process);
2165+
}
2166+
}
21492167
webui.splitLines(data).forEach(function(line) {
21502168
var indexStatus = line[0];
21512169
var workingTreeStatus = line[1];
2152-
var status = line[col];
21532170
line = line.substring(3);
21542171
var splitted = line.split(" -> ");
21552172
var model;
@@ -2164,33 +2181,36 @@ webui.ChangedFilesView = function(workspaceView, type, label) {
21642181
localStorage.removeItem(model);
21652182
}
21662183

2167-
if (col == 0 && indexStatus != " " && indexStatus != "?" && localStorage.getItem(model) !== null || col == 1 && workingTreeStatus != " " && workingTreeStatus != "D" && localStorage.getItem(model) === null) {
2184+
var isNotStaged= workingTreeStatus != "D" && workingTreeStatus != " " && localStorage.getItem(model) === null;
2185+
var addUnstagedFile = col == 1 && isNotStaged;
2186+
var addStagedFile = col == 0 && indexStatus != " " && indexStatus != "?" && localStorage.getItem(model) !== null;
2187+
if (addUnstagedFile || addStagedFile) {
21682188
++self.filesCount;
21692189
var isForCurrentUser;
21702190
if(model.indexOf(" ") > -1){
21712191
isForCurrentUser = (uncommittedItems.indexOf(model.substring(1, model.length-1)) > -1);
21722192
} else {
21732193
isForCurrentUser = (uncommittedItems.indexOf(model) > -1);
21742194
}
2175-
var cssClass = isForCurrentUser ? 'list-group-item available' : 'list-group-item unavailable';
2176-
2177-
if(isForCurrentUser){
2178-
var item = $('<a class="'+cssClass+'">').prependTo(fileList)[0];
2179-
}
2180-
else{
2181-
var item = $('<a class="'+cssClass+'">'+
2182-
webui.peopleIcon).appendTo(fileList)[0];
2183-
}
2184-
item.model = model;
2185-
item.status = status;
2186-
item.appendChild(document.createTextNode(line));
2187-
$(item).click(self.select);
2195+
21882196
if (isForCurrentUser) {
2189-
$(item).dblclick(self.process);
2197+
addItemToFileList(fileList, "", model);
21902198
}
21912199
}
21922200
});
21932201

2202+
for (const otherDeveloperItem of Object.keys(otherDeveloperUncommittedItems)) {
2203+
for (const otherDeveloperUsername of otherDeveloperUncommittedItems[otherDeveloperItem]) {
2204+
if (col==1) {
2205+
addItemToFileList(fileList, otherDeveloperUsername, otherDeveloperItem);
2206+
}
2207+
}
2208+
}
2209+
2210+
$(function () {
2211+
$('[data-toggle="tooltip"]').tooltip()
2212+
});
2213+
21942214
Object.keys(localStorage).filter(function (key) {
21952215
return !filePaths.includes(key);
21962216
}).map(function (key) {

0 commit comments

Comments
 (0)