Skip to content
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

Rel 8.0.0 pre prod gs do not merge #865

Open
wants to merge 96 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
6f1f394
DTS-27715: changes commit
eswbogol Aug 14, 2023
3e4009b
test case fix
Aug 21, 2023
95d394d
GS : JIRA-TEST-SPNEGO integration
eswbogol Oct 5, 2023
f654cac
GS : JIRA-TEST-SPNEGO integration
eswbogol Oct 5, 2023
eef3aeb
GS DTS-29033 : Jira Test JQL support changes
eswbogol Oct 5, 2023
d9e9d9a
GS vault changes
eswbogol Oct 5, 2023
a47b631
Squad case-sesitivity test
gipathak Nov 14, 2023
59414b2
Squal case sensitive check updated.
gipathak Nov 14, 2023
b7e365f
Squal case sensitive check updated code.
gipathak Nov 16, 2023
86de85d
portfolio text free changes.
gipathak Nov 16, 2023
62e95fb
squad changes.
gipathak Nov 17, 2023
7f6cba9
Gs on request changes
gipathak Dec 22, 2023
d4984ab
DTS-28860-FIX fix applied on GS
gipathak Jan 30, 2024
689eac5
8.0+ changes
purushottam08 Mar 14, 2024
d35dd83
sprint fetch flow fixed
purushottam08 Mar 26, 2024
5d20208
epic flow updated and jql flow is fixed
purushottam08 Apr 1, 2024
d138da5
version flow corrected
purushottam08 Apr 4, 2024
77784d8
JIRA-Test-JQL implementation on Jira Test
gipathak Apr 4, 2024
25abb91
JIRA-TEST-JQL integration
gipathak Apr 9, 2024
6438765
JIRA-TEST-JQL integration updated
gipathak Apr 9, 2024
49fe3c8
GS-JIRA-TEST-Changes
gipathak Apr 12, 2024
434e404
jira performance issue
gipathak Apr 23, 2024
c42ebf8
client centralised
purushottam08 Apr 24, 2024
eea8a1d
client centralised
purushottam08 Apr 25, 2024
482b3e3
client centralised
purushottam08 Apr 25, 2024
e55c74d
client centralised
purushottam08 Apr 25, 2024
c062302
Merge remote-tracking branch 'origin/GS_Squad_Filter' into GS_Squad_F…
Apr 25, 2024
fdc1583
sv
purushottam08 Apr 25, 2024
810d270
DTS-34692 multi sqad GS
brahmanand1 Apr 25, 2024
ecbbc4b
sv
purushottam08 Apr 25, 2024
55fd07c
Merge branch 'GS_Squad_Filter' of https://github.com/PublicisSapient/…
purushottam08 Apr 25, 2024
cd23b47
gitlab overlay fix
kunkambl Apr 25, 2024
6aa8fd7
sv
purushottam08 Apr 25, 2024
9224cf8
Consider test cases with atleast 1 valid story linkage
aksshriv1 Apr 25, 2024
959f944
gitlab overlay fix
kunkambl Apr 25, 2024
5c78357
Merge pull request #861 from PublicisSapient/DTS-36062_GS_ConsiderTes…
gipathak Apr 25, 2024
58378da
Merge branch 'GS_ENH_Backup' of https://github.com/PublicisSapient/PS…
kunkambl Apr 25, 2024
c112b0f
gitlab overlay fix
kunkambl Apr 25, 2024
5a1f371
Merge remote-tracking branch 'origin/GS_Squad_Filter' into GS_Squad_F…
Apr 25, 2024
ae617ca
Merge branch 'GS_ENH_Backup' of https://github.com/PublicisSapient/PS…
Apr 26, 2024
b69d266
Merge pull request #863 from PublicisSapient/GS_Squad_Filter
Chittauri Apr 26, 2024
986a367
jira performance issue
gipathak Apr 26, 2024
3a60a4c
added changes related to squad
HinPublicis Apr 26, 2024
bec917a
changes to the filter component
HinPublicis Apr 29, 2024
9ccfc43
Update filter.component.ts
HinPublicis Apr 30, 2024
cf74102
changes to the filter component
HinPublicis Apr 29, 2024
fe475be
Merge remote-tracking branch 'origin/Rel_8.0.0_PreProd_GS' into Rel_8…
Apr 30, 2024
6d4a539
Merge remote-tracking branch 'origin/Rel_8.0.0_PreProd_GS' into Rel_8…
Apr 30, 2024
3864c54
Merge remote-tracking branch 'origin/Rel_8.0.0_PreProd_GS' into Rel_8…
May 1, 2024
de49eb7
Merge remote-tracking branch 'origin/Rel_8.0.0_PreProd_GS' into Rel_8…
May 1, 2024
5a89fca
Merge remote-tracking branch 'origin/Rel_8.0.0_PreProd_GS' into Rel_8…
May 2, 2024
991e85f
Update filter.component.html
HinPublicis May 8, 2024
285da5f
Update executive.component.ts
HinPublicis May 15, 2024
0f291a7
Update maturity.component.ts
HinPublicis May 15, 2024
11461b7
Multiple squad backend change
gipathak May 16, 2024
2df9b71
Update QualityStatusServiceImpl.java
Chittauri Jun 4, 2024
3857cfa
Update QualityStatusServiceImpl.java
Chittauri Jun 4, 2024
71031ca
Merge remote-tracking branch 'origin/DTS-36376_GS_UnlinkedDefectColum…
Jun 7, 2024
fe86c64
field made double to string
purushottam08 Jun 10, 2024
974ea4a
Multiple squad backend change
gipathak May 16, 2024
86170dd
Merge remote-tracking branch 'origin/GS-Squad-Capacity' into GS-Squad…
Jun 11, 2024
7494636
Update JiraIssueRepositoryImpl.java
Chittauri Jun 12, 2024
d3b0137
Merge pull request #1093 from PublicisSapient/Lead_Time_For_Change_Fix
gipathak Jun 12, 2024
7ae556b
Merge remote-tracking branch 'origin/GS-Squad-Capacity' into GS-Squad…
Jun 11, 2024
88164f1
Merge remote-tracking branch 'origin/GS-Squad-Capacity' into GS-Squad…
Jun 12, 2024
9eed698
Merge remote-tracking branch 'origin/GS-Squad-Capacity' into GS-Squad…
Jun 12, 2024
5ddbf2a
Merge remote-tracking branch 'origin/GS-Squad-Capacity' into GS-Squad…
Jun 12, 2024
a323fa8
Merge pull request #1047 from PublicisSapient/DTS-36376_GS_UnlinkedDe…
Chittauri Jun 12, 2024
1a1227d
Merge pull request #1083 from PublicisSapient/GS-Squad-Capacity
gipathak Jun 14, 2024
c962b18
Merge pull request #1083 from PublicisSapient/GS-Squad-Capacity
gipathak Jun 14, 2024
d5e668b
Merge remote-tracking branch 'origin/Rel_8.0.0_PreProd_GS' into Rel_8…
Jun 14, 2024
cf6be94
new Field for gitlab tool for GS
aksshriv1 Jun 24, 2024
1119909
Merge pull request #1144 from PublicisSapient/DTS-37091_GSGitlabChange
gipathak Jun 24, 2024
5ad22f2
GS:convertIssuesListToBranchPattern
gipathak Jun 25, 2024
25b2c4f
Merge branch 'Rel_8.0.0_PreProd_GS' of https://github.com/PublicisSap…
gipathak Jun 25, 2024
7996676
GS:convertIssuesListToBranchPattern
gipathak Jun 26, 2024
b9ab7d5
config details added globally
brahmanand1 Jun 26, 2024
ae53c78
DTS-38318:Scope Churn KPI | Export does not display any information f…
gipathak Jul 6, 2024
aacd1b3
Rel_8.0.0_PreProd_GS: UI changes
gipathak Jul 12, 2024
3970230
GS config issue fixed
brahmanand1 Jul 12, 2024
a8ded33
Merge pull request #1219 from PublicisSapient/gs_defect_fix
gipathak Jul 12, 2024
a79d09e
Gitlab changes for MR or PR logic.
gipathak Jul 30, 2024
dc20cfa
DTS-38952:GS | Scope churn KPI export does not display any informatio…
gipathak Aug 1, 2024
2e9215b
GS: Gitlab connector
gipathak Aug 27, 2024
6dd7e5a
DTS-39590: date format fix GS
kunkambl Sep 20, 2024
312a514
DTS-39590 remove time from start and end date
brahmanand1 Sep 23, 2024
54d6806
Merge pull request #1491 from PublicisSapient/DTS-39590_gs_date_changes
brahmanand1 Sep 23, 2024
b8b590b
Merge pull request #1486 from PublicisSapient/DTS-39590_GS
kunkambl Sep 24, 2024
42e0bfb
test case fixed
brahmanand1 Sep 26, 2024
55d370c
Dev Completion Date Fix
aksshriv1 Oct 23, 2024
f6d3aee
Merge pull request #1620 from PublicisSapient/DTS-GS_PlannedWorkStatu…
aksshriv1 Oct 23, 2024
73d6026
GS Unplanned defect fix
aksshriv1 Nov 7, 2024
560a055
Merge pull request #1643 from PublicisSapient/DTS-GS_UnplannedDefectFix
aksshriv1 Nov 7, 2024
3905bfd
DailyStandUp view disabled.
gipathak Nov 12, 2024
a5c38ec
GitLab connector change for adding perpage size to property file.
gipathak Dec 3, 2024
19f00fe
Created VS Resolved Kpi toLowerCase fix.
gipathak Dec 20, 2024
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
190 changes: 127 additions & 63 deletions UI/src/app/config/capacity-planning/capacity-planning.component.html

Large diffs are not rendered by default.

213 changes: 198 additions & 15 deletions UI/src/app/config/capacity-planning/capacity-planning.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export class CapacityPlanningComponent implements OnInit {
@ViewChild('manageAssignee') manageAssignee: ManageAssigneeComponent;
trendLineValueList: any[];
projectListArr: Array<object> = [];
squadListArr: Array<object> = [];
filterForm: UntypedFormGroup;
tabHeaders = ['Scrum', 'Kanban'];
tabContentHeaders = { upload_tep: 'Test Execution Percentage Table', upload_Sprint_Capacity: 'Capacity Table' };
Expand All @@ -63,7 +64,9 @@ export class CapacityPlanningComponent implements OnInit {
endDate: any;
executionDate: any;
popupForm: UntypedFormGroup;
squadForm: UntypedFormGroup;
selectedSprintAssigneFormArray = [];
selectedSquad = [];
selectedSprintAssigneValidator = [];
isCapacitySaveDisabled = true;
capacityErrorMessage = '';
Expand All @@ -76,6 +79,7 @@ export class CapacityPlanningComponent implements OnInit {
sprintDetails: any;
projectDetails: any;
selectedProjectBaseConfigId: string;
selectedProjectName : string;
selectedSprintDetails: any;
selectedSprintId: any;
selectedSprintName: any;
Expand Down Expand Up @@ -180,6 +184,9 @@ export class CapacityPlanningComponent implements OnInit {
this.popupForm = new UntypedFormGroup({
capacity: new UntypedFormControl()
});

//add additionalFilterCapacity checks
this.squadForm = new UntypedFormGroup({});
}

// called when user switches the "Scrum/Kanban" switch
Expand Down Expand Up @@ -207,13 +214,14 @@ export class CapacityPlanningComponent implements OnInit {
this.capacityScrumData = [];
this.projectDetails = {};
this.selectedProjectBaseConfigId = '';
this.selectedProjectName = '';
this.getFilterDataOnLoad();
}

// gets data for filters on load
getFilterDataOnLoad() {

if (this.filter_kpiRequest && this.filter_kpiRequest !== '') {
if (this.filter_kpiRequest !== '') {
this.filter_kpiRequest.unsubscribe();
}

Expand All @@ -224,22 +232,19 @@ export class CapacityPlanningComponent implements OnInit {
this.selectedFilterData['sprintIncluded'] = ['CLOSED', 'ACTIVE', 'FUTURE'];
this.filter_kpiRequest = this.http_service.getFilterData(this.selectedFilterData)
.subscribe(filterData => {
if (filterData[0] !== 'error') {
if (filterData[0] !== 'error' && filterData?.['data']?.length > 0) {
this.filterData = filterData['data'];
if (this.filterData && this.filterData.length > 0) {
this.projectListArr = this.sortAlphabetically(this.filterData.filter(x => x.labelName.toLowerCase() == 'project'));
this.squadListArr = this.getSortedAdditonalFilter(this.projectListArr);
this.projectListArr = this.makeUniqueArrayList(this.projectListArr);
this.squadListArr = this.makeUniqueArrayList(this.squadListArr);
const defaultSelection = this.selectedProjectBaseConfigId ? false : true;
this.checkDefaultFilterSelection(defaultSelection);
if (Object.keys(filterData).length === 0) {
if (!Object.keys(filterData).length) {
this.resetProjectSelection();
// show error message
this.messageService.add({ severity: 'error', summary: 'Projects not found.' });
}
} else {
this.resetProjectSelection();
}


} else {
this.resetProjectSelection();
Expand Down Expand Up @@ -293,6 +298,7 @@ export class CapacityPlanningComponent implements OnInit {
const selectedProject = this.filterForm?.get('selectedProjectValue')?.value;
this.projectDetails = { ...this.trendLineValueList.find(i => i.nodeId === selectedProject) };
this.selectedProjectBaseConfigId = this.projectDetails?.basicProjectConfigId;
this.getSquadsOfSelectedProject(this.projectDetails?.nodeId);
this.getProjectBasedData();
this.isAdminForSelectedProject = this.getAuthorizationService.checkIfSuperUser() || !this.getAuthorizationService.checkIfViewer(this.projectDetails);
}
Expand All @@ -305,6 +311,12 @@ export class CapacityPlanningComponent implements OnInit {
}
}

getSquadsOfSelectedProject(projectName){
if (projectName) {
this.selectedSquad = [...this.squadListArr?.filter((x) => x['path'][0]?.includes(projectName))];
}
}

getCapacityData(projectId) {
this.http_service.getCapacityData(projectId).subscribe((response) => {
if (response && response?.success && response?.data) {
Expand Down Expand Up @@ -495,6 +507,7 @@ export class CapacityPlanningComponent implements OnInit {
this.selectedSprintAssigneFormArray.push(
{
role: new FormControl(assignee.role),
squad: new FormControl(assignee.squad),
plannedCapacity: new FormControl({ value: assignee.plannedCapacity, disabled: !assignee.role }, [Validators.pattern('[0-9]*')]),
leaves: new FormControl({ value: assignee.leaves, disabled: !(assignee?.role && assignee?.plannedCapacity) }, [Validators.min(0), Validators.max(assignee.plannedCapacity)])
}
Expand All @@ -505,7 +518,8 @@ export class CapacityPlanningComponent implements OnInit {

calculateAvaliableCapacity(assignee, assigneeFormControls, fieldName) {
assignee[fieldName] = assigneeFormControls[fieldName]?.value;
if (fieldName === 'role') {

if (this.checkMandatoryFields(assigneeFormControls, fieldName)) {
assigneeFormControls.plannedCapacity.enable();
} else {
if (assigneeFormControls.plannedCapacity.value > 0) {
Expand Down Expand Up @@ -541,6 +555,7 @@ export class CapacityPlanningComponent implements OnInit {

onSprintCapacitySave(selectedSprint) {
selectedSprint.capacity = this.calculateTotalCapacityForSprint(selectedSprint);
selectedSprint.additionalFilterCapacityList = this.generateAdditionalFilterCapacityList( selectedSprint);
this.projectCapacityEditMode = false;
const postData = { ...selectedSprint };
delete postData['id'];
Expand Down Expand Up @@ -586,12 +601,28 @@ export class CapacityPlanningComponent implements OnInit {
});
}


enableDisableSubmitButton() {
if (this.selectedView === 'upload_Sprint_Capacity') {
this.enableDisableCapacitySubmitButton();
if(this.selectedSquad.length>0 && this.squadForm!=null){
this.isCapacitySaveDisabled = false;
this.capacityErrorMessage = '';
Object.entries(this.squadForm?.value).forEach(([key, value]) => {
if (value == null || (value instanceof FormControl && value.value == null)) {
this.isCapacitySaveDisabled = true;
this.capacityErrorMessage = 'Please enter Capacity';
return;
}
});

}
else{
this.enableDisableCapacitySubmitButton();
}
}
}


enableDisableCapacitySubmitButton() {
if (this.popupForm.get('capacity')?.value && this.popupForm.get('capacity')?.value === 'Enter Value') {
this.isCapacitySaveDisabled = true;
Expand Down Expand Up @@ -629,10 +660,45 @@ export class CapacityPlanningComponent implements OnInit {
this.reqObj['sprintNodeId'] = this.selectedSprintId;
}
if (this.selectedView === 'upload_Sprint_Capacity') {
this.popupForm = new UntypedFormGroup({
capacity: new UntypedFormControl(data?.capacity ? data?.capacity : '')
});
this.reqObj['capacity'] = data?.capacity ? data?.capacity : '';;

if (this.selectedSquad.length > 0) {

if (data?.additionalFilterCapacityList) {
const flattened = data.additionalFilterCapacityList.flatMap(item => item.nodeCapacityList);
this.selectedSquad.forEach(squad => {
const matchingFilter = flattened.find(filter => filter.additionalFilterId === squad.nodeId);

if (matchingFilter) {
if (!this.squadForm.controls[squad.nodeId]) {
this.squadForm.addControl(squad.nodeId, new UntypedFormControl(matchingFilter.additionalFilterCapacity));
} else {
this.squadForm.controls[squad.nodeId].setValue(matchingFilter.additionalFilterCapacity);
}
} else {
if (!this.squadForm.controls[squad.nodeId]) {
this.squadForm.addControl(squad.nodeId, new UntypedFormControl(null));
}
}

});
}
else {
this.selectedSquad.forEach(squad => {
let control= new UntypedFormControl();
if (this.squadForm.get(squad.nodeId)) {
// Update existing control
this.squadForm.get(squad.nodeId).setValue(control);
} else {
// Add new control
this.squadForm.addControl(squad.nodeId, control);
}
});
}
}

this.popupForm = new UntypedFormGroup({capacity: new UntypedFormControl(data?.capacity ? data?.capacity : '')});

this.reqObj['capacity'] = data?.capacity ? data?.capacity : '';
if (this.kanban) {
this.reqObj['startDate'] = data?.startDate;
this.reqObj['endDate'] = data?.endDate;
Expand All @@ -651,7 +717,13 @@ export class CapacityPlanningComponent implements OnInit {

// called on the click of the Submit button when creating capacity per sprint(hrs)
submitCapacity() {
this.reqObj['capacity'] = this.popupForm?.get('capacity').value;
if(this.squadForm?.value && Object.keys(this.squadForm.value).length > 0){
this.reqObj['additionalFilterCapacityList'] = this.toggleOffGenerateAdditionalFilterCapacityList(this.squadForm?.value)
this.reqObj['capacity'] = Object.values(this.squadForm?.value).reduce((acc: number, value: number) => acc + value, 0).toString();
}
else{
this.reqObj['capacity'] = this.popupForm?.get('capacity').value;
}
this.http_service.saveCapacity(this.reqObj)
.subscribe(response => {
if (response.success) {
Expand All @@ -672,6 +744,7 @@ export class CapacityPlanningComponent implements OnInit {
this.isCapacitySaveDisabled = true;
this.capacityErrorMessage = '';
});

}

setFormValuesEmpty() {
Expand All @@ -689,11 +762,23 @@ export class CapacityPlanningComponent implements OnInit {
}
});
}

if (this.reqObj) {
for (const capReqField in this.reqObj) {
this.reqObj[capReqField] = '';
}
}

this.clearSquadForm();
}

clearSquadForm(){
if (this.squadForm && this.squadForm.controls) {
Object.keys(this.squadForm?.controls).forEach(key => {
this.squadForm.removeControl(key);
});

}
}


Expand All @@ -709,5 +794,103 @@ export class CapacityPlanningComponent implements OnInit {
}
}

checkMandatoryFields(assigneeFormControls, fieldName) {
if(fieldName==='role'|| fieldName==='squad'){
const roleValue = assigneeFormControls['role']?.value;
const squadValue = assigneeFormControls['squad']?.value;
if (this.selectedSquad.length > 0){
if((squadValue !== null) && (roleValue !== null)){
return true;
}
}
else if(roleValue !== null){
return true;
}
}
return false;
}

generateAdditionalFilterCapacityList(selectedSprint) {
if (this.selectedSquad.length > 0){
const squadCapacityMap: { [key: string]: { [key: string]: number } } = {};

// Group by squad and sum availableCapacity
selectedSprint.assigneeCapacity.forEach(member => {
const squad = this.selectedSquad.find(squad => squad.nodeId === member.squad);
if (squad) {
if (!squadCapacityMap[squad.labelName]) {
squadCapacityMap[squad.labelName] = {};
}
if (!squadCapacityMap[squad.labelName][squad.nodeId]) {
squadCapacityMap[squad.labelName][squad.nodeId] = 0;
}
squadCapacityMap[squad.labelName][squad.nodeId] += member.availableCapacity;
}
});

return this.createAdditionalFilterCapacityList(squadCapacityMap);
}

}

toggleOffGenerateAdditionalFilterCapacityList(capacityObject: { [key: string]: number }) {
if (this.selectedSquad.length > 0) {
const squadCapacityMap: { [key: string]: { [key: string]: number } } = {};

// Group by squad and sum availableCapacity
for (const key in capacityObject) {
const value = capacityObject[key];
const squad = this.selectedSquad.find(squad => key.includes(squad.nodeId));
if (squad) {
if (!squadCapacityMap[squad.labelName]) {
squadCapacityMap[squad.labelName] = {};
}
if (!squadCapacityMap[squad.labelName][squad.nodeId]) {
squadCapacityMap[squad.labelName][squad.nodeId] = 0;
}
squadCapacityMap[squad.labelName][squad.nodeId] += value;
}
}
return this.createAdditionalFilterCapacityList(squadCapacityMap);
}
}

createAdditionalFilterCapacityList( squadCapacityMap ){
const additionalFilterCapacityList = [];

for (const labelName in squadCapacityMap) {
const nodeCapacityList = Object.keys(squadCapacityMap[labelName]).map(nodeId => {
return {
additionalFilterId: nodeId,
additionalFilterCapacity: squadCapacityMap[labelName][nodeId]
};
});

additionalFilterCapacityList.push({
filterId: labelName,
nodeCapacityList: nodeCapacityList
});
}

return additionalFilterCapacityList;

}

getNodeName(assignee) {
if (assignee?.squad) {
const squad = this.selectedSquad.find(s => s.nodeId === assignee.squad);
return squad ? squad.nodeName : '- -';
}
return '- -';
}


getSortedAdditonalFilter(projectListArr) {
//Get the levels of the projects in projectListArr
let projectMap= projectListArr.map(project => project.level);
// Step 3: Filter out the objects from filterData which have a level that is exactly 2 levels above any project level
return this.sortAlphabetically(this.filterData.filter(data => projectMap.includes(data.level - 2)));

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ <h5 class="card__primary__title__text p-mb-0">Basic Configuration</h5>
<p-autoComplete id="{{ field.hierarchyLevelId }}"
[formControlName]="field.hierarchyLevelId" [style]="{'width':'500px'}"
[suggestions]="field.filteredSuggestions" (completeMethod)="search($event, field)"
required="required" [dropdown]="true" field="name" [forceSelection]="true">
required="required" [dropdown]="true" field="name">
<ng-template let-country pTemplate="item">
<div class="country-item">
<div>{{country.name}}</div>
Expand Down Expand Up @@ -151,4 +151,4 @@ <h5 class="card__primary__title__text p-mb-0">Basic Configuration</h5>
</div>
</div>
</div>
<p-blockUI [blocked]="blocked"></p-blockUI>
<p-blockUI [blocked]="blocked"></p-blockUI>
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export class BasicConfigComponent implements OnInit {

stringValidator(control: AbstractControl): { [key: string]: boolean } | null {
const inputValue: string = control.value as string;
if ((typeof control.value === 'string' || control.value instanceof String) && control.value && control.value !== null && !/^[a-zA-Z0-9\s]+$/.test(inputValue)) {
if ((typeof control.value === 'string' || control.value instanceof String) && control.value && control.value !== null && !/^[a-zA-Z0-9\s_-]+$/.test(inputValue)) {
return { stringValidator: true };
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ <h5 class="card__primary__title__text p-m-0">{{formTitle}} Configuration</h5>
<label for="{{form_elem.id}}">{{form_elem.label}}</label>
<textarea pInputTextarea id="{{form_elem.id}}" formControlName="{{form_elem.id}}"
[ngClass]="{ 'p-invalid': submitted && tool[form_elem.id].errors}"
[attr.disabled]="!this[form_elem.disabled] ? true : null"></textarea>
[attr.disabled]="!this[form_elem?.disabled] && this[form_elem?.disabled]!=undefined? true : null"></textarea>
</ng-container>
</div>
<div *ngSwitchCase="'basicDropdown'" class="p-mb-3">
Expand Down Expand Up @@ -324,4 +324,4 @@ <h5 class="card__primary__title__text p-m-0">{{formTitle}} Configuration</h5>
</div>
</div>
</div>
<app-page-loader *ngIf="isLoading"></app-page-loader>
<app-page-loader *ngIf="isLoading"></app-page-loader>
Loading
Loading