From 0169d15c9e88c8fea448c24fe0fa71ffb4734af0 Mon Sep 17 00:00:00 2001 From: marzmehr Date: Thu, 15 Feb 2024 17:35:51 -0800 Subject: [PATCH 1/3] SS-773: Add functionality to select multiple training types to pull reports --- api/models/dto/TrainingReportSearchDto.cs | 2 +- api/services/ManageTypesService.cs | 4 +- .../usermanagement/TrainingService.cs | 4 +- web/package.json | 3 + web/src/components/MyTeam/ViewReports.vue | 130 +- web/src/main.ts | 4 + web/src/styles/vuetify.scss | 29625 ++++++++++++++++ web/src/types/common/index.ts | 2 +- 8 files changed, 29742 insertions(+), 32 deletions(-) create mode 100644 web/src/styles/vuetify.scss diff --git a/api/models/dto/TrainingReportSearchDto.cs b/api/models/dto/TrainingReportSearchDto.cs index 7b52535f..57d002d7 100644 --- a/api/models/dto/TrainingReportSearchDto.cs +++ b/api/models/dto/TrainingReportSearchDto.cs @@ -7,7 +7,7 @@ public class TrainingReportSearchDto { public int? regionId { get; set; } public int? locationId { get; set; } - public int? reportSubtypeId { get; set; } + public int[]? reportSubtypeIds { get; set; } public DateTimeOffset? startDate { get; set; } public DateTimeOffset? endDate { get; set; } } diff --git a/api/services/ManageTypesService.cs b/api/services/ManageTypesService.cs index b85e76b1..dcfd244e 100644 --- a/api/services/ManageTypesService.cs +++ b/api/services/ManageTypesService.cs @@ -139,12 +139,12 @@ public async Task> GetAll(LookupTypes? codeType, int? locationI return lookupCodes; } - public async Task> GetAllForReports(int? id, LookupTypes? codeType, int? locationId, bool? mandatory, bool showExpired = false) + public async Task> GetAllForReports(int[]? ids, LookupTypes? codeType, int? locationId, bool? mandatory, bool showExpired = false) { var lookupCodes = await Db.LookupCode.AsNoTracking() .Include(lc => lc.SortOrder.Where(so => so.LocationId == locationId)) .Where(lc => - (id == null || lc.Id == id) && + (ids == null || ids.Length==0 || ids.Contains(lc.Id)) && (codeType == null || lc.Type == codeType) && (locationId == null || lc.LocationId == null || lc.LocationId == locationId) && (mandatory == null || lc.Mandatory == mandatory) && diff --git a/api/services/usermanagement/TrainingService.cs b/api/services/usermanagement/TrainingService.cs index 5d2feb24..9ae201af 100644 --- a/api/services/usermanagement/TrainingService.cs +++ b/api/services/usermanagement/TrainingService.cs @@ -80,8 +80,8 @@ public async Task> GetSheriffsTrainingReports(TrainingRe var sheriffs = await sheriffQuery.ToListAsync(); - List mandatoryTrainings = await ManageTypesService.GetAllForReports(trainingReportSearch.reportSubtypeId, LookupTypes.TrainingType, null, true, false); - List optionalTrainings = await ManageTypesService.GetAllForReports(trainingReportSearch.reportSubtypeId, LookupTypes.TrainingType, null, false, false); + List mandatoryTrainings = await ManageTypesService.GetAllForReports(trainingReportSearch.reportSubtypeIds, LookupTypes.TrainingType, null, true, false); + List optionalTrainings = await ManageTypesService.GetAllForReports(trainingReportSearch.reportSubtypeIds, LookupTypes.TrainingType, null, false, false); var sheriffTrainings = new List(); diff --git a/web/package.json b/web/package.json index 36af3055..82da3ee9 100644 --- a/web/package.json +++ b/web/package.json @@ -14,6 +14,7 @@ "@fortawesome/free-solid-svg-icons": "^5.15.1", "@fortawesome/vue-fontawesome": "^2.0.0", "@types/underscore": "^1.10.0", + "@mdi/font": "^6.5.95", "ansi-regex": "^6.0.1", "axios": "^0.21.4", "axios-auth-refresh": "^3.2.1", @@ -44,6 +45,7 @@ "vue-property-decorator": "^8.4.2", "vue-resource": "^1.5.3", "vue-router": "^3.1.6", + "vuetify": "^2.6.3", "vuex": "^3.3.0", "vuex-class": "^0.3.2", "vuex-module-decorators": "^0.17.0" @@ -68,6 +70,7 @@ "ts-loader": "^7.0.1", "tslib": "^1.11.1", "typescript": "3.8.3", + "vue-cli-plugin-vuetify": "~2.0.5", "vue-template-compiler": "2.6.11", "webpack-bundle-analyzer": "^4.5.0" }, diff --git a/web/src/components/MyTeam/ViewReports.vue b/web/src/components/MyTeam/ViewReports.vue index f22e423a..7adbe495 100644 --- a/web/src/components/MyTeam/ViewReports.vue +++ b/web/src/components/MyTeam/ViewReports.vue @@ -64,25 +64,51 @@ - - - - + + + - - All Training Types - - - {{trainingType.code}} - - - + :items="trainingTypeOptions" + label="Select" + item-text="code" + item-value="id" + :error="!reportSubTypeState" + multiple + flat + hide-details + solo> + + + + @@ -233,7 +259,7 @@ error = ''; updateRegionId = 0; printReady = false; - reportParameters = {region: 'All', location: 'All', reportSubtype: 'All', reportType:'Training'} as reportInfoType; + reportParameters = {region: 'All', location: 'All', reportSubtype: [0], reportType:'Training'} as reportInfoType; reportDateRange = { startDate:'', endDate:'', valid:false} as dateRangeInfoType trainingReportData: trainingReportInfoType[] = [] filteredTrainingReportData: trainingReportInfoType[] = [] @@ -272,16 +298,16 @@ this.dataReady = false; this.clearReports(); this.reportParameters.region = 'All'; - this.reportParameters.location = 'All'; - this.reportParameters.reportSubtype = 'All'; + this.reportParameters.location = 'All'; this.searching = false; this.generatingReport = false; this.locationOptionsList = this.locationList; - this.getTrainingTypes(); + this.getTrainingTypes(); } public clearReports(){ this.dataLoaded = false; + this.reportSubTypeState = true this.trainingReportData = []; this.excludedTrainingReportData = []; } @@ -295,7 +321,7 @@ if (!this.reportParameters.reportType){ this.reportTypeState = false; } - else if (!this.reportParameters.reportSubtype){ + else if (this.reportParameters.reportSubtype?.length==0){ this.reportSubTypeState = false; } else { @@ -304,7 +330,7 @@ regionId: this.reportParameters.region == 'All'? null : this.reportParameters.region, locationId: this.reportParameters.location == 'All'? null : this.reportParameters.location, // reportType: this.reportParameters.reportType, - reportSubtypeId: this.reportParameters.reportSubtype == 'All'? null : this.reportParameters.reportSubtype, + reportSubtypeIds: this.likesAllSubtypes? [] : this.reportParameters.reportSubtype, startDate: this.reportDateRange.valid? this.reportDateRange.startDate : null, endDate: this.reportDateRange.valid? this.reportDateRange.endDate : null } @@ -382,6 +408,7 @@ if(response.data){ this.trainingTypeOptions = response.data; } + this.reportParameters.reportSubtype = this.trainingTypeOptions.map(t => t.id) this.dataReady = true; },err => { @@ -399,7 +426,7 @@ const url = 'api/sheriff/updateExcused'; this.$http.put(url, body) - .then(response => { + .then(() => { this.find() }, err => { this.error = err.response.data.error; @@ -441,10 +468,61 @@ this.paginationExcludedKey++; } + public toggle () { + Vue.nextTick(() => { + if (this.likesAllSubtypes) { + this.reportParameters.reportSubtype = [] + } else { + this.reportParameters.reportSubtype = this.trainingTypeOptions.map(t => t.id) + } + }) + } + + get likesAllSubtypes(){ + return this.trainingTypeOptions.length==this.reportParameters.reportSubtype.length + } + + get likesSomeSubtypes() { + return this.trainingTypeOptions.length > 0 && !this.likesAllSubtypes + } + + get icon () { + if (this.likesAllSubtypes) return 'mdi-close-box' + if (this.likesSomeSubtypes) return 'mdi-minus-box' + return 'mdi-checkbox-blank-outline' + } + } -