-
Notifications
You must be signed in to change notification settings - Fork 4
[NAE-2072] Workspaces #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/7.0.0-rev2
Are you sure you want to change the base?
Changes from all commits
eb739ee
c9b3599
7e4929d
cc9a3bf
b6109f7
2a2c555
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -68,7 +68,8 @@ export class PanelsComponent implements OnInit { | |||||
stringId: null, | ||||||
petriNetId: null, | ||||||
permissions: {}, | ||||||
users: {} | ||||||
users: {}, | ||||||
workspaceId: '' | ||||||
}; | ||||||
this.workflow = { | ||||||
stringId: 'ID', | ||||||
|
@@ -83,7 +84,8 @@ export class PanelsComponent implements OnInit { | |||||
email: '[email protected]', | ||||||
fullName: 'Test Testovič' | ||||||
}, | ||||||
immediateData: [] | ||||||
immediateData: [], | ||||||
workspaceId: '' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use consistent default workspace ID value. Similar to the case object above, consider using "default" instead of an empty string for consistency. - workspaceId: ''
+ workspaceId: 'default' 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||
}; | ||||||
this.featuredFields$ = new BehaviorSubject<Array<HeaderColumn>>([ | ||||||
new HeaderColumn(HeaderColumnType.META, 'visualId', 'Visual ID', 'text'), | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -23,6 +23,10 @@ export class Net implements PetriNetReferenceWithPermissions { | |||||
* @ignore | ||||||
*/ | ||||||
private _identifier: string; | ||||||
/** | ||||||
* Workspace id | ||||||
* */ | ||||||
private _workspaceId: string; | ||||||
/** | ||||||
* @ignore | ||||||
* */ | ||||||
|
@@ -84,6 +88,7 @@ export class Net implements PetriNetReferenceWithPermissions { | |||||
this._transactions = []; | ||||||
this._roles = []; | ||||||
this._uriNodeId = net.uriNodeId; | ||||||
this._workspaceId = net.workspaceId | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix missing semicolon. The constructor initialization is missing a semicolon at the end of the line. - this._workspaceId = net.workspaceId
+ this._workspaceId = net.workspaceId; 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||
} | ||||||
|
||||||
get stringId(): string { | ||||||
|
@@ -197,4 +202,13 @@ export class Net implements PetriNetReferenceWithPermissions { | |||||
set uriNodeId(uriNodeId: string) { | ||||||
this._uriNodeId = uriNodeId; | ||||||
} | ||||||
|
||||||
|
||||||
get workspaceId(): string { | ||||||
return this._workspaceId; | ||||||
} | ||||||
|
||||||
set workspaceId(value: string) { | ||||||
this._workspaceId = value; | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -111,6 +111,10 @@ export interface Case { | |||||||||||||||||||||
* **Example:** 5e4cd5070a975a19858772aa | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
petriNetId: string; | ||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Workspace id | ||||||||||||||||||||||
* */ | ||||||||||||||||||||||
workspaceId: string; | ||||||||||||||||||||||
Comment on lines
+114
to
+117
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainImprove documentation consistency. The /**
- * Workspace id
+ * **Example:** default
+ *
+ * Workspace id
* */ Verify that existing code creating Case objects won't break with this new required property: 🏁 Script executed: #!/bin/bash
# Check for Case object creation that might miss the new required property
rg -A 5 -B 2 "new.*Case|Case.*=" --type ts Length of output: 66678 Add a usage example for I didn’t find any object literals or • File: Suggested diff: /**
- * Workspace id
+ * **Example:** default
+ *
+ * Workspace id
*/
workspaceId: string; 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* **Example:** home | ||||||||||||||||||||||
*/ | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,5 +48,9 @@ export interface PetriNetReference { | |
* [ImmediateData]{@link ImmediateData} | ||
*/ | ||
immediateData: Array<ImmediateData>; | ||
/** | ||
* Workspace id | ||
* */ | ||
workspaceId: string; | ||
Comment on lines
+51
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify all implementations are updated for the breaking change. Adding the required Run the following script to verify all 🏁 Script executed: #!/bin/bash
# Description: Find all PetriNetReference object creations and verify workspaceId is included
# Search for PetriNetReference object creations
rg -A 10 -B 2 "PetriNetReference|new.*Net\("
# Search for files that might be missing workspaceId in object literals
ast-grep --pattern $'{
$$$
title: $_,
$$$
}' Length of output: 67189 Add The new required
Example update in a spec file: public workflow: PetriNetReference = {
stringId: '',
title: '',
identifier: '',
version: '',
initials: '',
defaultCaseName: '',
createdDate: [],
author: { email: '', fullName: '' },
immediateData: undefined,
+ workspaceId: ''
}; Repeat for all other object literals where a 🤖 Prompt for AI Agents
|
||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,4 +70,8 @@ export interface Task { | |
delegateTitle?: string; | ||
immediateData?: Array<ImmediateData>; | ||
assignedUserPolicy?: AssignedUserPolicy; | ||
/** | ||
* Workspace id | ||
* */ | ||
workspaceId: string; | ||
Comment on lines
+73
to
+76
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify all Task implementations include the new required property. The addition of the required Run the following script to identify any Task object creations that might be missing the workspaceId: 🏁 Script executed: #!/bin/bash
# Description: Find Task object creations and verify workspaceId inclusion
# Search for Task object creations and assignments
rg -A 15 "Task\s*=\s*{|:\s*Task\s*=|new.*Task\(|as\s+Task"
# Look for mock Task objects that might need updating
fd -e ts -x rg -l "Task.*mock|mock.*Task" {} Length of output: 1368 🏁 Script executed: #!/bin/bash
# 1. Find object literals explicitly annotated with Task:
echo "=== Object literals typed as Task ==="
rg -n -E ':\s*Task\s*=\s*\{' -n projects/netgrif-components-core || echo "No direct annotations found."
# 2. Find casts to Task:
echo -e "\n=== 'as Task' casts ==="
rg -n 'as\s\+Task' -n projects/netgrif-components-core || echo "No 'as Task' casts found."
# 3. Verify mocks include workspaceId:
echo -e "\n=== Checking mocks for workspaceId ==="
for f in $(fd -e ts -g "create-mock-task*.ts"); do
if rg -q "workspaceId" "$f"; then
echo "OK: workspaceId present in $f"
else
echo "MISSING: workspaceId not found in $f"
fi
done Length of output: 1397 Include A required • projects/netgrif-components-core/src/lib/utility/tests/utility/create-mock-task-outcome.ts Please also scan for any other untyped Task literals or fixtures to ensure they include the new 🤖 Prompt for AI Agents
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,4 +34,8 @@ export interface IUser { | |
* **Example:** Netgrif | ||
*/ | ||
lastName: string; | ||
/** | ||
* **Example:** default | ||
*/ | ||
workspaceId: string; | ||
Comment on lines
+37
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainLGTM! Consistent interface extension. The Consider whether validation should be added for workspace ID format and if this should be optional for backward compatibility: 🏁 Script executed: #!/bin/bash
# Check if there are any existing usages of IUser that might break with this required property
rg -A 3 -B 3 "implements IUser|extends IUser|: IUser" Length of output: 69072 Add The new required • In • In Also update any mapping or factory methods that create 🤖 Prompt for AI Agents
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ export class User implements IUser { | |
public realmId: string, | ||
public firstName: string, | ||
public lastName: string, | ||
public workspaceId: string, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainVerify constructor parameter placement doesn't break existing code. Adding Run this script to verify all User constructor calls are compatible: 🏁 Script executed: #!/bin/bash
# Description: Find all User constructor calls to verify they won't break with the new parameter
# Search for new User() instantiations
echo "=== Direct User constructor calls ==="
rg -A 3 "new User\(" --type ts
# Search for User constructor calls in factories or builders
echo -e "\n=== User creation in factories/transformers ==="
rg -A 5 "User\(" --type ts | grep -v "export class User"
# Check if UserTransformer or similar classes handle the new parameter
echo -e "\n=== UserTransformer implementations ==="
ast-grep --pattern 'class $_ {
$$$
transform($$$) {
$$$
new User($$$)
$$$
}
$$$
}' Length of output: 65160 Fix User constructor parameter placement to avoid breaking changes. The
🤖 Prompt for AI Agents
|
||
public authorities: Array<string>, | ||
public roles: Array<ProcessRole>, | ||
public groups?: Array<string>, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
export interface Workspace { | ||
id: string; | ||
defaultWorkspace: boolean; | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,5 +1,5 @@ | ||||||||||||||||||||||||||||||||||||||||||||
import {Injectable, OnDestroy} from '@angular/core'; | ||||||||||||||||||||||||||||||||||||||||||||
import {Observable, ReplaySubject, Subscription} from 'rxjs'; | ||||||||||||||||||||||||||||||||||||||||||||
import {BehaviorSubject, Observable, ReplaySubject, Subscription} from 'rxjs'; | ||||||||||||||||||||||||||||||||||||||||||||
import {ProcessRole} from '../../resources/interface/process-role'; | ||||||||||||||||||||||||||||||||||||||||||||
import {User} from '../models/user'; | ||||||||||||||||||||||||||||||||||||||||||||
import {Credentials} from '../../authentication/models/credentials'; | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -12,6 +12,7 @@ import {HttpErrorResponse} from '@angular/common/http'; | |||||||||||||||||||||||||||||||||||||||||||
import {SessionService} from '../../authentication/session/services/session.service'; | ||||||||||||||||||||||||||||||||||||||||||||
import {UserResource} from '../../resources/interface/user-resource'; | ||||||||||||||||||||||||||||||||||||||||||||
import {AnonymousService} from '../../authentication/anonymous/anonymous.service'; | ||||||||||||||||||||||||||||||||||||||||||||
import {Workspace} from "../models/workspace"; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
@Injectable({ | ||||||||||||||||||||||||||||||||||||||||||||
providedIn: 'root' | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -25,6 +26,7 @@ export class UserService implements OnDestroy { | |||||||||||||||||||||||||||||||||||||||||||
protected _subAuth: Subscription; | ||||||||||||||||||||||||||||||||||||||||||||
protected _subAnonym: Subscription; | ||||||||||||||||||||||||||||||||||||||||||||
private _publicLoadCalled: boolean; | ||||||||||||||||||||||||||||||||||||||||||||
protected _workspaces: ReplaySubject<Array<Workspace>>; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
public readonly GLOBAL_ROLE_PREFIX = 'global_'; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
@@ -37,11 +39,14 @@ export class UserService implements OnDestroy { | |||||||||||||||||||||||||||||||||||||||||||
this._user = this.emptyUser(); | ||||||||||||||||||||||||||||||||||||||||||||
this._loginCalled = false; | ||||||||||||||||||||||||||||||||||||||||||||
this._userChange$ = new ReplaySubject<User>(1); | ||||||||||||||||||||||||||||||||||||||||||||
this._workspaces = new ReplaySubject<Array<Workspace>>(1); | ||||||||||||||||||||||||||||||||||||||||||||
this._anonymousUserChange$ = new ReplaySubject<User>(1); | ||||||||||||||||||||||||||||||||||||||||||||
setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||||
this._subAuth = this._authService.authenticated$.subscribe(auth => { | ||||||||||||||||||||||||||||||||||||||||||||
if (auth && !this._loginCalled) { | ||||||||||||||||||||||||||||||||||||||||||||
this.loadUser(); | ||||||||||||||||||||||||||||||||||||||||||||
} else if (auth && this._loginCalled) { | ||||||||||||||||||||||||||||||||||||||||||||
this.loadWorkspaces(); | ||||||||||||||||||||||||||||||||||||||||||||
} else if (!auth) { | ||||||||||||||||||||||||||||||||||||||||||||
this.clearUser(); | ||||||||||||||||||||||||||||||||||||||||||||
this.publishUserChange(); | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -66,6 +71,10 @@ export class UserService implements OnDestroy { | |||||||||||||||||||||||||||||||||||||||||||
return this._userChange$.asObservable(); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
get workspaces$(): Observable<Array<Workspace>> { | ||||||||||||||||||||||||||||||||||||||||||||
return this._workspaces.asObservable(); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
get anonymousUser(): User { | ||||||||||||||||||||||||||||||||||||||||||||
return this.anonymousUser; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -177,7 +186,7 @@ export class UserService implements OnDestroy { | |||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
protected emptyUser() { | ||||||||||||||||||||||||||||||||||||||||||||
return new User('', '', '', '', '', '', [], [], [], []); | ||||||||||||||||||||||||||||||||||||||||||||
return new User('', '', '', '', '', '', '', [], [], [], []); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
protected loadUser(): void { | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -186,6 +195,7 @@ export class UserService implements OnDestroy { | |||||||||||||||||||||||||||||||||||||||||||
const backendUser = {...user, id: user.id.toString()}; | ||||||||||||||||||||||||||||||||||||||||||||
this._user = this._userTransform.transform(backendUser); | ||||||||||||||||||||||||||||||||||||||||||||
this.publishUserChange(); | ||||||||||||||||||||||||||||||||||||||||||||
this.loadWorkspaces(); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
}, error => { | ||||||||||||||||||||||||||||||||||||||||||||
if (error instanceof HttpErrorResponse && error.status === 401) { | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -210,6 +220,24 @@ export class UserService implements OnDestroy { | |||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
public loadWorkspaces() { | ||||||||||||||||||||||||||||||||||||||||||||
this._userResource.getAllWorkspaces().pipe(take(1)).subscribe(workspaces => { | ||||||||||||||||||||||||||||||||||||||||||||
if (workspaces) { | ||||||||||||||||||||||||||||||||||||||||||||
this._workspaces.next(workspaces) | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
}, error => { | ||||||||||||||||||||||||||||||||||||||||||||
this._log.error('Loading workspaces has failed!', error); | ||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
public changeWorkspace(workspaceId: string) { | ||||||||||||||||||||||||||||||||||||||||||||
this._userResource.changeWorkspace(workspaceId).subscribe(user => { | ||||||||||||||||||||||||||||||||||||||||||||
if (user) { | ||||||||||||||||||||||||||||||||||||||||||||
window.location.reload(); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+233
to
+239
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling and input validation. The method should handle potential failures and validate the input parameter: public changeWorkspace(workspaceId: string) {
+ if (!workspaceId) {
+ this._log.error('Workspace ID is required for workspace change');
+ return;
+ }
+
this._userResource.changeWorkspace(workspaceId).subscribe(user => {
if (user) {
window.location.reload();
}
+ }, error => {
+ this._log.error('Changing workspace has failed!', error);
});
} 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
public clearUser() { | ||||||||||||||||||||||||||||||||||||||||||||
this._user = this.emptyUser(); | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,7 +5,7 @@ import {UserResource} from '../../../resources/interface/user-resource'; | |||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
export class MockAuthenticationMethodService extends AuthenticationMethodService { | ||||||||||||||||||||||||||||||||||||||
login(credentials: Credentials): Observable<UserResource> { | ||||||||||||||||||||||||||||||||||||||
return of({email: 'mail', id: 'id', username: 'username', realmId: 'realmId', name: 'name', firstName: 'name', surname: 'surname', lastName: 'surname', fullName: 'name surname', | ||||||||||||||||||||||||||||||||||||||
return of({email: 'mail', id: 'id', username: 'username', realmId: 'realmId', name: 'name', firstName: 'name', surname: 'surname', lastName: 'surname', fullName: 'name surname', workspaceId: '', | ||||||||||||||||||||||||||||||||||||||
groups: [], authorities: [], nextGroups: [], processRoles: []}); | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+8
to
9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Inconsistent workspace ID value in mock data. The mock uses an empty string for Consider updating the mock to use a consistent default value: - return of({email: 'mail', id: 'id', username: 'username', realmId: 'realmId', name: 'name', firstName: 'name', surname: 'surname', lastName: 'surname', fullName: 'name surname', workspaceId: '',
+ return of({email: 'mail', id: 'id', username: 'username', realmId: 'realmId', name: 'name', firstName: 'name', surname: 'surname', lastName: 'surname', fullName: 'name surname', workspaceId: 'default', 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use consistent default workspace ID value.
The empty string value for
workspaceId
is inconsistent with the "default" example shown in theIUser
interface. For demo purposes, using a meaningful value would be better.📝 Committable suggestion
🤖 Prompt for AI Agents