mirror of https://github.com/rancher/dashboard.git
170 lines
5.1 KiB
Vue
170 lines
5.1 KiB
Vue
<script lang="ts">
|
|
import { PropType, defineComponent } from 'vue';
|
|
import LabeledSelect from '@shell/components/form/LabeledSelect.vue';
|
|
import { PaginationParamFilter } from '@shell/types/store/pagination.types';
|
|
import { labelSelectPaginationFunction, LabelSelectPaginationFunctionOptions } from '@shell/components/form/labeled-select-utils/labeled-select.utils';
|
|
import { LabelSelectPaginateFnOptions, LabelSelectPaginateFnResponse } from '@shell/types/components/labeledSelect';
|
|
import { RESOURCE_LABEL_SELECT_MODE, ResourceLabeledSelectPaginateSettings, ResourceLabeledSelectSettings } from '@shell/types/components/resourceLabeledSelect';
|
|
|
|
/**
|
|
* Convenience wrapper around the LabelSelect component to support pagination
|
|
*
|
|
* Handles
|
|
*
|
|
* 1) Conditionally enabling the pagination feature given system settings
|
|
* 2) Helper function to fetch the pagination result
|
|
*
|
|
* A number of ways can be provided to override the conveniences (see props)
|
|
*/
|
|
export default defineComponent({
|
|
name: 'ResourceLabeledSelect',
|
|
|
|
components: { LabeledSelect },
|
|
|
|
emits: ['update:value'],
|
|
|
|
props: {
|
|
/**
|
|
* Resource to show
|
|
*/
|
|
resourceType: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
|
|
inStore: {
|
|
type: String,
|
|
default: undefined,
|
|
},
|
|
|
|
/**
|
|
* Determine if pagination is used via settings (DYNAMIC) or hardcode off
|
|
*/
|
|
paginateMode: {
|
|
type: String as PropType<RESOURCE_LABEL_SELECT_MODE>,
|
|
default: RESOURCE_LABEL_SELECT_MODE.DYNAMIC,
|
|
},
|
|
|
|
/**
|
|
* Specific settings to use when we're showing all results in the drop down
|
|
*/
|
|
allResourcesSettings: {
|
|
type: Object as PropType<ResourceLabeledSelectSettings>,
|
|
default: null,
|
|
},
|
|
|
|
/**
|
|
* Specific settings to use when we're showing paginated results in the drop down
|
|
*/
|
|
paginatedResourceSettings: {
|
|
type: Object as PropType<ResourceLabeledSelectPaginateSettings>,
|
|
default: null,
|
|
},
|
|
},
|
|
|
|
data() {
|
|
let validInStore = this.inStore;
|
|
|
|
if (!validInStore && this.resourceType) {
|
|
validInStore = this.$store.getters['currentStore'](this.resourceType);
|
|
}
|
|
|
|
if (!validInStore) {
|
|
validInStore = 'cluster';
|
|
}
|
|
|
|
return {
|
|
paginate: false,
|
|
validInStore,
|
|
};
|
|
},
|
|
|
|
async fetch() {
|
|
switch (this.paginateMode) {
|
|
case RESOURCE_LABEL_SELECT_MODE.ALL_RESOURCES:
|
|
this.paginate = false;
|
|
break;
|
|
case RESOURCE_LABEL_SELECT_MODE.DYNAMIC:
|
|
this.paginate = this.$store.getters[`${ this.validInStore }/paginationEnabled`](this.resourceType);
|
|
break;
|
|
}
|
|
|
|
if (!this.paginate) {
|
|
// The resource won't be paginated and component expects everything up front
|
|
await this.$store.dispatch(`${ this.validInStore }/findAll`, { type: this.resourceType });
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
labelSelectAttributes() {
|
|
// This component is a wrapper for LabelSelect, so pass through everything
|
|
const allAttrs = {
|
|
...this.$attrs, // Attributes (other than props)
|
|
...this.$props, // Attributes that are props
|
|
};
|
|
|
|
return this.paginate ? {
|
|
...allAttrs,
|
|
...this.paginatedResourceSettings?.labelSelectOptions || {}
|
|
} : {
|
|
...allAttrs,
|
|
...this.allResourcesSettings?.labelSelectOptions || {}
|
|
};
|
|
},
|
|
|
|
allOfType() {
|
|
if (this.$fetchState.pending || this.paginate) {
|
|
return [];
|
|
}
|
|
|
|
const all = this.$store.getters[`${ this.validInStore }/all`](this.resourceType);
|
|
|
|
return this.allResourcesSettings?.updateResources ? this.allResourcesSettings.updateResources(all) : all;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* Make the request to fetch the resource given the state of the label select (filter, page, page size, etc see LabelSelectPaginateFn)
|
|
* opts: Typeof LabelSelectPaginateFn
|
|
*/
|
|
async paginateType(opts: LabelSelectPaginateFnOptions): Promise<LabelSelectPaginateFnResponse> {
|
|
if (this.paginatedResourceSettings?.overrideRequest) {
|
|
return await this.paginatedResourceSettings.overrideRequest(opts);
|
|
}
|
|
|
|
const { filter } = opts;
|
|
const filters = !!filter ? [PaginationParamFilter.createSingleField({
|
|
field: 'metadata.name', value: filter, exact: false
|
|
})] : [];
|
|
const defaultOptions: LabelSelectPaginationFunctionOptions = {
|
|
opts,
|
|
filters,
|
|
type: this.resourceType,
|
|
ctx: { getters: this.$store.getters, dispatch: this.$store.dispatch },
|
|
sort: [{ asc: true, field: 'metadata.name' }],
|
|
store: this.validInStore
|
|
};
|
|
const options = this.paginatedResourceSettings?.requestSettings ? this.paginatedResourceSettings.requestSettings(defaultOptions) : defaultOptions;
|
|
const res = await labelSelectPaginationFunction(options);
|
|
|
|
return this.paginatedResourceSettings?.updateResources ? {
|
|
...res,
|
|
page: this.paginatedResourceSettings.updateResources(res.page)
|
|
} : res;
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<LabeledSelect
|
|
v-bind="labelSelectAttributes"
|
|
:loading="$fetchState.pending"
|
|
:options="allOfType"
|
|
:paginate="paginateType"
|
|
:multiple="$attrs.multiple || false"
|
|
@update:value="$emit('update:value', $event)"
|
|
/>
|
|
</template>
|