@@ -19,6 +19,9 @@ except according to the terms contained in the LICENSE file.
1919 <entity-filters v-model:conflict =" conflict" v-model:creatorId =" creatorIds" v-model:creationDate =" creationDateRange"
2020 :disabled =" deleted" :disabled-message =" deleted ? $t('filterDisabledMessage') : null" @reset-click =" resetFilters" />
2121 </form >
22+ <radio-field v-if =" dataset.dataExists && dataset.hasGeometry"
23+ v-model =" dataView" :options =" viewOptions" :disabled =" deleted"
24+ :disabled-message =" $t('mapDisabled')" button-appearance />
2225 <teleport-if-exists v-if =" odataEntities.dataExists" to =" .dataset-entities-heading-row" >
2326 <entity-download-button :odata-filter =" deleted ? null : odataFilter"
2427 :search-term =" deleted ? null : searchTerm"
@@ -27,30 +30,21 @@ except according to the terms contained in the LICENSE file.
2730 </teleport-if-exists >
2831 </div >
2932 <table-refresh-bar :odata =" odataEntities"
30- :refreshing =" refreshing" @refresh-click =" fetchChunk(false, true)" />
31- <entity-table v-show =" odataEntities.dataExists" ref =" table"
32- v-model:all-selected =" allSelected"
33- :properties =" dataset.properties" :deleted =" deleted"
34- :awaiting-deleted-responses =" awaitingResponses"
35- @selection-changed =" handleSelectionChange"
36- @update =" showUpdate"
37- @resolve =" showResolve" @delete =" showDelete" @restore =" showRestore" />
38-
39- <p v-show =" emptyTableMessage" class =" empty-table-message" >
40- {{ emptyTableMessage }}
33+ :refreshing =" refreshing" @refresh-click =" refresh" />
34+ <p v-show =" emptyMessage" class =" empty-table-message" >
35+ {{ emptyMessage }}
4136 </p >
42- <odata-loading-message :state =" odataEntities.initiallyLoading"
43- type =" entity"
44- :top =" pagination.size"
45- :filter =" odataFilter != null || !!searchTerm"
46- :total-count =" dataset.dataExists ? dataset.entities : 0" />
47-
48- <!-- @update:page is emitted on size change as well -->
49- <pagination v-if =" pagination.count > 0"
50- v-model:page =" pagination.page" v-model:size =" pagination.size"
51- :count =" pagination.count" :size-options =" pageSizeOptions"
52- :spinner =" odataEntities.awaitingResponse"
53- @update:page =" handlePageChange()" />
37+
38+ <entity-table-view v-if =" dataView === 'table'" ref =" view"
39+ v-model:all-selected =" allSelected" :deleted =" deleted"
40+ :filter =" odataFilter" :search-term =" searchTerm"
41+ :awaiting-responses =" awaitingResponses"
42+ @selection-changed =" handleSelectionChange"
43+ @clear-selection =" clearSelectedEntities"
44+ @update =" showUpdate" @resolve =" showResolve" @delete =" showDelete"
45+ @restore =" showRestore" />
46+ <entity-map-view v-else ref =" view" :filter =" geojsonFilter"
47+ :search-term =" searchTerm" :awaiting-responses =" awaitingResponses" />
5448 </disable-container >
5549
5650 <entity-update v-bind =" update" @hide =" hideUpdate" @success =" afterUpdate" />
@@ -75,28 +69,30 @@ except according to the terms contained in the LICENSE file.
7569</template >
7670
7771<script >
78- import { reactive , watch } from ' vue' ;
72+ import { watch } from ' vue' ;
7973
74+ import ActionBar from ' ../action-bar.vue' ;
75+ import DisableContainer from ' ../disable-container.vue' ;
8076import EntityDownloadButton from ' ./download-button.vue' ;
8177import EntityDelete from ' ./delete.vue' ;
78+ import EntityMapView from ' ./map-view.vue' ;
8279import EntityRestore from ' ./restore.vue' ;
8380import EntityFilters from ' ./filters.vue' ;
84- import EntityTable from ' ./table.vue' ;
81+ import EntityTableView from ' ./table-view .vue' ;
8582import EntityUpdate from ' ./update.vue' ;
8683import EntityResolve from ' ./resolve.vue' ;
87- import OdataLoadingMessage from ' ../odata-loading-message.vue' ;
88- import Spinner from ' ../spinner.vue' ;
89- import Pagination from ' ../pagination.vue' ;
84+ import RadioField from ' ../radio-field.vue' ;
85+ import TableRefreshBar from ' ../table-refresh-bar.vue' ;
9086import TeleportIfExists from ' ../teleport-if-exists.vue' ;
9187import SearchTextbox from ' ../search-textbox.vue' ;
92- import ActionBar from ' ../action-bar.vue' ;
93- import DisableContainer from ' ../disable-container.vue' ;
94- import TableRefreshBar from ' ../table-refresh-bar.vue' ;
88+ import Spinner from ' ../spinner.vue' ;
9589
90+ import useDataView from ' ../../composables/data-view' ;
9691import useQueryRef from ' ../../composables/query-ref' ;
9792import useDateRangeQueryRef from ' ../../composables/date-range-query-ref' ;
9893import useRequest from ' ../../composables/request' ;
9994import { apiPaths , requestAlertMessage } from ' ../../util/request' ;
95+ import { joinSentences } from ' ../../util/i18n' ;
10096import { modalData } from ' ../../util/reactivity' ;
10197import { noop } from ' ../../util/util' ;
10298import { odataEntityToRest } from ' ../../util/odata' ;
@@ -110,13 +106,13 @@ export default {
110106 DisableContainer,
111107 EntityDelete,
112108 EntityDownloadButton,
113- EntityRestore,
114109 EntityFilters,
110+ EntityMapView,
115111 EntityResolve,
116- EntityTable,
112+ EntityRestore,
113+ EntityTableView,
117114 EntityUpdate,
118- OdataLoadingMessage,
119- Pagination,
115+ RadioField,
120116 SearchTextbox,
121117 Spinner,
122118 TableRefreshBar,
@@ -182,15 +178,15 @@ export default {
182178 });
183179
184180 const creationDateRange = useDateRangeQueryRef ();
181+ const { dataView , options: viewOptions } = useDataView ();
185182
186183 const { request } = useRequest ();
187184
188- const pageSizeOptions = [250 , 500 , 1000 ];
189-
190185 return {
191- dataset, odataEntities, conflict, request,
192- deletedEntityCount, pageSizeOptions, searchTerm, entityCreators, creatorIds,
193- creationDateRange
186+ dataset, deletedEntityCount, odataEntities, entityCreators,
187+ searchTerm, creatorIds, creationDateRange, conflict,
188+ dataView, viewOptions,
189+ request
194190 };
195191 },
196192 data () {
@@ -213,8 +209,6 @@ export default {
213209
214210 awaitingResponses: new Set (),
215211
216- pagination: { page: 0 , size: this .pageSizeOptions [0 ], count: 0 },
217- now: new Date ().toISOString (),
218212 snapshotFilter: ' ' ,
219213 // used for restoring them back when undo button is pressed
220214 bulkDeletedEntities: [],
@@ -251,35 +245,55 @@ export default {
251245 }
252246 return conditions .length !== 0 ? conditions .join (' and ' ) : null ;
253247 },
254- emptyTableMessage () {
248+ geojsonFilter () {
249+ const query = {};
250+ if (this .filtersOnCreatorId ) query .creatorId = this .creatorIds ;
251+ if (this .creationDateRange .length !== 0 ) {
252+ query .start__gte = this .creationDateRange [0 ].toISO ();
253+ query .end__lte = this .creationDateRange [1 ].endOf (' day' ).toISO ();
254+ }
255+ if (this .conflict .length === 1 )
256+ query .conflict = this .conflict [0 ] ? [' soft' , ' hard' ] : ' null' ;
257+ return Object .keys (query).length !== 0 ? query : null ;
258+ },
259+ emptyMessage () {
255260 if (! this .odataEntities .dataExists ) return ' ' ;
256261 if (this .odataEntities .value .length > 0 ) return ' ' ;
257262
263+ // Cases related to entity deletion
258264 if (this .odataEntities .removedEntities .size === this .odataEntities .count && this .odataEntities .count > 0 ) {
259265 return this .deleted ? this .$t (' deletedEntity.allRestored' ) : this .$t (' allDeleted' );
260266 }
261267 if (this .odataEntities .removedEntities .size > 0 && this .odataEntities .value .length === 0 ) {
262268 return this .deleted ? this .$t (' deletedEntity.allRestoredOnPage' ) : this .$t (' allDeletedOnPage' );
263269 }
264- return this .deleted ? this .$t (' deletedEntity.emptyTable' )
265- : (this .odataFilter ? this .$t (' noMatching' ) : this .$t (' noEntities' ));
270+ if (this .deleted ) {
271+ return this .$t (' deletedEntity.emptyTable' );
272+ }
273+
274+ if (this .odataFilter ) return this .$t (' noMatching' );
275+ return this .dataView === ' table'
276+ ? this .$t (' noEntities' )
277+ : joinSentences (this .$i18n , [
278+ this .$t (' common.emptyMap' ),
279+ this .$t (' emptyMap' )
280+ ]);
266281 },
267282 actionBarState () {
268283 return this .selectedEntities .size > 0 && ! this .alert .state && ! this .container .openModal .state ;
269284 }
270285 },
271286 watch: {
272- deleted () {
273- this .fetchChunk (true );
274- },
275287 ' odataEntities.value' : {
276288 handler () {
277289 this .clearSelectedEntities ();
278290 }
279291 },
280292 ' odataEntities.count' : {
281293 handler () {
282- if (this .dataset .dataExists && this .odataEntities .dataExists && ! this .odataFilter && ! this .deleted && ! this .searchTerm )
294+ if (this .dataset .dataExists && this .odataEntities .dataExists &&
295+ this .dataView === ' table' && ! this .odataFilter && ! this .deleted &&
296+ ! this .searchTerm )
283297 this .dataset .entities = this .odataEntities .count ;
284298 }
285299 },
@@ -309,87 +323,24 @@ export default {
309323
310324 },
311325 created () {
312- this .fetchChunk (true );
313- this .$watch (() => [this .odataFilter , this .searchTerm ], () => this .fetchChunk (true ));
314326 this .fetchCreators ();
315327 },
316328 methods: {
317- // `clear` indicates whether this.odataEntities should be cleared before
318- // sending the request. `refresh` indicates whether the request is a
319- // background refresh (whether the refresh button was pressed).
320- fetchChunk (clear , refresh = false ) {
321- this .refreshing = refresh;
322- // Are we fetching the first chunk of entities or the next chunk?
323- const first = clear || refresh;
324-
325- if (first) {
326- this .now = new Date ().toISOString ();
327- this .setSnapshotFilter ();
328- this .pagination .page = 0 ;
329- }
330-
331- let $filter = this .snapshotFilter ;
332- if (this .odataFilter ) {
333- $filter += ` and ${ this .odataFilter } ` ;
334- }
335-
336- const $search = this .searchTerm ? this .searchTerm : undefined ;
337-
338- this .clearSelectedEntities ();
339-
340- this .odataEntities .request ({
341- url: apiPaths .odataEntities (
342- this .projectId ,
343- this .datasetName ,
344- {
345- $top: this .pagination .size ,
346- $skip: this .pagination .page * this .pagination .size ,
347- $count: true ,
348- $search,
349- $filter,
350- $orderby: ' __system/createdAt desc'
351- }
352- ),
353- clear,
354- patch: ! first
355- ? (response ) => this .odataEntities .replaceData (response .data , response .config )
356- : null
357- })
358- .then (() => {
359- this .pagination .count = this .odataEntities .count ;
360-
361- if (this .deleted ) {
362- this .deletedEntityCount .cancelRequest ();
363- if (! this .deletedEntityCount .dataExists ) {
364- this .deletedEntityCount .data = reactive ({});
365- }
366- this .deletedEntityCount .value = this .odataEntities .count ;
367- }
368- })
369- .finally (() => { this .refreshing = false ; })
370- .catch (noop);
371-
372- // emit event to parent component to re-fetch deleted Entity count
373- if (refresh && ! this .deleted ) {
374- this .$emit (' fetch-deleted-count' );
375- }
376- },
377- setSnapshotFilter () {
378- this .snapshotFilter = ' ' ;
379- if (this .deleted ) {
380- this .snapshotFilter += ` __system/deletedAt le ${ this .now } ` ;
381- } else {
382- this .snapshotFilter += ` __system/createdAt le ${ this .now } and ` ;
383- this .snapshotFilter += ` (__system/deletedAt eq null or __system/deletedAt gt ${ this .now } )` ;
384- }
385- },
386329 resetFilters () {
387330 this .$router .replace ({ path: this .$route .path , query: {} });
388331 },
332+ refresh () {
333+ this .refreshing = true ;
334+ this .$refs .view .fetchData (false )
335+ .then (() => { this .refreshing = false ; });
336+
337+ // emit event to parent component to re-fetch deleted Entity count
338+ if (! this .deleted ) this .$emit (' fetch-deleted-count' );
339+ },
389340 // This method is called directly by DatasetEntities.
390341 reset () {
391342 if (this .odataFilter == null && ! this .searchTerm ) {
392- this .fetchChunk ( true );
343+ this .$refs . view . fetchData ( );
393344 } else {
394345 this .resetFilters ();
395346 }
@@ -437,7 +388,7 @@ export default {
437388 this .odataEntities .value [index] = newOData;
438389
439390 if (this .resolveIndex == null )
440- this .$refs .table .afterUpdate (index);
391+ this .$refs .view .afterUpdate (index);
441392 else
442393 this .showResolve (this .resolveIndex );
443394 },
@@ -466,7 +417,7 @@ export default {
466417 };
467418 this .odataEntities .value [this .resolveIndex ] = newOData;
468419
469- this .$refs .table .afterUpdate (this .resolveIndex );
420+ this .$refs .view .afterUpdate (this .resolveIndex );
470421 },
471422 showDelete (entity ) {
472423 this .deleteModal .show ({ entity });
@@ -503,7 +454,7 @@ export default {
503454 ? this .odataEntities .value .findIndex (entity => entity .__id === uuid)
504455 : - 1 ;
505456 if (index !== - 1 ) {
506- this .$refs .table .afterDelete (index);
457+ this .$refs .view .afterDelete (index);
507458 this .selectedEntities .delete (this .odataEntities .value [index]);
508459 this .odataEntities .value .splice (index, 1 );
509460 }
@@ -547,7 +498,7 @@ export default {
547498 ? this .odataEntities .value .findIndex (entity => entity .__id === uuid)
548499 : - 1 ;
549500 if (index !== - 1 ) {
550- this .$refs .table .afterDelete (index);
501+ this .$refs .view .afterDelete (index);
551502 this .odataEntities .value .splice (index, 1 );
552503 }
553504 })
@@ -556,20 +507,14 @@ export default {
556507 this .awaitingResponses .delete (uuid);
557508 });
558509 },
559- handlePageChange () {
560- // This function is called for size change as well. So when the total number of entities are
561- // less than the lowest size option, hence we don't need to make a request.
562- if (this .odataEntities .count < this .pageSizeOptions [0 ]) return ;
563- this .fetchChunk (false );
564- },
565510 clearSelectedEntities () {
566511 this .selectedEntities .clear ();
567512 this .odataEntities .value ? .forEach (e => { e .__system .selected = false ; });
568513 this .allSelected = false ;
569514 },
570515 cancelBackgroundRefresh () {
571516 if (! this .refreshing ) return ;
572- this .odataEntities . cancelRequest ();
517+ this .$refs . view . cancelFetch ();
573518 this .deletedEntityCount .cancelRequest ();
574519 },
575520 requestBulkDelete () {
@@ -696,9 +641,7 @@ export default {
696641 flex- wrap: wrap- reverse;
697642}
698643
699- #entity- list table: has (tbody : empty ) {
700- display: none;
701- }
644+ #entity- list .radio - field { margin- left: auto; }
702645
703646#entity- table: has (tbody tr) + .empty - table- message {
704647 display: none;
@@ -717,6 +660,7 @@ export default {
717660 // This text is shown when there are no Entities to show in a table.
718661 " noEntities" : " There are no Entities to show." ,
719662 " noMatching" : " There are no matching Entities." ,
663+ " emptyMap" : " Entities only appear if they include data in the geometry property." ,
720664 " allDeleted" : " All Entities are deleted." ,
721665 " allDeletedOnPage" : " All Entities on the page have been deleted." ,
722666 " alert" : {
@@ -726,6 +670,7 @@ export default {
726670 },
727671 " filterDisabledMessage" : " Filtering is unavailable for deleted Entities" ,
728672 " searchDisabledMessage" : " Search is unavailable for deleted Entities" ,
673+ " mapDisabled" : " Map is unavailable for deleted Entities" ,
729674 " downloadDisabled" : " Download is unavailable for deleted Entities" ,
730675 " deletedEntity" : {
731676 " emptyTable" : " There are no deleted Entities." ,
0 commit comments