Последняя версия с сервера прошлого разработчика
This commit is contained in:
994
nova/resources/js/views/Lens.vue
Executable file
994
nova/resources/js/views/Lens.vue
Executable file
@@ -0,0 +1,994 @@
|
||||
<template>
|
||||
<loading-view :loading="initialLoading" :dusk="lens + '-lens-component'">
|
||||
<custom-lens-header class="mb-3" :resource-name="resourceName" />
|
||||
|
||||
<div v-if="shouldShowCards">
|
||||
<cards
|
||||
v-if="smallCards.length > 0"
|
||||
:cards="smallCards"
|
||||
class="mb-3"
|
||||
:resource-name="resourceName"
|
||||
:lens="lens"
|
||||
/>
|
||||
|
||||
<cards
|
||||
v-if="largeCards.length > 0"
|
||||
:cards="largeCards"
|
||||
size="large"
|
||||
:resource-name="resourceName"
|
||||
:lens="lens"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<heading v-if="resourceResponse" class="mb-3">
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'index',
|
||||
params: {
|
||||
resourceName: resourceName,
|
||||
},
|
||||
}"
|
||||
class="no-underline text-primary font-bold dim"
|
||||
data-testid="lens-back"
|
||||
>←</router-link
|
||||
>
|
||||
|
||||
<span class="px-2 text-70">/</span> {{ lenseName }}
|
||||
</heading>
|
||||
|
||||
<card>
|
||||
<div class="py-3 flex items-center border-b border-50">
|
||||
<div class="px-3" v-if="shouldShowCheckBoxes">
|
||||
<!-- Select All -->
|
||||
<dropdown
|
||||
dusk="select-all-dropdown"
|
||||
placement="bottom-end"
|
||||
class="-mx-2"
|
||||
>
|
||||
<dropdown-trigger class="px-2">
|
||||
<fake-checkbox :checked="selectAllChecked" />
|
||||
</dropdown-trigger>
|
||||
|
||||
<dropdown-menu slot="menu" direction="ltr" width="250">
|
||||
<div class="p-4">
|
||||
<ul class="list-reset">
|
||||
<li class="flex items-center mb-4">
|
||||
<checkbox-with-label
|
||||
:checked="selectAllChecked"
|
||||
@input="toggleSelectAll"
|
||||
>
|
||||
{{ __('Select All') }}
|
||||
</checkbox-with-label>
|
||||
</li>
|
||||
<li
|
||||
class="flex items-center"
|
||||
v-if="allMatchingResourceCount > 0"
|
||||
>
|
||||
<checkbox-with-label
|
||||
dusk="select-all-matching-button"
|
||||
:checked="selectAllMatchingChecked"
|
||||
@input="toggleSelectAllMatching"
|
||||
>
|
||||
<template>
|
||||
<span class="mr-1">
|
||||
{{ __('Select All Matching') }} ({{
|
||||
allMatchingResourceCount
|
||||
}})
|
||||
</span>
|
||||
</template>
|
||||
</checkbox-with-label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</dropdown-menu>
|
||||
</dropdown>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center ml-auto px-3">
|
||||
<!-- Action Selector -->
|
||||
<action-selector
|
||||
v-if="selectedResources.length > 0 || haveStandaloneActions"
|
||||
:resource-name="resourceName"
|
||||
:actions="availableActions"
|
||||
:pivot-actions="pivotActions"
|
||||
:pivot-name="pivotName"
|
||||
:selected-resources="selectedResourcesForActionSelector"
|
||||
:endpoint="lensActionEndpoint"
|
||||
:query-string="{
|
||||
currentSearch,
|
||||
encodedFilters,
|
||||
currentTrashed,
|
||||
viaResource,
|
||||
viaResourceId,
|
||||
viaRelationship,
|
||||
}"
|
||||
@actionExecuted="getResources"
|
||||
/>
|
||||
|
||||
<filter-menu
|
||||
:resourceName="resourceName"
|
||||
:soft-deletes="softDeletes"
|
||||
:via-resource="viaResource"
|
||||
:via-has-one="viaHasOne"
|
||||
:trashed="trashed"
|
||||
:per-page="perPage"
|
||||
:per-page-options="
|
||||
perPageOptions || resourceInformation.perPageOptions
|
||||
"
|
||||
:show-trashed-option="
|
||||
authorizedToForceDeleteAnyResources ||
|
||||
authorizedToRestoreAnyResources
|
||||
"
|
||||
:lens="lens"
|
||||
@clear-selected-filters="clearSelectedFilters(lens)"
|
||||
@filter-changed="filterChanged"
|
||||
@trashed-changed="trashedChanged"
|
||||
@per-page-changed="updatePerPageChanged"
|
||||
/>
|
||||
|
||||
<delete-menu
|
||||
v-if="shouldShowDeleteMenu"
|
||||
dusk="delete-menu"
|
||||
:soft-deletes="softDeletes"
|
||||
:resources="resources"
|
||||
:selected-resources="selectedResources"
|
||||
:via-many-to-many="viaManyToMany"
|
||||
:all-matching-resource-count="allMatchingResourceCount"
|
||||
:all-matching-selected="selectAllMatchingChecked"
|
||||
:authorized-to-delete-selected-resources="
|
||||
authorizedToDeleteSelectedResources
|
||||
"
|
||||
:authorized-to-force-delete-selected-resources="
|
||||
authorizedToForceDeleteSelectedResources
|
||||
"
|
||||
:authorized-to-delete-any-resources="authorizedToDeleteAnyResources"
|
||||
:authorized-to-force-delete-any-resources="
|
||||
authorizedToForceDeleteAnyResources
|
||||
"
|
||||
:authorized-to-restore-selected-resources="
|
||||
authorizedToRestoreSelectedResources
|
||||
"
|
||||
:authorized-to-restore-any-resources="
|
||||
authorizedToRestoreAnyResources
|
||||
"
|
||||
@deleteSelected="deleteSelectedResources"
|
||||
@deleteAllMatching="deleteAllMatchingResources"
|
||||
@forceDeleteSelected="forceDeleteSelectedResources"
|
||||
@forceDeleteAllMatching="forceDeleteAllMatchingResources"
|
||||
@restoreSelected="restoreSelectedResources"
|
||||
@restoreAllMatching="restoreAllMatchingResources"
|
||||
@close="deleteModalOpen = false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<loading-view :loading="loading">
|
||||
<div
|
||||
v-if="!resources.length"
|
||||
class="flex justify-center items-center px-6 py-8"
|
||||
>
|
||||
<div class="text-center">
|
||||
<svg
|
||||
class="mb-3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="65"
|
||||
height="51"
|
||||
viewBox="0 0 65 51"
|
||||
>
|
||||
<path
|
||||
fill="#A8B9C5"
|
||||
d="M56 40h2c.552285 0 1 .447715 1 1s-.447715 1-1 1h-2v2c0 .552285-.447715 1-1 1s-1-.447715-1-1v-2h-2c-.552285 0-1-.447715-1-1s.447715-1 1-1h2v-2c0-.552285.447715-1 1-1s1 .447715 1 1v2zm-5.364125-8H38v8h7.049375c.350333-3.528515 2.534789-6.517471 5.5865-8zm-5.5865 10H6c-3.313708 0-6-2.686292-6-6V6c0-3.313708 2.686292-6 6-6h44c3.313708 0 6 2.686292 6 6v25.049375C61.053323 31.5511 65 35.814652 65 41c0 5.522847-4.477153 10-10 10-5.185348 0-9.4489-3.946677-9.950625-9zM20 30h16v-8H20v8zm0 2v8h16v-8H20zm34-2v-8H38v8h16zM2 30h16v-8H2v8zm0 2v4c0 2.209139 1.790861 4 4 4h12v-8H2zm18-12h16v-8H20v8zm34 0v-8H38v8h16zM2 20h16v-8H2v8zm52-10V6c0-2.209139-1.790861-4-4-4H6C3.790861 2 2 3.790861 2 6v4h52zm1 39c4.418278 0 8-3.581722 8-8s-3.581722-8-8-8-8 3.581722-8 8 3.581722 8 8 8z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<h3 class="text-base text-80 font-normal mb-6">
|
||||
{{
|
||||
__('No :resource matched the given criteria.', {
|
||||
resource: resourceInformation.label.toLowerCase(),
|
||||
})
|
||||
}}
|
||||
</h3>
|
||||
|
||||
<create-resource-button
|
||||
classes="btn btn-sm btn-outline"
|
||||
:singular-name="singularName"
|
||||
:resource-name="resourceName"
|
||||
:via-resource="viaResource"
|
||||
:via-resource-id="viaResourceId"
|
||||
:via-relationship="viaRelationship"
|
||||
:relationship-type="relationshipType"
|
||||
:authorized-to-create="authorizedToCreate && !resourceIsFull"
|
||||
:authorized-to-relate="authorizedToRelate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Resource Table -->
|
||||
<div class="overflow-hidden overflow-x-auto relative">
|
||||
<resource-table
|
||||
:authorized-to-relate="authorizedToRelate"
|
||||
:resource-name="resourceName"
|
||||
:resources="resources"
|
||||
:singular-name="singularName"
|
||||
:selected-resources="selectedResources"
|
||||
:selected-resource-ids="selectedResourceIds"
|
||||
:actions-are-available="allActions.length > 0"
|
||||
:actions-endpoint="lensActionEndpoint"
|
||||
:should-show-checkboxes="shouldShowCheckBoxes"
|
||||
:via-resource="viaResource"
|
||||
:via-resource-id="viaResourceId"
|
||||
:via-relationship="viaRelationship"
|
||||
:relationship-type="relationshipType"
|
||||
:update-selection-status="updateSelectionStatus"
|
||||
@order="orderByField"
|
||||
@reset-order-by="resetOrderBy"
|
||||
@delete="deleteResources"
|
||||
@restore="restoreResources"
|
||||
@actionExecuted="getResources"
|
||||
ref="resourceTable"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<component
|
||||
:is="paginationComponent"
|
||||
v-if="resourceResponse && resources.length > 0"
|
||||
:next="hasNextPage"
|
||||
:previous="hasPreviousPage"
|
||||
@load-more="loadMore"
|
||||
@page="selectPage"
|
||||
:pages="totalPages"
|
||||
:page="currentPage"
|
||||
:per-page="perPage"
|
||||
:resource-count-label="resourceCountLabel"
|
||||
:current-resource-count="resources.length"
|
||||
:all-matching-resource-count="allMatchingResourceCount"
|
||||
>
|
||||
<span
|
||||
v-if="resourceCountLabel"
|
||||
class="text-sm text-80 px-4"
|
||||
:class="{
|
||||
'ml-auto': paginationComponent == 'pagination-links',
|
||||
}"
|
||||
>
|
||||
{{ resourceCountLabel }}
|
||||
</span>
|
||||
</component>
|
||||
</loading-view>
|
||||
</card>
|
||||
</loading-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
HasCards,
|
||||
Deletable,
|
||||
Errors,
|
||||
Filterable,
|
||||
Minimum,
|
||||
Paginatable,
|
||||
PerPageable,
|
||||
InteractsWithQueryString,
|
||||
InteractsWithResourceInformation,
|
||||
} from 'laravel-nova'
|
||||
import HasActions from '@/mixins/HasActions'
|
||||
import { CancelToken, Cancel } from 'axios'
|
||||
|
||||
export default {
|
||||
mixins: [
|
||||
HasActions,
|
||||
HasCards,
|
||||
Deletable,
|
||||
Filterable,
|
||||
Paginatable,
|
||||
PerPageable,
|
||||
InteractsWithResourceInformation,
|
||||
InteractsWithQueryString,
|
||||
],
|
||||
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.lenseName,
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
resourceName: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
|
||||
viaResource: {
|
||||
default: '',
|
||||
},
|
||||
|
||||
viaResourceId: {
|
||||
default: '',
|
||||
},
|
||||
|
||||
viaRelationship: {
|
||||
default: '',
|
||||
},
|
||||
|
||||
relationshipType: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
|
||||
lens: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
canceller: null,
|
||||
initialLoading: true,
|
||||
loading: true,
|
||||
|
||||
resourceResponse: null,
|
||||
resources: [],
|
||||
softDeletes: false,
|
||||
selectedResources: [],
|
||||
selectAllMatchingResources: false,
|
||||
allMatchingResourceCount: 0,
|
||||
hasId: false,
|
||||
|
||||
deleteModalOpen: false,
|
||||
|
||||
actionValidationErrors: new Errors(),
|
||||
|
||||
authorizedToRelate: false,
|
||||
|
||||
orderBy: '',
|
||||
orderByDirection: '',
|
||||
trashed: '',
|
||||
|
||||
// Load More Pagination
|
||||
currentPageLoadMore: null,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Mount the component and retrieve its initial data.
|
||||
*/
|
||||
async created() {
|
||||
if (Nova.missingResource(this.resourceName))
|
||||
return this.$router.push({ name: '404' })
|
||||
|
||||
this.initializeSearchFromQueryString()
|
||||
this.initializePerPageFromQueryString()
|
||||
this.initializeTrashedFromQueryString()
|
||||
this.initializeOrderingFromQueryString()
|
||||
|
||||
await this.initializeFilters(this.lens)
|
||||
this.getResources()
|
||||
// this.getAuthorizationToRelate()
|
||||
this.getActions()
|
||||
|
||||
this.initialLoading = false
|
||||
|
||||
this.$watch(
|
||||
() => {
|
||||
return (
|
||||
this.lens +
|
||||
this.resourceName +
|
||||
this.encodedFilters +
|
||||
this.currentSearch +
|
||||
this.currentPage +
|
||||
this.currentPerPage +
|
||||
this.currentOrderBy +
|
||||
this.currentOrderByDirection +
|
||||
this.currentTrashed
|
||||
)
|
||||
},
|
||||
() => {
|
||||
if (this.canceller !== null) this.canceller()
|
||||
|
||||
this.getResources()
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route(to, from) {
|
||||
if (
|
||||
to.params.resourceName === from.params.resourceName &&
|
||||
to.params.lens === from.params.lens
|
||||
) {
|
||||
this.initializeState(this.lens)
|
||||
} else {
|
||||
this.initializeFilters(this.lens)
|
||||
this.getActions()
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
selectAllResources() {
|
||||
this.selectedResources = this.resources.slice(0)
|
||||
},
|
||||
|
||||
toggleSelectAll() {
|
||||
if (this.selectAllChecked) return this.clearResourceSelections()
|
||||
this.selectAllResources()
|
||||
},
|
||||
|
||||
toggleSelectAllMatching() {
|
||||
if (!this.selectAllMatchingResources) {
|
||||
this.selectAllResources()
|
||||
this.selectAllMatchingResources = true
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.selectAllMatchingResources = false
|
||||
},
|
||||
|
||||
/*
|
||||
* Update the resource selection status
|
||||
*/
|
||||
updateSelectionStatus(resource) {
|
||||
if (!_(this.selectedResources).includes(resource))
|
||||
return this.selectedResources.push(resource)
|
||||
const index = this.selectedResources.indexOf(resource)
|
||||
if (index > -1) return this.selectedResources.splice(index, 1)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the resources based on the current page, search, filters, etc.
|
||||
*/
|
||||
getResources() {
|
||||
this.loading = true
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.clearResourceSelections()
|
||||
|
||||
return Minimum(
|
||||
Nova.request().get(
|
||||
'/nova-api/' + this.resourceName + '/lens/' + this.lens,
|
||||
{
|
||||
params: this.resourceRequestQueryString,
|
||||
cancelToken: new CancelToken(canceller => {
|
||||
this.canceller = canceller
|
||||
}),
|
||||
}
|
||||
),
|
||||
300
|
||||
)
|
||||
.then(({ data }) => {
|
||||
this.resources = []
|
||||
|
||||
this.resourceResponse = data
|
||||
this.resources = data.resources
|
||||
this.softDeletes = data.softDeletes
|
||||
this.perPage = data.per_page
|
||||
this.hasId = data.hasId
|
||||
|
||||
this.loading = false
|
||||
|
||||
this.getAllMatchingResourceCount()
|
||||
|
||||
Nova.$emit('resources-loaded')
|
||||
})
|
||||
.catch(e => {
|
||||
if (e instanceof Cancel) {
|
||||
return
|
||||
}
|
||||
|
||||
throw e
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the actions available for the current resource.
|
||||
*/
|
||||
getActions() {
|
||||
this.actions = []
|
||||
this.pivotActions = null
|
||||
Nova.request()
|
||||
.get(`/nova-api/${this.resourceName}/lens/${this.lens}/actions`, {
|
||||
params: {
|
||||
viaResource: this.viaResource,
|
||||
viaResourceId: this.viaResourceId,
|
||||
viaRelationship: this.viaRelationship,
|
||||
relationshipType: this.relationshipType,
|
||||
display: 'index',
|
||||
},
|
||||
})
|
||||
.then(response => {
|
||||
this.actions = response.data.actions
|
||||
this.pivotActions = response.data.pivotActions
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear the selected resouces and the "select all" states.
|
||||
*/
|
||||
clearResourceSelections() {
|
||||
this.selectAllMatchingResources = false
|
||||
this.selectedResources = []
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the count of all of the matching resources.
|
||||
*/
|
||||
getAllMatchingResourceCount() {
|
||||
Nova.request()
|
||||
.get(
|
||||
'/nova-api/' + this.resourceName + '/lens/' + this.lens + '/count',
|
||||
{
|
||||
params: this.resourceRequestQueryString,
|
||||
}
|
||||
)
|
||||
.then(response => {
|
||||
this.allMatchingResourceCount = response.data.count
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort the resources by the given field.
|
||||
*/
|
||||
orderByField(field) {
|
||||
let direction = this.currentOrderByDirection == 'asc' ? 'desc' : 'asc'
|
||||
|
||||
if (this.currentOrderBy != field.sortableUriKey) {
|
||||
direction = 'asc'
|
||||
}
|
||||
|
||||
this.updateQueryString({
|
||||
[this.orderByParameter]: field.sortableUriKey,
|
||||
[this.orderByDirectionParameter]: direction,
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset the order by to its default state
|
||||
*/
|
||||
resetOrderBy(field) {
|
||||
this.updateQueryString({
|
||||
[this.orderByParameter]: field.sortableUriKey,
|
||||
[this.orderByDirectionParameter]: null,
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Sync the current search value from the query string.
|
||||
*/
|
||||
initializeSearchFromQueryString() {
|
||||
this.search = this.currentSearch
|
||||
},
|
||||
|
||||
/**
|
||||
* Sync the current order by values from the query string.
|
||||
*/
|
||||
initializeOrderingFromQueryString() {
|
||||
this.orderBy = this.currentOrderBy
|
||||
this.orderByDirection = this.currentOrderByDirection
|
||||
},
|
||||
|
||||
/**
|
||||
* Sync the trashed state values from the query string.
|
||||
*/
|
||||
initializeTrashedFromQueryString() {
|
||||
this.trashed = this.currentTrashed
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the trashed constraint for the resource listing.
|
||||
*/
|
||||
trashedChanged(trashedStatus) {
|
||||
this.trashed = trashedStatus
|
||||
this.updateQueryString({ [this.trashedParameter]: this.trashed })
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the per page parameter in the query string
|
||||
*/
|
||||
updatePerPageChanged(perPage) {
|
||||
this.perPage = perPage
|
||||
this.perPageChanged()
|
||||
},
|
||||
|
||||
/**
|
||||
* Load more resources.
|
||||
*/
|
||||
loadMore() {
|
||||
if (this.currentPageLoadMore === null) {
|
||||
this.currentPageLoadMore = this.currentPage
|
||||
}
|
||||
|
||||
this.currentPageLoadMore = this.currentPageLoadMore + 1
|
||||
|
||||
return Minimum(
|
||||
Nova.request().get(
|
||||
'/nova-api/' + this.resourceName + '/lens/' + this.lens,
|
||||
{
|
||||
params: {
|
||||
...this.resourceRequestQueryString,
|
||||
page: this.currentPageLoadMore, // We do this to override whatever page number is in the URL
|
||||
},
|
||||
}
|
||||
),
|
||||
300
|
||||
).then(({ data }) => {
|
||||
this.resourceResponse = data
|
||||
this.resources = [...this.resources, ...data.resources]
|
||||
|
||||
this.getAllMatchingResourceCount()
|
||||
|
||||
Nova.$emit('resources-loaded')
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* Select the next page.
|
||||
*/
|
||||
selectPage(page) {
|
||||
this.updateQueryString({ [this.pageParameter]: page })
|
||||
},
|
||||
|
||||
/**
|
||||
* Sync the per page values from the query string.
|
||||
*/
|
||||
initializePerPageFromQueryString() {
|
||||
this.perPage =
|
||||
this.$route.query[this.perPageParameter] ||
|
||||
this.resourceInformation.perPageOptions[0]
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
/**
|
||||
* Get the endpoint for this resource's actions.
|
||||
*/
|
||||
lensActionEndpoint() {
|
||||
return `/nova-api/${this.resourceName}/lens/${this.lens}/action`
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the name of the search query string variable.
|
||||
*/
|
||||
searchParameter() {
|
||||
return this.resourceName + '_search'
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the name of the order by query string variable.
|
||||
*/
|
||||
orderByParameter() {
|
||||
return this.resourceName + '_order'
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the name of the order by direction query string variable.
|
||||
*/
|
||||
orderByDirectionParameter() {
|
||||
return this.resourceName + '_direction'
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the name of the trashed constraint query string variable.
|
||||
*/
|
||||
trashedParameter() {
|
||||
return this.resourceName + '_trashed'
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the name of the per page query string variable.
|
||||
*/
|
||||
perPageParameter() {
|
||||
return this.resourceName + '_per_page'
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the name of the page query string variable.
|
||||
*/
|
||||
pageParameter() {
|
||||
return this.resourceName + '_page'
|
||||
},
|
||||
|
||||
/**
|
||||
* Build the resource request query string.
|
||||
*/
|
||||
resourceRequestQueryString() {
|
||||
return {
|
||||
search: this.currentSearch,
|
||||
filters: this.encodedFilters,
|
||||
orderBy: this.currentOrderBy,
|
||||
orderByDirection: this.currentOrderByDirection,
|
||||
perPage: this.currentPerPage,
|
||||
page: this.currentPage,
|
||||
viaResource: this.viaResource,
|
||||
viaResourceId: this.viaResourceId,
|
||||
// viaRelationship: this.viaRelationship,
|
||||
viaResourceRelationship: this.viaResourceRelationship,
|
||||
relationshipType: this.relationshipType,
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if all resources are selected.
|
||||
*/
|
||||
selectAllChecked() {
|
||||
return this.selectedResources.length == this.resources.length
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if all matching resources are selected.
|
||||
*/
|
||||
selectAllMatchingChecked() {
|
||||
return (
|
||||
this.selectedResources.length == this.resources.length &&
|
||||
this.selectAllMatchingResources
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the IDs for the selected resources.
|
||||
*/
|
||||
selectedResourceIds() {
|
||||
return _.map(this.selectedResources, resource => resource.id.value)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current search value from the query string.
|
||||
*/
|
||||
currentSearch() {
|
||||
return this.$route.query[this.searchParameter] || ''
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current order by value from the query string.
|
||||
*/
|
||||
currentOrderBy() {
|
||||
return this.$route.query[this.orderByParameter] || ''
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current order by direction from the query string.
|
||||
*/
|
||||
currentOrderByDirection() {
|
||||
return this.$route.query[this.orderByDirectionParameter] || 'desc'
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current trashed constraint value from the query string.
|
||||
*/
|
||||
currentTrashed() {
|
||||
return this.$route.query[this.trashedParameter] || ''
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the current resource listing is via a many-to-many relationship.
|
||||
*/
|
||||
viaManyToMany() {
|
||||
return (
|
||||
this.relationshipType == 'belongsToMany' ||
|
||||
this.relationshipType == 'morphToMany'
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the resource / relationship is "full".
|
||||
*/
|
||||
resourceIsFull() {
|
||||
return this.viaHasOne && this.resources.length > 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the current resource listing is via a has-one relationship.
|
||||
*/
|
||||
viaHasOne() {
|
||||
return (
|
||||
this.relationshipType == 'hasOne' || this.relationshipType == 'morphOne'
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the singular name for the resource
|
||||
*/
|
||||
singularName() {
|
||||
return this.resourceInformation.singularLabel
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if there are any resources for the view
|
||||
*/
|
||||
hasResources() {
|
||||
return Boolean(this.resources.length > 0)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the resource should show any cards
|
||||
*/
|
||||
shouldShowCards() {
|
||||
return this.cards.length > 0
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the endpoint for this resource's metrics.
|
||||
*/
|
||||
cardsEndpoint() {
|
||||
return `/nova-api/${this.resourceName}/lens/${this.lens}/cards`
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine whether to show the selection checkboxes for resources
|
||||
*/
|
||||
shouldShowCheckBoxes() {
|
||||
return (
|
||||
Boolean(this.hasResources && !this.viaHasOne) &&
|
||||
Boolean(
|
||||
this.actionsAreAvailable ||
|
||||
this.authorizedToDeleteAnyResources ||
|
||||
this.canShowDeleteMenu
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine whether the delete menu should be shown to the user
|
||||
*/
|
||||
shouldShowDeleteMenu() {
|
||||
return (
|
||||
Boolean(this.selectedResources.length > 0) && this.canShowDeleteMenu
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if any selected resources may be deleted.
|
||||
*/
|
||||
authorizedToDeleteSelectedResources() {
|
||||
return Boolean(
|
||||
_.find(this.selectedResources, resource => resource.authorizedToDelete)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if any selected resources may be force deleted.
|
||||
*/
|
||||
authorizedToForceDeleteSelectedResources() {
|
||||
return Boolean(
|
||||
_.find(
|
||||
this.selectedResources,
|
||||
resource => resource.authorizedToForceDelete
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to delete any listed resource.
|
||||
*/
|
||||
authorizedToDeleteAnyResources() {
|
||||
return (
|
||||
this.resources.length > 0 &&
|
||||
Boolean(_.find(this.resources, resource => resource.authorizedToDelete))
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to force delete any listed resource.
|
||||
*/
|
||||
authorizedToForceDeleteAnyResources() {
|
||||
return (
|
||||
this.resources.length > 0 &&
|
||||
Boolean(
|
||||
_.find(this.resources, resource => resource.authorizedToForceDelete)
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if any selected resources may be restored.
|
||||
*/
|
||||
authorizedToRestoreSelectedResources() {
|
||||
return Boolean(
|
||||
_.find(this.selectedResources, resource => resource.authorizedToRestore)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to restore any listed resource.
|
||||
*/
|
||||
authorizedToRestoreAnyResources() {
|
||||
return (
|
||||
this.resources.length > 0 &&
|
||||
Boolean(
|
||||
_.find(this.resources, resource => resource.authorizedToRestore)
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine whether the user is authorized to perform actions on the delete menu
|
||||
*/
|
||||
canShowDeleteMenu() {
|
||||
return (
|
||||
this.hasId &&
|
||||
Boolean(
|
||||
this.authorizedToDeleteSelectedResources ||
|
||||
this.authorizedToForceDeleteSelectedResources ||
|
||||
this.authorizedToDeleteAnyResources ||
|
||||
this.authorizedToForceDeleteAnyResources ||
|
||||
this.authorizedToRestoreSelectedResources ||
|
||||
this.authorizedToRestoreAnyResources
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the currently encoded filter string from the store
|
||||
*/
|
||||
encodedFilters() {
|
||||
return this.$store.getters[`${this.resourceName}/currentEncodedFilters`]
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the initial encoded filters from the query string
|
||||
*/
|
||||
initialEncodedFilters() {
|
||||
return this.$route.query[this.filterParameter] || ''
|
||||
},
|
||||
|
||||
paginationComponent() {
|
||||
return `pagination-${Nova.config['pagination'] || 'links'}`
|
||||
},
|
||||
|
||||
hasNextPage() {
|
||||
return Boolean(
|
||||
this.resourceResponse && this.resourceResponse.next_page_url
|
||||
)
|
||||
},
|
||||
|
||||
hasPreviousPage() {
|
||||
return Boolean(
|
||||
this.resourceResponse && this.resourceResponse.prev_page_url
|
||||
)
|
||||
},
|
||||
|
||||
totalPages() {
|
||||
return Math.ceil(this.allMatchingResourceCount / this.currentPerPage)
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the resource count label
|
||||
*/
|
||||
resourceCountLabel() {
|
||||
const first = this.perPage * (this.currentPage - 1)
|
||||
|
||||
return (
|
||||
this.resources.length &&
|
||||
`${first + 1}-${first + this.resources.length} ${this.__('of')} ${
|
||||
this.allMatchingResourceCount
|
||||
}`
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current per page value from the query string.
|
||||
*/
|
||||
currentPerPage() {
|
||||
return this.perPage
|
||||
},
|
||||
|
||||
/**
|
||||
* The per-page options configured for this resource.
|
||||
*/
|
||||
perPageOptions() {
|
||||
if (this.resourceResponse) {
|
||||
return this.resourceResponse.per_page_options
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The Lense name.
|
||||
*/
|
||||
lenseName() {
|
||||
if (this.resourceResponse) {
|
||||
return this.resourceResponse.name
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user