@byu-oit/vue-decision-processing-components 8.36.1 → 8.36.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SearchForm.vue ADDED
@@ -0,0 +1,177 @@
1
+ <template>
2
+ <div class="search-form p-2">
3
+ <form @submit.prevent="doSearch(null)">
4
+ <div class="p-1 d-inline-block">
5
+ <div class="custom-control custom-switch">
6
+ <input type="checkbox" class="custom-control-input float-end" id="searchNewAppSwitch" v-model="searchNewApp">
7
+ <label class="custom-control-label" for="searchNewAppSwitch">{{ searchNewApp ? 'NEW' : 'OLD' }} App</label>
8
+ </div>
9
+
10
+ <label for="lastNameInput">Last Name/ID</label>
11
+ <input id="lastName00Input" v-model="lastName" @focus="$event.target.select()">
12
+
13
+ <label for="firstNameInput">First Name</label>
14
+ <input id="firstNameInput" v-model="firstName" @focus="$event.target.select()">
15
+
16
+ <label for="monthInput">Birthdate</label>
17
+ <input id="monthInput" aria-label="month" placeholder="mm" v-model="month" @focus="$event.target.select()" @blur="month = month.length===1 ? '0' + month : month" size="2" maxlength="2" :required="day !== '' || year !== ''">
18
+ <input id="dayInput" aria-label="day" placeholder="dd" v-model="day" @focus="$event.target.select()" @blur="day = day.length===1 ? '0' + day : day" size="2" maxlength="2" :required="month !== '' || year !== ''">
19
+ <input id="yearInput" aria-label="year" placeholder="yyyy" v-model="year" @focus="$event.target.select()" size="4" maxlength="4" :required="month !== '' || day !== ''">
20
+ </div>
21
+
22
+ <button id="submitBtn" type="submit" class="btn btn-sm btn-outline-primary">
23
+ {{searching ? 'Searching' : 'Search'}}
24
+ <FontAwesomeIcon v-if="searching" :icon="icon" :spin="searching" />
25
+ </button>
26
+ </form>
27
+ <SearchResults :results="results" @searchPaginate="doSearch" @select="$emit('select', { appId: $event, searchNewApp })" />
28
+ </div>
29
+ </template>
30
+ <script>
31
+ import SearchResults from './SearchResults.vue'
32
+ import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'
33
+ import {faSpinner} from '@fortawesome/free-solid-svg-icons'
34
+ import {mapActions} from "vuex";
35
+
36
+ export default {
37
+ name: 'SearchForm',
38
+ components: {
39
+ SearchResults,
40
+ FontAwesomeIcon
41
+ },
42
+ data() {
43
+ return {
44
+ lastName: '',
45
+ firstName: '',
46
+ month: '',
47
+ day: '',
48
+ year: '',
49
+ results: {},
50
+ searchNewApp: true,
51
+ searching: false
52
+ }
53
+ },
54
+ computed: {
55
+ icon() {
56
+ return faSpinner
57
+ },
58
+ birthDate() {
59
+ if (!(this.year.length === 4 && this.month.length === 2 && this.day.length === 2)) {
60
+ return ''
61
+ }
62
+ return this.year + '-' + this.month + '-' + this.day
63
+ }
64
+ },
65
+ methods: {
66
+ // mapActions is a Vuex helper function that maps stored actions to a local method
67
+ ...mapActions({
68
+ oldSearchFunction: 'oldAppSearch',
69
+ newSearchFunction: 'newAppSearch'
70
+ }),
71
+
72
+ async doSearch(pageLink) {
73
+ this.lastName = this.lastName.trim()
74
+ this.firstName = this.firstName.trim()
75
+
76
+ if (this.searchNewApp) {
77
+ this.results = await this.newAppSearch()
78
+ } else {
79
+ this.results = await this.oldAppSearch(pageLink)
80
+ }
81
+
82
+ if (!this.results) return
83
+
84
+ if (this.results.people.length === 1) {
85
+ this.$emit('select', {appId: this.results.people[0].appId, searchNewApp: this.searchNewApp})
86
+ } else {
87
+ this.$modal.show('search-results')
88
+ }
89
+
90
+ // clear search fields
91
+ this.lastName = ''
92
+ this.firstName = ''
93
+ this.year = ''
94
+ this.month = ''
95
+ this.day = ''
96
+ },
97
+ async newAppSearch() {
98
+ const params = {}
99
+ if (this.lastName.length > 0) {
100
+ if (this.firstName.length > 0) {
101
+ params.surname = this.lastName
102
+ params.first_name = this.firstName
103
+ } else {
104
+ params.search = this.lastName
105
+ }
106
+ } else if (this.firstName.length > 0) {
107
+ params.first_name = this.firstName
108
+ }
109
+ if (this.birthDate) {
110
+ params.birth_date = this.birthDate
111
+ }
112
+
113
+ if (Object.keys(params).length === 0) {
114
+ alert('No search terms specified!')
115
+ return
116
+ }
117
+
118
+ this.searching = true
119
+ return this.newSearchFunction(params)
120
+ .finally(() => this.searching = false)
121
+ },
122
+ async oldAppSearch(pageLink) {
123
+ let params = {}
124
+ if (this.lastName.length > 0) {
125
+ if (this.firstName.length > 0) {
126
+ params.last_name = this.lastName
127
+ params.first_name = this.firstName
128
+ if (this.birthDate) {
129
+ params.birth = this.birthDate
130
+ }
131
+ } else if (this.birthDate) {
132
+ params.last_name = this.lastName
133
+ params.birth = this.birthDate
134
+ } else {
135
+ params.search = this.lastName
136
+ }
137
+ } else if (this.firstName.length > 0) {
138
+ params.first_name = this.firstName
139
+ if (this.birthDate) {
140
+ params.birth = this.birthDate
141
+ }
142
+ }
143
+ if (Object.keys(params).length === 0) {
144
+ alert('No search terms specified!')
145
+ return
146
+ }
147
+
148
+ this.searching = true
149
+ return this.oldSearchFunction(params, pageLink)
150
+ .finally(() => this.searching = false)
151
+ }
152
+ }
153
+ }
154
+ </script>
155
+ <style scoped>
156
+ .search-form {
157
+ box-shadow: inset 0rem 0.1rem 0.1rem rgba(0, 0, 0, 0.25);
158
+ }
159
+
160
+ .custom-switch .custom-control-label::before,
161
+ .custom-control-label::before {
162
+ right: -2.25rem;
163
+ left: unset;
164
+ }
165
+
166
+ .custom-switch .custom-control-label::after,
167
+ .custom-control-label::after {
168
+ right: calc(-1.5rem + 2px);
169
+ left: unset;
170
+ }
171
+
172
+ .custom-switch {
173
+ display: inherit;
174
+ padding-right: 2.25rem;
175
+ padding-left: unset;
176
+ }
177
+ </style>
@@ -0,0 +1,113 @@
1
+ <template>
2
+ <modal name="search-results" :width="dialogWidth" height="auto" :scrollable="true">
3
+ <div class="bg-light p-1 text-uppercase">Search Results</div>
4
+ <div class="search-results p-2">
5
+ <div class="results">
6
+ <table class="table table-sm table-striped table-hover">
7
+ <thead>
8
+ <th>Name</th>
9
+ <th>Birthday</th>
10
+ <th>BYU ID</th>
11
+ <th>Net ID</th>
12
+ <th>Applicant Type</th>
13
+ <th>Admit Period</th>
14
+ <th>Application Status</th>
15
+ <th>Submitted On</th>
16
+ </thead>
17
+ <tbody>
18
+ <tr v-for="row of filteredApps" :key="row.appId">
19
+ <td>
20
+ <a href="#" @click.prevent="$emit('select', row.appId)">
21
+ {{row.name}}
22
+ </a>
23
+ </td>
24
+ <td>{{row.dateOfBirth | dateFormat}}</td>
25
+ <td>{{row.byuId}}</td>
26
+ <td>{{row.netId}}</td>
27
+ <td>{{row.applicantType}}</td>
28
+ <td>{{row.admitPeriod | yearTerm }}</td>
29
+ <td>{{row.applicationStatus + (row.decisionQualifier ? ' | ' + row.decisionQualifier : '')}}</td>
30
+ <td>{{row.submittedDate | dateFormat}}</td>
31
+ </tr>
32
+ </tbody>
33
+ </table>
34
+ </div>
35
+ <span class="modal-footer">
36
+ <input type="checkbox" v-model="showNonPending" id="showNonPending">
37
+ <label for="showNonPending">Show Closed/Past Applications</label>
38
+ <button v-if="results.prev" @click="prev" class="btn btn-outline-info">Prev Page</button>
39
+ <button v-if="results.next" @click="next" class="btn btn-outline-info">Next Page</button>
40
+ <button @click="close" class="btn btn-outline-secondary">Close</button>
41
+ </span>
42
+ </div>
43
+ </modal>
44
+ </template>
45
+ <script>
46
+ export default {
47
+ name: 'SearchResults',
48
+ props: {
49
+ results: {
50
+ type: Object,
51
+ default() {
52
+ return {next: null, prev: null, people: []}
53
+ }
54
+ }
55
+ },
56
+ data() {
57
+ return {
58
+ showNonPending: false
59
+ }
60
+ },
61
+ computed: {
62
+ dialogWidth() {
63
+ const vw = v => {
64
+ const w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0)
65
+ return (v * w) / 100
66
+ }
67
+ const desiredWidth = vw(80)
68
+ return Math.max(800, desiredWidth)
69
+ },
70
+ filteredApps() {
71
+ if (this.showNonPending) {
72
+ return this.results.people
73
+ }
74
+ if (!Array.isArray(this.results.people)) {
75
+ return []
76
+ }
77
+ console.log(this.results.people[0])
78
+ return this.results.people.filter(({applicationStatusValue}) => ['OPEN', 'SUBMITTED'].includes(applicationStatusValue))
79
+ }
80
+ },
81
+ methods: {
82
+ close() {
83
+ this.$modal.hide('search-results')
84
+ },
85
+ prev() {
86
+ const link = this.results.prev
87
+ this.$emit('searchPaginate', link)
88
+ },
89
+ next() {
90
+ const link = this.results.next
91
+ this.$emit('searchPaginate', link)
92
+ }
93
+ },
94
+ watch: {
95
+ $route: {
96
+ handler() {
97
+ this.close()
98
+ },
99
+ deep: true
100
+ },
101
+ results: {
102
+ handler() {
103
+ if (!this.showNonPending && this.results.people.length > 0 && this.filteredApps.length === 0) {
104
+ this.showNonPending = true
105
+ }
106
+ },
107
+ deep: true
108
+ }
109
+ }
110
+ }
111
+ </script>
112
+ <style scoped>
113
+ </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byu-oit/vue-decision-processing-components",
3
- "version": "8.36.1",
3
+ "version": "8.36.2",
4
4
  "description": "Vue components shared between decision processing systems for the CES schools.",
5
5
  "dependencies": {
6
6
  "@fortawesome/fontawesome-free": "^5.15.4",