Lene Scholtz 5 年前
父节点
当前提交
b96d90e8e9

+ 1
- 4
public/index.html 查看文件

@@ -33,10 +33,7 @@
33 33
 <script src="lib/easing/easing.min.js"></script>
34 34
 <script src="lib/owlcarousel/owl.carousel.min.js"></script>
35 35
 <script src="lib/scrollreveal/scrollreveal.min.js"></script>
36
-<script src="js/dragndrop.table.columns.js" type="text/javascript"></script>
37 36
 <script src="js/main.js"></script>
38
-<script>
39
-  $('.table').dragableColumns();
40
-</script>
37
+
41 38
 
42 39
 </html>

+ 33
- 8
src/App.vue 查看文件

@@ -13,29 +13,29 @@
13 13
 </template>
14 14
 
15 15
 <script>
16
-import SearchTab from './components/shared/searchTab.vue';
17
-import NavBar from './components/shared/navBar.vue';
18
-import FooterSection from './components/shared/footerSection.vue';
16
+import SearchTab from "./components/shared/searchTab.vue";
17
+import NavBar from "./components/shared/navBar.vue";
18
+import FooterSection from "./components/shared/footerSection.vue";
19 19
 
20 20
 export default {
21
-  name: 'app',
21
+  name: "app",
22 22
   components: {
23 23
     SearchTab,
24 24
     NavBar,
25
-    FooterSection,
25
+    FooterSection
26 26
   },
27 27
   methods: {
28 28
     routerGoTo(goTo) {
29 29
       this.$router.push(goTo);
30
-    },
31
-  },
30
+    }
31
+  }
32 32
 };
33 33
 </script>
34 34
 
35 35
 <style>
36 36
 button:hover {
37 37
   cursor: pointer;
38
-},
38
+}
39 39
 hr {
40 40
   background-color: #60cbeb;
41 41
 }
@@ -101,6 +101,31 @@ html {
101 101
   height: 100%;
102 102
   margin: 0;
103 103
 }
104
+.isSelected {
105
+  border-color: white white #60cbeb white;
106
+}
107
+.isUnSelected {
108
+  border-color: white white white white;
109
+}
110
+.tabButton {
111
+  display: block;
112
+  padding: 0.5rem 1rem;
113
+  background-color: white;
114
+  border-style: none none solid none;
115
+  width: 100px;
116
+}
117
+.top-left {
118
+  position: absolute;
119
+  top: 8px;
120
+  width: 350px;
121
+  color: white;
122
+}
123
+.normalText {
124
+  background-color: #60cbeb;
125
+}
126
+.pendingOffer {
127
+  background-color: #ff8344;
128
+}
104 129
 </style>
105 130
 
106 131
 <style scoped>

+ 35
- 0
src/components/property/propertyCard.vue 查看文件

@@ -1,4 +1,5 @@
1 1
 <template>
2
+  <!-- eslint-disable max-len -->
2 3
   <div>
3 4
     <div class="form-group row" v-if="showSort">
4 5
       <button
@@ -19,6 +20,13 @@
19 20
         style="width: 150px; height:40px;"
20 21
         @click="sortHighPrice()"
21 22
       >Highest Price</button>
23
+      <button
24
+        v-if="salesType === 'Rent'"
25
+        type="button"
26
+        class="btn btn-link font-weight-bold color-b"
27
+        style="width: 150px; height:40px;"
28
+        @click="sortDateAvailable()"
29
+      >Date Available</button>
22 30
       <hr />
23 31
     </div>
24 32
     <div class="form-group row">
@@ -32,6 +40,18 @@
32 40
                 class="img-a img-fluid"
33 41
                 style="height:466px; width:350px; object-fit: cover;"
34 42
               />
43
+              <p
44
+                v-if="!currentProperty.isSale"
45
+                :class="[currentProperty.hasPendingOffer ? 'top-left pendingOffer' : 'top-left normalText']"
46
+              >
47
+                <strong>{{ currentProperty.available }}</strong>
48
+              </p>
49
+              <p
50
+                v-if="currentProperty.isSale  && currentProperty.hasPendingOffer"
51
+                class="top-left pendingOffer"
52
+              >
53
+                <strong>{{ currentProperty.available }}</strong>
54
+              </p>
35 55
             </div>
36 56
             <div class="card-overlay">
37 57
               <div class="card-overlay-a-content">
@@ -41,6 +61,11 @@
41 61
                       :to="`/property/property/${currentProperty.id}`"
42 62
                       class="link-a"
43 63
                     >{{ currentProperty.shortDescription }}</router-link>
64
+                    <router-link
65
+                      v-if="!currentProperty.isSale"
66
+                      :to="`/property/property/${currentProperty.id}`"
67
+                      class="link-a"
68
+                    ></router-link>
44 69
                   </h4>
45 70
                   <h4 class="card-title-c">
46 71
                     <router-link :to="`/property/property/${currentProperty.id}`" class="link-a">
@@ -113,6 +138,7 @@ export default {
113 138
   props: {
114 139
     properties: { type: Array, default: () => [] },
115 140
     showSort: { type: Boolean, default: true },
141
+    salesType: { type: String, default: 'Rent' },
116 142
   },
117 143
   methods: {
118 144
     sortHighPrice() {
@@ -140,6 +166,15 @@ export default {
140 166
         return 0;
141 167
       }
142 168
 
169
+      return this.properties.sort(compare);
170
+    },
171
+    sortDateAvailable() {
172
+      function compare(a, b) {
173
+        if (a.dateAvailable > b.dateAvailable) return 1;
174
+        if (a.dateAvailable < b.dateAvailable) return -1;
175
+        return 0;
176
+      }
177
+
143 178
       return this.properties.sort(compare);
144 179
     },
145 180
   },

+ 59
- 19
src/components/property/propertyCreate.vue 查看文件

@@ -71,9 +71,11 @@
71 71
                     @change="PropertyTypeSelected"
72 72
                   >
73 73
                     <option value="0">Please select type</option>
74
-                    <option v-for="item in propertyTypes" :value="item.id" :key="item.id">{{
74
+                    <option v-for="item in propertyTypes" :value="item.id" :key="item.id">
75
+                      {{
75 76
                       item.description
76
-                    }}</option>
77
+                      }}
78
+                    </option>
77 79
                   </select>
78 80
                 </div>
79 81
                 <div v-if="showPropertyTypeError">
@@ -155,9 +157,11 @@
155 157
                     v-model="property.provinceId"
156 158
                   >
157 159
                     <option value="0">Please select province</option>
158
-                    <option v-for="province in provinces" :value="province.id" :key="province.id">{{
160
+                    <option v-for="province in provinces" :value="province.id" :key="province.id">
161
+                      {{
159 162
                       province.description
160
-                    }}</option>
163
+                      }}
164
+                    </option>
161 165
                   </select>
162 166
                 </div>
163 167
                 <div v-if="showProvinceError">
@@ -179,9 +183,11 @@
179 183
                     v-model="property.cityId"
180 184
                   >
181 185
                     <option value="0">Please select city</option>
182
-                    <option v-for="city in cities" :value="city.id" :key="city.id">{{
186
+                    <option v-for="city in cities" :value="city.id" :key="city.id">
187
+                      {{
183 188
                       city.description
184
-                    }}</option>
189
+                      }}
190
+                    </option>
185 191
                   </select>
186 192
                 </div>
187 193
                 <div v-if="showCityError">
@@ -202,9 +208,11 @@
202 208
                     @change="getPostalCode"
203 209
                   >
204 210
                     <option value="0">Please select suburb</option>
205
-                    <option v-for="suburb in suburbs" :value="suburb.id" :key="suburb.id">{{
211
+                    <option v-for="suburb in suburbs" :value="suburb.id" :key="suburb.id">
212
+                      {{
206 213
                       suburb.description
207
-                    }}</option>
214
+                      }}
215
+                    </option>
208 216
                   </select>
209 217
                 </div>
210 218
                 <div v-if="showSuburbError">
@@ -264,6 +272,16 @@
264 272
                 </div>
265 273
               </div>
266 274
             </div>
275
+            <div class="form-group row" v-if="salesType === 'Rental'">
276
+              <div class="col-md-12">
277
+                <input
278
+                  type="date"
279
+                  class="form-control"
280
+                  name="date"
281
+                  v-model="property.dateAvailable"
282
+                />
283
+              </div>
284
+            </div>
267 285
             <div class="form-group row">
268 286
               <div class="col-md-12">
269 287
                 <label for="Property Description">Description</label>
@@ -357,15 +375,13 @@
357 375
               @click="SubmitData()"
358 376
               class="btn btn-b-n"
359 377
               style="width: 85px; height:40px;"
360
-            >
361
-              Save
362
-            </button>
378
+            >Save</button>
363 379
             <div
364 380
               v-if="showPropertyTypeError || showProvinceError || showCityError || showSuburbError"
365 381
             >
366
-              <p class="alert myError">
367
-                Missing fields. Please fill in all required fields. Marked with *
368
-              </p>
382
+              <p
383
+                class="alert myError"
384
+              >Missing fields. Please fill in all required fields. Marked with *</p>
369 385
             </div>
370 386
             <div v-if="wait" id="preloader"></div>
371 387
           </form>
@@ -401,7 +417,12 @@ export default {
401 417
       customToolbar: [
402 418
         [{ header: [false, 1, 2, 3, 4, 5, 6] }],
403 419
         ['bold', 'italic', 'underline', 'strike'],
404
-        [{ align: '' }, { align: 'center' }, { align: 'right' }, { align: 'justify' }],
420
+        [
421
+          { align: '' },
422
+          { align: 'center' },
423
+          { align: 'right' },
424
+          { align: 'justify' },
425
+        ],
405 426
         [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],
406 427
         [{ script: 'sub' }, { script: 'super' }],
407 428
         [{ indent: '-1' }, { indent: '+1' }],
@@ -411,6 +432,7 @@ export default {
411 432
       showProvinceError: false,
412 433
       showCityError: false,
413 434
       showSuburbError: false,
435
+      showDateError: false,
414 436
     };
415 437
   },
416 438
   methods: {
@@ -446,11 +468,19 @@ export default {
446 468
         this.showSuburbError = true;
447 469
       }
448 470
 
471
+      if (
472
+        this.salesType === 'Rental'
473
+        && this.property.dateAvailable === 'undef'
474
+      ) {
475
+        this.showDateError = true;
476
+      }
477
+
449 478
       if (
450 479
         this.showPropertyTypeError
451 480
         || this.showProvinceError
452 481
         || this.showCityError
453 482
         || this.showSuburbError
483
+        || this.showDateError
454 484
       ) {
455 485
         return;
456 486
       }
@@ -458,6 +488,7 @@ export default {
458 488
       this.wait = true;
459 489
       if (this.salesType === 'Sale') {
460 490
         this.property.isSale = true;
491
+        this.property.dateAvailable = new Date();
461 492
       }
462 493
       // eslint-disable-next-line no-plusplus
463 494
       for (let i = 0; i < this.images.length; i++) {
@@ -496,7 +527,9 @@ export default {
496 527
     },
497 528
     ProvinceSelected(item) {
498 529
       if (item.target.options.selectedIndex > 0) {
499
-        this.selectedProvince = this.provinces[item.target.options.selectedIndex - 1].description;
530
+        this.selectedProvince = this.provinces[
531
+          item.target.options.selectedIndex - 1
532
+        ].description;
500 533
         this.getCities(Object.assign({}, { province: this.selectedProvince }));
501 534
         this.showProvinceError = false;
502 535
       } else {
@@ -505,9 +538,14 @@ export default {
505 538
     },
506 539
     CitySelected(item) {
507 540
       if (item.target.options.selectedIndex > 0) {
508
-        this.selectedCity = this.cities[item.target.options.selectedIndex - 1].description;
541
+        this.selectedCity = this.cities[
542
+          item.target.options.selectedIndex - 1
543
+        ].description;
509 544
         this.getSuburbs(
510
-          Object.assign({}, { province: this.selectedProvince, city: this.selectedCity }),
545
+          Object.assign(
546
+            {},
547
+            { province: this.selectedProvince, city: this.selectedCity },
548
+          ),
511 549
         );
512 550
         this.showCityError = false;
513 551
       } else {
@@ -515,7 +553,9 @@ export default {
515 553
       }
516 554
     },
517 555
     getPostalCode(item) {
518
-      this.property.addressLine3 = this.suburbs[item.target.options.selectedIndex - 1].postalCode;
556
+      this.property.addressLine3 = this.suburbs[
557
+        item.target.options.selectedIndex - 1
558
+      ].postalCode;
519 559
       if (item.target.options.selectedIndex > 0) {
520 560
         this.showSuburbError = false;
521 561
       } else {

+ 41
- 18
src/components/property/propertyPage.vue 查看文件

@@ -6,9 +6,10 @@
6 6
       <div class="row">
7 7
         <div class="col-md-12 col-lg-8">
8 8
           <div class="title-box-d">
9
-            <h1 class="title-d" style="text-align:left; font-size: 250%">
10
-              {{ property.shortDescription }}
11
-            </h1>
9
+            <h1
10
+              class="title-d"
11
+              style="text-align:left; font-size: 250%"
12
+            >{{ property.shortDescription }}</h1>
12 13
           </div>
13 14
         </div>
14 15
       </div>
@@ -90,15 +91,22 @@
90 91
                   </div>
91 92
                   <div class="summary-list">
92 93
                     <ul class="list">
94
+                      <li v-if="!property.isSale" class="d-flex justify-content-between">
95
+                        <strong>Available:</strong>
96
+                        <span
97
+                          v-if="property.dateAvailable < date"
98
+                        >{{ property.dateAvailable | toDate }}</span>
99
+                        <span v-else>Now</span>
100
+                      </li>
93 101
                       <li class="d-flex justify-content-between">
94 102
                         <strong>Property ID:</strong>
95 103
                         <span>{{ property.id }}</span>
96 104
                       </li>
97 105
                       <li class="d-flex justify-content-between">
98 106
                         <strong>Status:</strong>
99
-                        <span v-if="property.status"
100
-                          >{{ property.status.code }} - {{ property.status.description }}</span
101
-                        >
107
+                        <span
108
+                          v-if="property.status"
109
+                        >{{ property.status.code }} - {{ property.status.description }}</span>
102 110
                       </li>
103 111
                       <li class="d-flex justify-content-between">
104 112
                         <strong>Address:</strong>
@@ -118,15 +126,13 @@
118 126
                     </ul>
119 127
                   </div>
120 128
                 </div>
121
-                <div class="col-md-12">
129
+                <div class="col-md-12" v-if="mayEdit">
122 130
                   <button
123 131
                     type="button"
124 132
                     class="btn btn-b-n"
125 133
                     data-toggle="modal"
126 134
                     data-target="#myModal"
127
-                  >
128
-                    Make an Offer
129
-                  </button>
135
+                  >Make an Offer</button>
130 136
                   <div id="myModal" class="modal fade" role="dialog">
131 137
                     <div class="modal-dialog modal-lg">
132 138
                       <!-- Modal content-->
@@ -151,6 +157,15 @@
151 157
                     </div>
152 158
                   </div>
153 159
                 </div>
160
+                <div
161
+                  class="col-md-12"
162
+                  v-if="!mayEdit"
163
+                  style="background-color: #ff8344; color: white;"
164
+                >
165
+                  <p>
166
+                    <b>Offer Pending</b>
167
+                  </p>
168
+                </div>
154 169
                 <div class="col-md-12">
155 170
                   <div class="row section-t3">
156 171
                     <div class="col-sm-12">
@@ -216,11 +231,11 @@
216 231
         </div>
217 232
         <!-- Tab Control -->
218 233
         <div class="row">
219
-          <div class="col-sm-12">
234
+          <div class="col-md-12">
220 235
             <div v-if="property.virtualTour" class="row justify-content-between">
221
-              <div class="col-md-7 col-lg-7 section-md-t3">
236
+              <div class="col-md-12 col-lg-12 section-md-t3">
222 237
                 <div class="row">
223
-                  <div class="col-sm-12">
238
+                  <div class="col-md-12">
224 239
                     <div class="title-box-d">
225 240
                       <h3 class="title-d" style="text-align:left">Virtual Tour</h3>
226 241
                     </div>
@@ -229,7 +244,7 @@
229 244
                 <iframe
230 245
                   :src="property.virtualTour"
231 246
                   width="100%"
232
-                  height="500"
247
+                  height="700"
233 248
                   frameborder="0"
234 249
                   webkitallowfullscreen
235 250
                   mozallowfullscreen
@@ -241,9 +256,9 @@
241 256
               <br />
242 257
             </div>
243 258
             <div v-if="property.video" class="row justify-content-between">
244
-              <div class="col-md-7 col-lg-7 section-md-t3">
259
+              <div class="col-md-12 col-lg-12 section-md-t3">
245 260
                 <div class="row">
246
-                  <div class="col-sm-12">
261
+                  <div class="col-md-12">
247 262
                     <div class="title-box-d">
248 263
                       <h3 class="title-d" style="text-align:left">Video</h3>
249 264
                     </div>
@@ -252,7 +267,7 @@
252 267
                 <iframe
253 268
                   :src="`https://www.youtube.com/embed/${property.video}`"
254 269
                   width="100%"
255
-                  height="500"
270
+                  height="700"
256 271
                   frameborder="0"
257 272
                   style="border:0"
258 273
                   allowfullscreen
@@ -281,17 +296,25 @@ export default {
281 296
   data() {
282 297
     return {
283 298
       index: null,
299
+      date: new Date(),
284 300
     };
285 301
   },
286 302
   mounted() {
287 303
     this.getProperty(this.$route.params.id);
288 304
     this.getPropertyImages(this.$route.params.id);
305
+    this.mayEditProperty(this.$route.params.id);
289 306
   },
290 307
   computed: {
291 308
     ...mapState('property', ['property', 'propertyImages']),
309
+    ...mapState('propertyEdit', ['mayEdit']),
292 310
   },
293 311
   methods: {
294
-    ...mapActions('property', ['getProperty', 'getPropertyImages', 'clearPropertyImages']),
312
+    ...mapActions('property', [
313
+      'getProperty',
314
+      'getPropertyImages',
315
+      'clearPropertyImages',
316
+    ]),
317
+    ...mapActions('propertyEdit', ['mayEditProperty']),
295 318
     formatPrice(value) {
296 319
       const val = (value / 1).toFixed(2);
297 320
       return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ');

+ 57
- 11
src/components/property/propertySearchFields.vue 查看文件

@@ -69,7 +69,7 @@
69 69
               <b>P</b>
70 70
             </span>
71 71
           </div>
72
-          <select class="form-control" v-model="propertySearch.province">
72
+          <select class="form-control" v-model="propertySearch.province" @change="ProvinceSelected">
73 73
             <option>All</option>
74 74
             <option v-for="(province, i) in provinces" :key="i">{{ province.description }}</option>
75 75
           </select>
@@ -80,8 +80,6 @@
80 80
           </div>
81 81
         </div>
82 82
       </div>
83
-    </div>
84
-    <div class="container text-left">
85 83
       <div class="form-group">
86 84
         <label for="city">City</label>
87 85
         <div class="input-group mb-3">
@@ -90,7 +88,7 @@
90 88
               <b>C</b>
91 89
             </span>
92 90
           </div>
93
-          <select class="form-control" v-model="propertySearch.city">
91
+          <select class="form-control" v-model="propertySearch.city" @change="CitySelected">
94 92
             <option>All</option>
95 93
             <option v-for="(city, i) in cities" :key="i">{{ city.description }}</option>
96 94
           </select>
@@ -101,8 +99,6 @@
101 99
           </div>
102 100
         </div>
103 101
       </div>
104
-    </div>
105
-    <div class="container text-left">
106 102
       <div class="form-group">
107 103
         <label for="suburb">Suburb</label>
108 104
         <div class="input-group mb-3">
@@ -122,8 +118,6 @@
122 118
           </div>
123 119
         </div>
124 120
       </div>
125
-    </div>
126
-    <div class="container text-left">
127 121
       <div class="form-group">
128 122
         <div class="row">
129 123
           <div class="col-md-6 text-left">
@@ -170,6 +164,47 @@
170 164
           </div>
171 165
         </div>
172 166
       </div>
167
+      <div class="form-group">
168
+        <div class="row">
169
+          <div class="col-md-12 text-left">
170
+            <label>Available From</label>
171
+            <div class="input-group mb-3">
172
+              <div class="input-group-prepend">
173
+                <span class="input-group-text" style="color: #60CBEB">
174
+                  <b>R</b>
175
+                </span>
176
+              </div>
177
+              <input
178
+                class="form-control"
179
+                type="date"
180
+                setp="any"
181
+                v-model="propertySearch.availableFrom"
182
+              />
183
+              <div class="input-group-append" @click="clearFilter('availableFrom')">
184
+                <span class="input-group-text cursor-pointer" style="color: #60CBEB">
185
+                  <b>X</b>
186
+                </span>
187
+              </div>
188
+            </div>
189
+          </div>
190
+        </div>
191
+      </div>
192
+      <div class="form-group">
193
+        <label for="propertytype">Property ID</label>
194
+        <div class="input-group mb-3">
195
+          <div class="input-group-prepend">
196
+            <span class="input-group-text" style="color: #60CBEB">
197
+              <b>T</b>
198
+            </span>
199
+          </div>
200
+          <input class="form-control" v-model="propertySearch.propertyId" type="number" />
201
+          <div class="input-group-append" @click="clearFilter('propertyId')">
202
+            <span class="input-group-text cursor-pointer" style="color: #60CBEB">
203
+              <b>X</b>
204
+            </span>
205
+          </div>
206
+        </div>
207
+      </div>
173 208
     </div>
174 209
   </div>
175 210
 </template>
@@ -191,9 +226,7 @@ export default {
191 226
     this.getProvince();
192 227
     this.getPropertyTypesRes();
193 228
     this.getPropertyTypesCom();
194
-    setTimeout(() => {
195
-      this.propertySearch.propertyUsageType = this.propertyType;
196
-    }, 100);
229
+    this.propertySearch.propertyUsageType = this.propertyType;
197 230
   },
198 231
   computed: {
199 232
     ...mapState('searchTab', ['provinces', 'cities', 'suburbs']),
@@ -214,6 +247,19 @@ export default {
214 247
     },
215 248
     PropertyTypeSelected(item) {
216 249
       this.propertySearch.propertyType = item.target.value;
250
+      let typeitem = this.propertyTypesCom.find(
251
+        t => t.description === item.target.value,
252
+      );
253
+      if (typeof typeitem === 'undefined') {
254
+        typeitem = this.propertyTypesRes.find(
255
+          t => t.description === item.target.value,
256
+        );
257
+      }
258
+      if (typeitem.usageType === 1) {
259
+        this.propertySearch.propertyUsageType = 'Commercial';
260
+      } else {
261
+        this.propertySearch.propertyUsageType = 'Residential';
262
+      }
217 263
     },
218 264
     ProvinceSelected(item) {
219 265
       if (item.target.value !== 'All') {

+ 6
- 17
src/components/property/propertySearchPage.vue 查看文件

@@ -27,14 +27,10 @@
27 27
       <br />
28 28
       <div class="row">
29 29
         <div class="col-md-2 offset-4">
30
-          <button type="button" @click="SetType('Residential')" class="btn btn-b-n">
31
-            Residential
32
-          </button>
30
+          <button type="button" @click="SetType('Residential')" class="btn btn-b-n">Residential</button>
33 31
         </div>
34 32
         <div class="col-md-2">
35
-          <button type="button" @click="SetType('Commercial')" class="btn btn-b-n">
36
-            Commercial
37
-          </button>
33
+          <button type="button" @click="SetType('Commercial')" class="btn btn-b-n">Commercial</button>
38 34
         </div>
39 35
       </div>
40 36
       <br />
@@ -50,8 +46,7 @@
50 46
               aria-controls="pills-video"
51 47
               aria-selected="true"
52 48
               v-on:click="SetSalesType('Sale')"
53
-              >For Sale</a
54
-            >
49
+            >For Sale</a>
55 50
           </li>
56 51
           <li class="nav-item">
57 52
             <a
@@ -63,8 +58,7 @@
63 58
               aria-controls="pills-plans"
64 59
               aria-selected="false"
65 60
               v-on:click="SetSalesType('Rent')"
66
-              >To Rent</a
67
-            >
61
+            >To Rent</a>
68 62
           </li>
69 63
         </ul>
70 64
       </div>
@@ -80,16 +74,12 @@
80 74
             class="input-group-text fa fa-search"
81 75
             style="color: #60CBEB"
82 76
             @click="SearchClick"
83
-          >
84
-            Search
85
-          </button>
77
+          >Search</button>
86 78
         </div>
87 79
       </div>
88 80
       <div class="row">
89 81
         <div class="col-md-12">
90
-          <h1 class="my-4" v-if="propertyUsageType === 'Residential'">
91
-            About Residential Properties
92
-          </h1>
82
+          <h1 class="my-4" v-if="propertyUsageType === 'Residential'">About Residential Properties</h1>
93 83
           <h1 class="my-4" v-else>About Commercial Properties</h1>
94 84
         </div>
95 85
         <div class="container col-md-6 text-left" v-if="propertyUsageType === 'Residential'">
@@ -185,7 +175,6 @@ export default {
185 175
     },
186 176
     SearchClick() {
187 177
       const item = this.suburbs.find(s => s.display === this.searchText);
188
-      console.log(JSON.stringify(item));
189 178
       this.propertySearch.province = item.province;
190 179
       this.propertySearch.city = item.city;
191 180
       this.propertySearch.suburb = item.suburb;

+ 43
- 8
src/components/property/propertySearchResults.vue 查看文件

@@ -26,7 +26,20 @@
26 26
       </div>
27 27
       <br />
28 28
       <div>
29
-        <propertyCard v-if="properties.length > 0" name="propertyholder" :properties="properties" />
29
+        <propertyCard
30
+          v-if="properties.length > 0"
31
+          name="propertyholder"
32
+          :properties="properties"
33
+          :salesType="propertySearch.salesType"
34
+        />
35
+        <!-- <div v-if="loading">
36
+          <img
37
+            class="img-fluid"
38
+            src="/img/kloader.gif"
39
+            alt="UVProp logo"
40
+            style="width:128px;height:128px;"
41
+          />
42
+        </div>-->
30 43
         <div v-if="properties.length === 0">
31 44
           <img src="../../../public/img/no-homes.png" />
32 45
           <br />
@@ -35,6 +48,11 @@
35 48
         </div>
36 49
       </div>
37 50
       <br />
51
+      <div class="row">
52
+        <div class="col-md-2 offset-5">
53
+          <button type="button" @click="SearchPage" class="btn btn-b-n">Back to Search</button>
54
+        </div>
55
+      </div>
38 56
     </div>
39 57
   </div>
40 58
 </template>
@@ -54,23 +72,40 @@ export default {
54 72
     if (typeof this.propertySearch.propertyUsageType === 'undefined') {
55 73
       this.propertySearch.propertyUsageType = 'Residential';
56 74
     }
75
+    if (this.user) {
76
+      this.propertySearch.userName = this.user.username;
77
+    }
57 78
     this.searchProperties(this.propertySearch);
58 79
   },
59 80
   methods: {
60
-    ...mapActions('propertySearch', ['searchProperties']),
81
+    ...mapActions('propertySearch', [
82
+      'searchProperties',
83
+      'clearProperties',
84
+      'updateResultsShowing',
85
+    ]),
61 86
     SetType(item) {
62 87
       this.propertySearch.propertyUsageType = item;
63 88
     },
89
+    SearchPage() {
90
+      this.clearProperties();
91
+      this.$router.push('/property/search');
92
+    },
64 93
   },
65 94
   computed: {
66
-    ...mapState('propertySearch', ['properties', 'propertySearch']),
67
-    ...mapState('authentication', ['username']),
95
+    ...mapState('propertySearch', [
96
+      'properties',
97
+      'propertySearch',
98
+      'resultsShowing',
99
+    ]),
100
+    ...mapState('authentication', ['user']),
68 101
     ParamsChanged() {
69
-      if (typeof this.propertySearch.propertyUsageType === 'undefined') {
70
-        // eslint-disable-next-line vue/no-side-effects-in-computed-properties
71
-        this.propertySearch.propertyUsageType = 'Residential';
102
+      if (this.resultsShowing) {
103
+        if (typeof this.propertySearch.propertyUsageType === 'undefined') {
104
+          // eslint-disable-next-line vue/no-side-effects-in-computed-properties
105
+          this.propertySearch.propertyUsageType = 'Residential';
106
+        }
107
+        this.searchProperties(this.propertySearch);
72 108
       }
73
-      this.searchProperties(this.propertySearch);
74 109
       return null;
75 110
     },
76 111
   },

+ 31
- 55
src/components/property/propertyeditPage.vue 查看文件

@@ -35,11 +35,11 @@
35 35
       <div class="row mb-3">
36 36
         <div class="container col-md-10" style="text-align:left">
37 37
           <form id="mainForm">
38
-            <div class="form-goup row">
38
+            <!-- <div class="form-goup row">
39 39
               <div class="col-md-4">
40 40
                 <field :type="'datetime'" :mayEdit="true" />
41 41
               </div>
42
-            </div>
42
+            </div>-->
43 43
             <div class="form-goup row">
44 44
               <div class="col-md-4">
45 45
                 <label>Usage Type</label>
@@ -104,14 +104,6 @@
104 104
               </div>
105 105
               <div class="col-md-6" style="margin-bottom: 1em">
106 106
                 <label>Province *</label>
107
-                <!-- <propField
108
-                  :display="property.province ? property.province.description : ''"
109
-                  :editType="'selector'"
110
-                  :arrayObject="provinces"
111
-                  :propertyName="'province'"
112
-                  :mayEdit="mayEdit"
113
-                  @UpdateValue="UpdateValue"
114
-                />-->
115 107
                 <field
116 108
                   :type="'select'"
117 109
                   :selectOptions="provinces"
@@ -127,14 +119,6 @@
127 119
               </div>
128 120
               <div class="col-md-6" style="margin-bottom: 1em">
129 121
                 <label>City *</label>
130
-                <!-- <propField
131
-                  :display="property.city ? property.city.description : ''"
132
-                  :editType="'selector'"
133
-                  :arrayObject="cities"
134
-                  :propertyName="'city'"
135
-                  :mayEdit="mayEdit"
136
-                  @UpdateValue="UpdateValue"
137
-                />-->
138 122
                 <field
139 123
                   :type="'select'"
140 124
                   :selectOptions="cities"
@@ -150,14 +134,6 @@
150 134
               </div>
151 135
               <div class="col-md-6" style="margin-bottom: 1em">
152 136
                 <label>Suburb *</label>
153
-                <!-- <propField
154
-                  :display="property.suburb ? property.suburb.description : ''"
155
-                  :editType="'selector'"
156
-                  :arrayObject="suburbs"
157
-                  :propertyName="'suburb'"
158
-                  :mayEdit="mayEdit"
159
-                  @UpdateValue="UpdateValue"
160
-                />-->
161 137
                 <field
162 138
                   :type="'select'"
163 139
                   :selectOptions="suburbs"
@@ -182,24 +158,9 @@
182 158
                 <label v-if="salesType === 'Rental'">Rental Price</label>
183 159
                 <label v-if="salesType !== 'Rental'">Sales Price</label>
184 160
                 <field :type="'number'" v-model="property.price" :mayEdit="mayEdit" />
185
-                <!-- <propField
186
-                  :display="String(property.price)"
187
-                  :editType="'number'"
188
-                  :propertyName="'price'"
189
-                  :mayEdit="mayEdit"
190
-                  @UpdateValue="UpdateValue"
191
-                />-->
192 161
               </div>
193 162
               <div class="col-md-6" v-if="salesType === 'Rental'">
194 163
                 <label>Per</label>
195
-                <!-- <propField
196
-                  :display="property.pricePer"
197
-                  :editType="'selector'"
198
-                  :propertyName="'pricePer'"
199
-                  :arrayObject="pricePerArr"
200
-                  :mayEdit="mayEdit"
201
-                  @UpdateValue="UpdateValue"
202
-                />-->
203 164
                 <field
204 165
                   :type="'selectlist'"
205 166
                   :selectOptions="pricePerArr"
@@ -208,6 +169,12 @@
208 169
                 />
209 170
               </div>
210 171
             </div>
172
+            <div class="form-group row" v-if="salesType === 'Rental'">
173
+              <div class="col-md-6">
174
+                <label>Available From</label>
175
+                <field :type="'date'" :mayEdit="mayEdit" v-model="property.dateAvailable" />
176
+              </div>
177
+            </div>
211 178
             <div class="form-group row">
212 179
               <div class="col-md-12">
213 180
                 <label for="Property Description">Description</label>
@@ -331,9 +298,7 @@
331 298
               class="btn btn-b-n"
332 299
               style="width: 85px; height:40px;"
333 300
               :disabled="!mayEdit"
334
-            >
335
-              Save
336
-            </button>
301
+            >Save</button>
337 302
             <button
338 303
               type="button"
339 304
               @click="Close()"
@@ -342,15 +307,13 @@
342 307
               :disabled="
343 308
                 showPropertyTypeError || showProvinceError || showCityError || showSuburbError
344 309
               "
345
-            >
346
-              Close
347
-            </button>
310
+            >Close</button>
348 311
             <div
349 312
               v-if="showPropertyTypeError || showProvinceError || showCityError || showSuburbError"
350 313
             >
351
-              <p class="alert myError">
352
-                Missing fields. Please fill in all required fields. Marked with *
353
-              </p>
314
+              <p
315
+                class="alert myError"
316
+              >Missing fields. Please fill in all required fields. Marked with *</p>
354 317
             </div>
355 318
             <div v-if="wait" id="preloader"></div>
356 319
           </form>
@@ -386,7 +349,12 @@ export default {
386 349
       customToolbar: [
387 350
         [{ header: [false, 1, 2, 3, 4, 5, 6] }],
388 351
         ['bold', 'italic', 'underline', 'strike'],
389
-        [{ align: '' }, { align: 'center' }, { align: 'right' }, { align: 'justify' }],
352
+        [
353
+          { align: '' },
354
+          { align: 'center' },
355
+          { align: 'right' },
356
+          { align: 'justify' },
357
+        ],
390 358
         [{ list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],
391 359
         [{ script: 'sub' }, { script: 'super' }],
392 360
         [{ indent: '-1' }, { indent: '+1' }],
@@ -411,7 +379,11 @@ export default {
411 379
       'getListsForPropertyEdit',
412 380
     ]),
413 381
     ...mapActions('property', ['getPropertyTypes']),
414
-    ...mapActions('propertyEdit', ['getSavedPropertyData', 'updateProperty', 'mayEditProperty']),
382
+    ...mapActions('propertyEdit', [
383
+      'getSavedPropertyData',
384
+      'updateProperty',
385
+      'mayEditProperty',
386
+    ]),
415 387
     provChanged(item) {
416 388
       this.getCities(Object.assign({}, { province: item.description }));
417 389
       this.property.city = null;
@@ -437,7 +409,9 @@ export default {
437 409
       this.showSuburbError = true;
438 410
     },
439 411
     suburbChanged(item) {
440
-      const newSuburb = this.suburbs.find(p => p.description === item.description);
412
+      const newSuburb = this.suburbs.find(
413
+        p => p.description === item.description,
414
+      );
441 415
       this.property.addressLine3 = newSuburb.postalCode;
442 416
       this.showSuburbError = false;
443 417
     },
@@ -447,9 +421,11 @@ export default {
447 421
     UpdateValue(item) {
448 422
       if (item.isUDF) {
449 423
         if (item.isPropOverview) {
450
-          this.propertyOverviewFields[0].fields[item.arrayIndex].value = item.value;
424
+          this.propertyOverviewFields[0].fields[item.arrayIndex].value =            item.value;
451 425
         } else if (item.isPropOverview === false) {
452
-          this.propertyFields[item.arrayIndex].fields[item.arrayItemIndex].value = item.value;
426
+          this.propertyFields[item.arrayIndex].fields[
427
+            item.arrayItemIndex
428
+          ].value = item.value;
453 429
         }
454 430
       } else if (!item.isUDF) {
455 431
         if (item.fieldName) {

+ 19
- 10
src/components/shared/checkItem.vue 查看文件

@@ -1,7 +1,7 @@
1 1
 <template>
2 2
   <div class="row p-2" @click="checkItem">
3
-    <div class="custom-control custom-checkbox">
4
-      <input type="checkbox" class="custom-control-input" :checked="checked" />
3
+    <div class="custom-control custom-checkbox mar-l-15">
4
+      <input type="checkbox" class="custom-control-input mar-l-15" :checked="Show" />
5 5
       <label class="custom-control-label">{{title}}</label>
6 6
     </div>
7 7
   </div>
@@ -9,17 +9,26 @@
9 9
 
10 10
 <script>
11 11
 export default {
12
-  props: ['title'],
13
-  data() {
14
-    return {
15
-      checked: true,
16
-    };
12
+  props: {
13
+    title: undefined,
14
+    show: {
15
+      default: false
16
+    }
17 17
   },
18 18
   methods: {
19 19
     checkItem() {
20
-      this.checked = !this.checked;
21
-      this.$emit('checkItem', this.title, this.checked);
22
-    },
20
+      this.$emit("checkItem", this.title, !this.show);
21
+    }
23 22
   },
23
+  computed: {
24
+    Show() {
25
+      return this.show;
26
+    }
27
+  }
24 28
 };
25 29
 </script>
30
+<style>
31
+.mar-l-15 {
32
+  margin-left: 15px;
33
+}
34
+</style>

+ 25
- 8
src/components/shared/fieldEditor.vue 查看文件

@@ -14,14 +14,14 @@
14 14
     <div v-if="edit" class="input-group-prepend">
15 15
       <input v-if="type === 'text'" class="form-control" v-model="value" />
16 16
       <input v-if="type === 'number'" type="number" class="form-control" v-model="value" />
17
+      <input v-if="type === 'date'" type="date" class="form-control" v-model="value" />
17 18
       <select v-if="type === 'select'" class="form-control" @change="selectionClick">
18 19
         <option>Please select</option>
19 20
         <option
20 21
           v-for="option in selectOptions"
21 22
           :value="option[selectValue]"
22 23
           :key="option[selectValue]"
23
-          >{{ option[selectText] }}</option
24
-        >
24
+        >{{ option[selectText] }}</option>
25 25
       </select>
26 26
       <select v-if="type === 'selectlist'" class="form-control" v-model="value">
27 27
         <option v-for="item in selectOptions" :value="item" :key="item">{{ item }}</option>
@@ -44,7 +44,15 @@
44 44
 
45 45
 <script>
46 46
 export default {
47
-  props: ['value', 'type', 'mayEdit', 'selectOptions', 'selectValue', 'selectText', 'display'],
47
+  props: [
48
+    'value',
49
+    'type',
50
+    'mayEdit',
51
+    'selectOptions',
52
+    'selectValue',
53
+    'selectText',
54
+    'display',
55
+  ],
48 56
   data() {
49 57
     return {
50 58
       edit: false,
@@ -68,13 +76,19 @@ export default {
68 76
     selectionClick(item) {
69 77
       if (item.target.options.selectedIndex > 0) {
70 78
         if (!this.value) {
71
-          this.myDisplay = this.selectOptions[item.target.options.selectedIndex - 1][
72
-            this.selectText
73
-          ];
79
+          this.myDisplay = this.selectOptions[
80
+            item.target.options.selectedIndex - 1
81
+          ][this.selectText];
74 82
         }
75 83
         if (this.selectOptions[item.target.options.selectedIndex - 1]) {
76
-          this.$emit('input', this.selectOptions[item.target.options.selectedIndex - 1]);
77
-          this.$emit('change', this.selectOptions[item.target.options.selectedIndex - 1]);
84
+          this.$emit(
85
+            'input',
86
+            this.selectOptions[item.target.options.selectedIndex - 1],
87
+          );
88
+          this.$emit(
89
+            'change',
90
+            this.selectOptions[item.target.options.selectedIndex - 1],
91
+          );
78 92
         }
79 93
       }
80 94
     },
@@ -91,6 +105,9 @@ export default {
91 105
     if (this.display) {
92 106
       this.myDisplay = this.display;
93 107
     }
108
+    if (this.type === 'date') {
109
+      this.myDisplay = this.$options.filters.toDate(this.value);
110
+    }
94 111
   },
95 112
   computed: {
96 113
     // eslint-disable-next-line vue/return-in-computed-property

+ 17
- 20
src/components/shared/gallerySlideShow.vue 查看文件

@@ -2,23 +2,15 @@
2 2
 <template>
3 3
   <transition name="modal">
4 4
     <div v-if="imgIndex !== null" class="vgs" @click="close">
5
-      <button type="button" class="vgs__close" @click="close">
6
-        &times;
7
-      </button>
8
-      <button v-if="isMultiple" type="button" class="vgs__prev" @click.stop="onPrev">
9
-        &lsaquo;
10
-      </button>
5
+      <button type="button" class="vgs__close" @click="close">&times;</button>
6
+      <button v-if="isMultiple" type="button" class="vgs__prev" @click.stop="onPrev">&lsaquo;</button>
11 7
       <div v-if="images" class="vgs__container" @click.stop="onNext">
12 8
         <img class="vgs__container__img" :src="imageUrl" :alt="alt" @click.stop="onNext" />
13 9
         <slot></slot>
14 10
       </div>
15
-      <button v-if="isMultiple" type="button" class="vgs__next" @click.stop="onNext">
16
-        &rsaquo;
17
-      </button>
11
+      <button v-if="isMultiple" type="button" class="vgs__next" @click.stop="onNext">&rsaquo;</button>
18 12
       <div v-if="isMultiple" ref="gallery" class="vgs__gallery">
19
-        <div v-if="images" class="vgs__gallery__title">
20
-          {{ imgIndex + 1 }} / {{ images.length }}
21
-        </div>
13
+        <div v-if="images" class="vgs__gallery__title">{{ imgIndex + 1 }} / {{ images.length }}</div>
22 14
         <div
23 15
           v-if="images"
24 16
           class="vgs__gallery__container"
@@ -138,7 +130,8 @@ export default {
138 130
       const galleryWidth = this.$refs.gallery.clientWidth;
139 131
       const currThumbsWidth = this.imgIndex * this.thumbnailWidth;
140 132
       const maxThumbsWidth = this.images.length * this.thumbnailWidth;
141
-      const centerPos = Math.floor(galleryWidth / (this.thumbnailWidth * 2)) * this.thumbnailWidth;
133
+      const centerPos =        Math.floor(galleryWidth / (this.thumbnailWidth * 2))
134
+        * this.thumbnailWidth;
142 135
 
143 136
       // Prevent scrolling of images if not needed
144 137
       if (maxThumbsWidth < galleryWidth) {
@@ -151,7 +144,11 @@ export default {
151 144
         currThumbsWidth
152 145
         > this.images.length * this.thumbnailWidth - galleryWidth + centerPos
153 146
       ) {
154
-        this.galleryXPos = -(this.images.length * this.thumbnailWidth - galleryWidth - 20);
147
+        this.galleryXPos = -(
148
+          this.images.length * this.thumbnailWidth
149
+          - galleryWidth
150
+          - 20
151
+        );
155 152
       } else {
156 153
         this.galleryXPos = -(this.imgIndex * this.thumbnailWidth) + centerPos;
157 154
       }
@@ -258,11 +255,11 @@ $screen-md-max: ($screen-lg - 1);
258 255
     overflow: hidden;
259 256
     cursor: pointer;
260 257
     overflow: hidden;
261
-    max-width: 100vh;
262
-    margin: 0.5rem auto 0;
258
+    max-width: 180vh;
259
+    margin: 2rem auto 0;
263 260
     left: 0.5rem;
264 261
     right: 0.5rem;
265
-    height: 60vh;
262
+    height: 85vh;
266 263
     border-radius: $radius-large;
267 264
     background-color: $black;
268 265
     @include respond-to(xs) {
@@ -304,13 +301,13 @@ $screen-md-max: ($screen-lg - 1);
304 301
   &__container {
305 302
     overflow: visible;
306 303
     display: block;
307
-    height: 250px;
304
+    height: 50px;
308 305
     white-space: nowrap;
309 306
     transition: all 200ms ease-in-out;
310 307
     width: 100%;
311 308
     &__img {
312
-      width: 250px;
313
-      height: 250px;
309
+      width: 50px;
310
+      height: 50px;
314 311
       object-fit: cover;
315 312
       display: inline-block;
316 313
       float: none;

+ 125
- 50
src/components/shared/listView.vue 查看文件

@@ -12,6 +12,29 @@
12 12
       </div>
13 13
       <div class="p-2">
14 14
         <div class="d-flex flex-row">
15
+          <div class="p2" v-if="showColumnChooser">
16
+            <div
17
+              class="btn btn-primary myBackground btn-width cursor-pointer"
18
+              data-toggle="modal"
19
+              data-target="#myModal"
20
+            >Column Chooser</div>
21
+            <div class="col-md-12">
22
+              <div id="myModal" class="modal fade" role="dialog">
23
+                <div class="modal-dialog modal-lg">
24
+                  <!-- Modal content-->
25
+                  <div class="modal-content">
26
+                    <div class="modal-header">
27
+                      <h5>Column Chooser</h5>
28
+                      <button type="button" class="close" data-dismiss="modal">&times;</button>
29
+                    </div>
30
+                    <div style="margin-left:50px; margin-right:50px;margin-bottom:50px;">
31
+                      <ListViewControl :items="allColumn" @checkItem="checkItem" />
32
+                    </div>
33
+                  </div>
34
+                </div>
35
+              </div>
36
+            </div>
37
+          </div>
15 38
           <div class="p2" v-if="selectedItems.length > 0">
16 39
             <div
17 40
               class="btn btn-primary myBackground btn-width cursor-pointer"
@@ -28,7 +51,7 @@
28 51
     <div v-if="items && items.length > 0" class="table-responsive">
29 52
       <table
30 53
         id="table"
31
-        :class="{'table table-hover': (1 === 1), 'table-sm': compact, 'table-bordered': bordered, 'table-striped': striped}"
54
+        :class="{'table table-hover': (1 === 1), 'table-sm': compact, 'table-bordered': bordered}"
32 55
       >
33 56
         <thead>
34 57
           <tr class="dnd-moved">
@@ -115,15 +138,17 @@
115 138
 </template>
116 139
 
117 140
 <script>
118
-import _ from 'lodash';
119
-import ItemsPerPageList from '../../assets/staticData/itemsPerPage';
120
-import BasePagination from './basePagination.vue';
121
-import Alert from './alert.vue';
141
+import _ from "lodash";
142
+import ItemsPerPageList from "../../assets/staticData/itemsPerPage";
143
+import BasePagination from "./basePagination.vue";
144
+import Alert from "./alert.vue";
145
+import ListViewControl from "./listViewControl.vue";
122 146
 
123 147
 export default {
124 148
   components: {
125 149
     BasePagination,
126 150
     Alert,
151
+    ListViewControl
127 152
   },
128 153
   mounted() {
129 154
     try {
@@ -135,87 +160,128 @@ export default {
135 160
     } catch (error) {
136 161
       throw error;
137 162
     }
163
+    this.getInitColumn();
138 164
   },
139 165
   props: {
140 166
     compact: {
141
-      default: true,
167
+      default: true
142 168
     },
143 169
     allowSelect: {
144
-      default: true,
170
+      default: true
145 171
     },
146 172
     allowMultipleSelect: {
147
-      default: false,
173
+      default: false
148 174
     },
149 175
     hideSearch: {
150
-      default: false,
176
+      default: false
151 177
     },
152 178
     showNew: {
153
-      default: true,
179
+      default: true
154 180
     },
155 181
     items: undefined,
156 182
     editable: {
157
-      default: false,
183
+      default: false
158 184
     },
159 185
     deleteable: {
160
-      default: false,
186
+      default: false
161 187
     },
162 188
     columnCount: {
163
-      default: 6,
189
+      default: 6
164 190
     },
165 191
     showPager: {
166
-      default: true,
192
+      default: true
167 193
     },
168 194
     title: {
169
-      default: undefined,
195
+      default: undefined
170 196
     },
171 197
     sortKey: {
172
-      default: 'id',
198
+      default: "id"
173 199
     },
174 200
     hideItemCount: {
175
-      default: false,
201
+      default: false
176 202
     },
177 203
 
178 204
     currentPage: {
179
-      default: 1,
205
+      default: 1
180 206
     },
181 207
     bordered: {
182
-      default: true,
208
+      default: true
183 209
     },
184 210
     striped: {
185
-      default: true,
211
+      default: true
186 212
     },
213
+    showColumnChooser: {
214
+      default: true
215
+    }
187 216
   },
188 217
   data() {
189 218
     return {
190 219
       hover: -1,
191 220
       selectedItems: [],
192 221
       showControl: false,
222
+      sortKey: "",
193 223
       reverse: false,
194
-      searchItem: '',
224
+      searchItem: "",
195 225
       visibleItemsPerPageCount: 20,
196 226
       itemsPerPageList: ItemsPerPageList,
227
+      visibleColumn: [],
228
+      allColumn: []
197 229
     };
198 230
   },
199 231
   methods: {
232
+    checkItem(column, show) {
233
+      const list = [];
234
+      for (var i in this.allColumn) {
235
+        let item = this.allColumn[i];
236
+        if (item && item.column === column) {
237
+          item.show = show;
238
+        }
239
+        list.push(item);
240
+      }
241
+      this.allColumn = list;
242
+    },
243
+    getInitColumn() {
244
+      const list = [];
245
+      const listAll = [];
246
+      if (this.items) {
247
+        for (const i in Object.keys(this.items)) {
248
+          const item = this.items[i];
249
+          for (const o in Object.keys(item)) {
250
+            if (
251
+              !listAll.includes(Object.keys(item)[o]) &&
252
+              !Array.isArray(Object.values(item)[o])
253
+            ) {
254
+              const columnName = Object.keys(item)[o];
255
+              if (!listAll.some(x => x.column === columnName))
256
+                listAll.push({
257
+                  column: columnName,
258
+                  show: _.filter(listAll, x => x.show).length < this.columnCount
259
+                });
260
+            }
261
+          }
262
+        }
263
+      }
264
+      this.allColumn = listAll;
265
+    },
200 266
     onClearSelected() {
201 267
       this.selectedItems = [];
202
-      this.$emit('onClearSelected');
268
+      this.$emit("onClearSelected");
203 269
     },
204 270
     isSelected(i) {
205 271
       const ind = this.getActualIndex(i);
206 272
       return _.some(this.selectedItems, x => x === ind);
207 273
     },
208 274
     onNew() {
209
-      this.$emit('onNew');
275
+      this.$emit("onNew");
210 276
     },
211 277
     isObject(item) {
212 278
       return !!item && item.constructor === Object;
213 279
     },
214 280
     onEdit(item) {
215
-      this.$emit('onEdit', item);
281
+      this.$emit("onEdit", item);
216 282
     },
217 283
     onDelete(item) {
218
-      this.$emit('onDelete', item);
284
+      this.$emit("onDelete", item);
219 285
     },
220 286
     onRowClick(item, i) {
221 287
       const ind = this.getActualIndex(i);
@@ -227,7 +293,7 @@ export default {
227 293
         }
228 294
         this.selectedItems.push(ind);
229 295
       }
230
-      this.$emit('onRowClick', this.selectedItems);
296
+      this.$emit("onRowClick", this.selectedItems);
231 297
     },
232 298
     getActualIndex(index) {
233 299
       return (this.currentPage - 1) * this.visibleItemsPerPageCount + index;
@@ -252,10 +318,10 @@ export default {
252 318
     async pageChangeHandle(value) {
253 319
       console.log(value);
254 320
       switch (value) {
255
-        case 'next':
321
+        case "next":
256 322
           this.currentPage += 1;
257 323
           break;
258
-        case 'previous':
324
+        case "previous":
259 325
           this.currentPage -= 1;
260 326
           break;
261 327
         default:
@@ -266,17 +332,17 @@ export default {
266 332
       if (this.currentPage !== 1) {
267 333
         this.currentPage = 1;
268 334
       }
269
-    },
335
+    }
270 336
   },
271 337
   computed: {
272 338
     ListWidth() {
273 339
       if (this.showControl) {
274
-        return 'col-md-9';
340
+        return "col-md-9";
275 341
       }
276
-      return 'col-md-12';
342
+      return "col-md-12";
277 343
     },
278 344
     SortDirection() {
279
-      return this.reverse ? 'desc' : 'asc';
345
+      return this.reverse ? "desc" : "asc";
280 346
     },
281 347
     PageCount() {
282 348
       return this.visibleItemsPerPageCount !== 0
@@ -284,30 +350,34 @@ export default {
284 350
         : 1;
285 351
     },
286 352
     Columns() {
353
+      const listColumns = [];
354
+      if (!this.allColumn || this.allColumn.length === 0) {
355
+        this.getInitColumn();
356
+      }
357
+      const list = _.filter(this.allColumn, x => x.show);
358
+      for (const i in list) {
359
+        const item = list[i];
360
+        if (item) {
361
+          listColumns.push(item.column);
362
+        }
363
+      }
364
+      return listColumns;
365
+    },
366
+    AllColumns() {
287 367
       const list = [];
288 368
       if (this.items) {
289
-        for (const i in Object.keys(this.items)) {
290
-          const item = this.items[i];
291
-          for (const o in Object.keys(item)) {
292
-            if (
293
-              !list.includes(Object.keys(item)[o])
294
-              && !Array.isArray(Object.values(item)[o])
295
-            ) {
296
-              if (list.length < this.columnCount) {
297
-                list.push(Object.keys(item)[o]);
298
-              }
299
-            }
300
-          }
301
-        }
302 369
       }
303 370
       return list;
304 371
     },
305 372
     FilteredItems() {
306
-      const list = _.filter(this.items, item => Object.values(item).some(
307
-          i => JSON.stringify(i)
373
+      const list = _.filter(this.items, item =>
374
+        Object.values(item).some(
375
+          i =>
376
+            JSON.stringify(i)
308 377
               .toLowerCase()
309
-              .indexOf(this.searchItem.toLowerCase()) > -1,
310
-        ),);
378
+              .indexOf(this.searchItem.toLowerCase()) > -1
379
+        )
380
+      );
311 381
       return _.orderBy(list, this.sortKey, this.SortDirection);
312 382
     },
313 383
     DisplayItems() {
@@ -319,7 +389,8 @@ export default {
319 389
       }
320 390
       return list.slice(startSlice, endSlice);
321 391
     },
322
-  },
392
+    GetAllColumn() {}
393
+  }
323 394
 };
324 395
 </script>
325 396
 <style scoped>
@@ -333,6 +404,10 @@ th[draggable] a {
333 404
   text-decoration: none;
334 405
   color: #333333;
335 406
 }
407
+.table-striped > tbody > tr:nth-child(2n + 1) > td,
408
+.table-striped > tbody > tr:nth-child(2n + 1) > th {
409
+  background-color: rgba(225, 225, 225, 0.8);
410
+}
336 411
 .active {
337 412
   background-color: rgba(255, 255, 255, 0.5);
338 413
   cursor: pointer;

+ 37
- 8
src/components/shared/listViewControl.vue 查看文件

@@ -1,24 +1,53 @@
1 1
 <template>
2
-  <div>
3
-    <div v-for="item in items" :key="item">
4
-      <CheckItem :title="item" @checkItem="changeColumn" />
2
+  <div class="container">
3
+    <div class="offset-3 col-md-6">
4
+      <input v-model="searchItem" class="form-control" placeholder="Search...." />
5
+    </div>
6
+    <hr />
7
+    <div class="row">
8
+      <div v-for="item in items" :key="item" class="col-md-4">
9
+        <div :class="{'inSearch': isInSelected(item)}">
10
+          <CheckItem :title="item.column" :show="item.show" @checkItem="checkItem" />
11
+        </div>
12
+      </div>
5 13
     </div>
6 14
   </div>
7 15
 </template>
8 16
 <script>
9
-import CheckItem from './checkItem.vue';
17
+import CheckItem from "./checkItem.vue";
10 18
 
11 19
 export default {
12 20
   components: {
13
-    CheckItem,
21
+    CheckItem
22
+  },
23
+  data() {
24
+    return {
25
+      searchItem: undefined
26
+    };
14 27
   },
15 28
   props: {
16
-    items: undefined,
29
+    items: undefined
17 30
   },
18 31
   methods: {
19
-    changeColumn(title, checked) {
20
-      this.$emit('changeColumn', title, checked);
32
+    isInSelected(i) {
33
+      if (this.searchItem && this.searchItem.length > 0) {
34
+        return (
35
+          i.column.toLowerCase().indexOf(this.searchItem.toLowerCase()) > -1
36
+        );
37
+      }
38
+      return false;
21 39
     },
40
+    checkItem(column, show) {
41
+      this.$emit("checkItem", column, show);
42
+    }
22 43
   },
44
+  computed: {}
23 45
 };
24 46
 </script>
47
+<style>
48
+.inSearch {
49
+  border: 1px solid rgba(50, 50, 50, 0.5);
50
+  border-radius: 10px;
51
+  background-color: rgba(225, 225, 225, 0.6);
52
+}
53
+</style>

+ 44
- 72
src/components/shared/searchTab.vue 查看文件

@@ -26,77 +26,41 @@
26 26
               </div>
27 27
             </div>
28 28
           </div>
29
-          <div class="col-md-12">
30
-            <ul class="nav nav-pills-a nav-pills mb-3 section-t3" id="pills-tab" role="tablist">
31
-              <li class="nav-item">
32
-                <a
33
-                  class="nav-link active"
34
-                  id="pills-video-tab"
35
-                  data-toggle="pill"
36
-                  href="#pills-video"
37
-                  role="tab"
38
-                  aria-controls="pills-video"
39
-                  aria-selected="true"
40
-                  v-on:click="updateType('Timeshare')"
41
-                  >Timeshare</a
42
-                >
43
-              </li>
44
-              <li class="nav-item">
45
-                <a
46
-                  class="nav-link"
47
-                  id="pills-plans-tab"
48
-                  data-toggle="pill"
49
-                  href="#pills-plans"
50
-                  role="tab"
51
-                  aria-controls="pills-plans"
52
-                  aria-selected="false"
53
-                  v-on:click="updateType('Residential')"
54
-                  >Residential</a
55
-                >
56
-              </li>
57
-              <li class="nav-item">
58
-                <a
59
-                  class="nav-link"
60
-                  id="pills-map-tab"
61
-                  data-toggle="pill"
62
-                  href="#pills-map"
63
-                  role="tab"
64
-                  aria-controls="pills-map"
65
-                  aria-selected="false"
66
-                  v-on:click="updateType('Commercial')"
67
-                  >Commercial</a
68
-                >
69
-              </li>
70
-            </ul>
71
-            <div class="tab-content" id="pills-tabContent">
72
-              <div
73
-                class="tab-pane fade show active"
74
-                id="pills-video"
75
-                role="tabpanel"
76
-                aria-labelledby="pills-video-tab"
77
-              >
78
-                <timeshareSearch :keyword="keyword" />
79
-              </div>
80
-              <div
81
-                class="tab-pane fade"
82
-                id="pills-plans"
83
-                role="tabpanel"
84
-                aria-labelledby="pills-plans-tab"
85
-              >
86
-                <propertySearch propertyType="Residential" />
87
-              </div>
88
-              <div
89
-                class="tab-pane fade"
90
-                id="pills-map"
91
-                role="tabpanel"
92
-                aria-labelledby="pills-map-tab"
93
-              >
94
-                <propertySearch propertyType="Commercial" />
95
-              </div>
96
-            </div>
29
+          <div class="col-md-2">
30
+            <button
31
+              type="button"
32
+              :class="[selectedPropertyType === 'Timeshare' ? 'tabButton isSelected' : 'tabButton isUnSelected']"
33
+              @click="setTypeTimeshare"
34
+            >
35
+              <b>Timeshare</b>
36
+            </button>
37
+          </div>
38
+          <div class="col-md-2">
39
+            <button
40
+              type="button"
41
+              :class="[selectedPropertyType === 'Residential' ? 'tabButton isSelected' : 'tabButton isUnSelected']"
42
+              @click="setTypeResidential"
43
+            >
44
+              <b>Residential</b>
45
+            </button>
46
+          </div>
47
+          <div class="col-md-2">
48
+            <button
49
+              type="button"
50
+              :class="[selectedPropertyType === 'Commercial' ? 'tabButton isSelected' : 'tabButton isUnSelected']"
51
+              @click="setTypeCommercial"
52
+            >
53
+              <b>Commercial</b>
54
+            </button>
55
+          </div>
56
+          <div class="col-md-12" v-if="selectedPropertyType === 'Timeshare'">
57
+            <timeshareSearch :keyword="keyword" />
58
+          </div>
59
+          <div class="col-md-12" v-else>
60
+            <propertySearch :propertyType="selectedPropertyType" />
97 61
           </div>
98 62
           <div class="col-md-12">
99
-            <button type="submit" class="btn btn-b-n" @click="Search">Search</button>
63
+            <button type="button" class="btn btn-b-n" @click="Search">Search</button>
100 64
           </div>
101 65
         </div>
102 66
       </form>
@@ -116,7 +80,7 @@ export default {
116 80
   },
117 81
   data() {
118 82
     return {
119
-      selectedPropertyType: 'timeshare',
83
+      selectedPropertyType: 'Timeshare',
120 84
       keyword: '',
121 85
     };
122 86
   },
@@ -129,13 +93,21 @@ export default {
129 93
       this.selectedPropertyType = item;
130 94
     },
131 95
     Search() {
132
-      if (this.selectedPropertyType === 'timeshare') {
96
+      if (this.selectedPropertyType === 'Timeshare') {
133 97
         this.$router.push('/timesharesearch');
134 98
       } else {
135
-        this.propertySearch.propertyUsageType = this.selectedPropertyType;
136 99
         this.$router.push('/property/propertySearch/results');
137 100
       }
138 101
     },
102
+    setTypeTimeshare() {
103
+      this.selectedPropertyType = 'Timeshare';
104
+    },
105
+    setTypeResidential() {
106
+      this.selectedPropertyType = 'Residential';
107
+    },
108
+    setTypeCommercial() {
109
+      this.selectedPropertyType = 'Commercial';
110
+    },
139 111
   },
140 112
 };
141 113
 </script>

+ 0
- 5
src/router/index.js 查看文件

@@ -134,11 +134,6 @@ export default new Router({
134 134
       name: 'PropertyPage',
135 135
       component: PropertyPage,
136 136
     },
137
-    {
138
-      path: '/property/:propertyUsageType/search',
139
-      name: 'PropertySearch',
140
-      component: PropertySearch,
141
-    },
142 137
     {
143 138
       path: '/property/search',
144 139
       name: 'PropertySearchTab',

+ 3
- 0
src/store/modules/property/property.js 查看文件

@@ -1,4 +1,5 @@
1 1
 import axios from 'axios';
2
+import { Date } from 'core-js';
2 3
 
3 4
 export default {
4 5
   namespaced: true,
@@ -27,6 +28,7 @@ export default {
27 28
       virtualTour: '',
28 29
       video: '',
29 30
       userId: 0,
31
+      dateAvailable: Date,
30 32
     },
31 33
     propertyImages: [],
32 34
     propertyTypes: [],
@@ -87,6 +89,7 @@ export default {
87 89
         virtualTour: '',
88 90
         video: '',
89 91
         userId: 0,
92
+        dateAvailable: Date,
90 93
       };
91 94
     },
92 95
     clearPropertyImages(state) {

+ 16
- 16
src/store/modules/property/propertySearch.js 查看文件

@@ -1,3 +1,4 @@
1
+/* eslint-disable valid-typeof */
1 2
 /* eslint-disable max-len */
2 3
 /* eslint-disable indent */
3 4
 import axios from 'axios';
@@ -16,12 +17,15 @@ export default {
16 17
       suburb: 'All',
17 18
       minPrice: 0,
18 19
       maxPrice: 0,
20
+      availableFrom: undefined,
21
+      propertyId: 0,
19 22
     },
20 23
     properties: [],
21 24
     latestProperties: [],
22 25
     suburbs: [],
23 26
     searchText: '',
24 27
     suburbList: [],
28
+    resultsShowing: false,
25 29
   },
26 30
   mutations: {
27 31
     updateSearch(state, propertySearch) {
@@ -35,7 +39,11 @@ export default {
35 39
       state.propertySearch = search;
36 40
     },
37 41
     onClearFilter(state, filter) {
38
-      state.propertySearch[filter] = 'All';
42
+      if (filter === 'availableFrom') {
43
+        state.propertySearch[filter] = undefined;
44
+      } else {
45
+        state.propertySearch[filter] = 'All';
46
+      }
39 47
     },
40 48
     setSuburbs(state, items) {
41 49
       state.suburbList = [];
@@ -48,6 +56,9 @@ export default {
48 56
     setFilter(state, value) {
49 57
       state.searchText = value;
50 58
     },
59
+    setResultsShowing(state, value) {
60
+      state.resultsShowing = value;
61
+    },
51 62
   },
52 63
   getters: {
53 64
     filterSuburbs: (state) => {
@@ -62,20 +73,6 @@ export default {
62 73
     clearFilter({ commit }, filter) {
63 74
       commit('onClearFilter', filter);
64 75
     },
65
-    getPropertySearchObject({ commit }) {
66
-      const search = {
67
-        userName: '',
68
-        salesType: 'Sale',
69
-        propertyUsageType: 'All',
70
-        propertyType: 'All',
71
-        province: 'All',
72
-        city: 'All',
73
-        suburb: 'All',
74
-        minPrice: 0,
75
-        maxPrice: 0,
76
-      };
77
-      commit('setPropertySearch', search);
78
-    },
79 76
     searchProperties({ commit }, item) {
80 77
       if (item.keyword === '') {
81 78
         item.keyword = 'All';
@@ -94,7 +91,7 @@ export default {
94 91
       }
95 92
       axios
96 93
         .get(
97
-          `/api/Property/Search/${item.userName}/${item.keyword}/${item.salesType}/${item.propertyUsageType}/${item.propertyType}/${item.province}/${item.city}/${item.suburb}/${item.minPrice}/${item.maxPrice}`,
94
+          `/api/Property/Search/${item.userName}/${item.keyword}/${item.salesType}/${item.propertyUsageType}/${item.propertyType}/${item.province}/${item.city}/${item.suburb}/${item.minPrice}/${item.maxPrice}/${item.availableFrom}/${item.propertyId}`,
98 95
         )
99 96
         .then(result => commit('updateSearch', result.data))
100 97
         .catch(console.error);
@@ -114,5 +111,8 @@ export default {
114 111
     applyFilter({ commit }, value) {
115 112
       commit('setFilter', { value });
116 113
     },
114
+    updateResultsShowing({ commit }, value) {
115
+      commit('setResultsShowing', value);
116
+    },
117 117
   },
118 118
 };

正在加载...
取消
保存