mirror of https://github.com/rancher/dashboard.git
195 lines
5.6 KiB
Vue
195 lines
5.6 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 { LabelSelectPaginateFn, LabelSelectPaginateFnOptions, LabelSelectPaginateFnResponse } from '@shell/types/components/labeledSelect';
|
|
|
|
type PaginateTypeOverridesFn = (opts: LabelSelectPaginationFunctionOptions) => LabelSelectPaginationFunctionOptions;
|
|
|
|
interface SharedSettings {
|
|
/**
|
|
* Provide specific LabelSelect options for this mode (paginated / not paginated)
|
|
*/
|
|
labelSelectOptions?: { [key: string]: any },
|
|
/**
|
|
* Map the resources shown in LabelSelect
|
|
*/
|
|
mapResult?: (resources: any[]) => any[]
|
|
}
|
|
|
|
/**
|
|
* Settings to use when the LabelSelect is paginating
|
|
*/
|
|
export interface ResourceLabeledSelectPaginateSettings extends SharedSettings {
|
|
/**
|
|
* Override the convience function which fetches a page of results
|
|
*/
|
|
overrideRequest?: LabelSelectPaginateFn,
|
|
/**
|
|
* Override the default settings used in the convenience function to fetch a page of results
|
|
*/
|
|
requestSettings?: PaginateTypeOverridesFn,
|
|
}
|
|
|
|
/**
|
|
* Settings to use when the LabelSelect is fetching all resources (not paginating)
|
|
*/
|
|
export type ResourceLabeledSelectSettings = SharedSettings
|
|
|
|
/**
|
|
* Force a specific mode
|
|
*/
|
|
export enum RESOURCE_LABEL_SELECT_MODE {
|
|
/**
|
|
* Fetch all resources
|
|
*/
|
|
ALL_RESOURCES = 'ALL', // eslint-disable-line no-unused-vars
|
|
/**
|
|
* Determine if all resources are fetched given system settings
|
|
*/
|
|
DYNAMIC = 'DYNAMIC', // eslint-disable-line no-unused-vars
|
|
}
|
|
|
|
/**
|
|
* 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 },
|
|
|
|
props: {
|
|
/**
|
|
* Resource to show
|
|
*/
|
|
resourceType: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
|
|
inStore: {
|
|
type: String,
|
|
default: 'cluster',
|
|
},
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
allResourcesSettings: {
|
|
type: Object as PropType<ResourceLabeledSelectSettings>,
|
|
default: null,
|
|
},
|
|
|
|
/**
|
|
* Specific settings to use when we're showing paginated results
|
|
*/
|
|
paginatedResourceSettings: {
|
|
type: Object as PropType<ResourceLabeledSelectPaginateSettings>,
|
|
default: null,
|
|
},
|
|
},
|
|
|
|
data() {
|
|
return { paginate: false };
|
|
},
|
|
|
|
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.inStore }/paginationEnabled`](this.resourceType);
|
|
break;
|
|
}
|
|
|
|
if (!this.paginate) {
|
|
await this.$store.dispatch(`${ this.inStore }/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.inStore }/all`](this.resourceType);
|
|
|
|
return this.allResourcesSettings?.mapResult ? this.allResourcesSettings.mapResult(all) : all;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
/**
|
|
* 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' }],
|
|
};
|
|
const options = this.paginatedResourceSettings?.requestSettings ? this.paginatedResourceSettings.requestSettings(defaultOptions) : defaultOptions;
|
|
const res = await labelSelectPaginationFunction(options);
|
|
|
|
return this.paginatedResourceSettings?.mapResult ? {
|
|
...res,
|
|
page: this.paginatedResourceSettings.mapResult(res.page)
|
|
} : res;
|
|
},
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<LabeledSelect
|
|
v-bind="labelSelectAttributes"
|
|
:loading="$fetchState.pending"
|
|
:options="allOfType"
|
|
:paginate="paginateType"
|
|
/>
|
|
</template>
|