Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/environments/components/environment_flux_resource_selector.vue')
-rw-r--r--app/assets/javascripts/environments/components/environment_flux_resource_selector.vue210
1 files changed, 210 insertions, 0 deletions
diff --git a/app/assets/javascripts/environments/components/environment_flux_resource_selector.vue b/app/assets/javascripts/environments/components/environment_flux_resource_selector.vue
new file mode 100644
index 00000000000..cad6752da94
--- /dev/null
+++ b/app/assets/javascripts/environments/components/environment_flux_resource_selector.vue
@@ -0,0 +1,210 @@
+<script>
+import { GlFormGroup, GlCollapsibleListbox, GlAlert } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+import fluxKustomizationsQuery from '../graphql/queries/flux_kustomizations.query.graphql';
+import fluxHelmReleasesQuery from '../graphql/queries/flux_helm_releases.query.graphql';
+import {
+ HELM_RELEASES_RESOURCE_TYPE,
+ KUSTOMIZATIONS_RESOURCE_TYPE,
+ KUSTOMIZATION,
+ HELM_RELEASE,
+} from '../constants';
+
+export default {
+ components: {
+ GlFormGroup,
+ GlCollapsibleListbox,
+ GlAlert,
+ },
+ props: {
+ configuration: {
+ required: true,
+ type: Object,
+ },
+ namespace: {
+ required: true,
+ type: String,
+ },
+ fluxResourcePath: {
+ required: false,
+ type: String,
+ default: '',
+ },
+ },
+ i18n: {
+ fluxResourceLabel: s__('Environments|Select Flux resource (optional)'),
+ kustomizationsGroupLabel: s__('Environments|Kustomizations'),
+ helmReleasesGroupLabel: s__('Environments|HelmReleases'),
+ fluxResourcesHelpText: s__('Environments|Select Flux resource'),
+ errorTitle: s__(
+ 'Environments|Unable to access the following resources from this environment. Check your authorization on the following and try again:',
+ ),
+ reset: __('Reset'),
+ },
+ data() {
+ return {
+ fluxResourceSearchTerm: '',
+ kustomizationsError: '',
+ helmReleasesError: '',
+ };
+ },
+ apollo: {
+ fluxKustomizations: {
+ query: fluxKustomizationsQuery,
+ variables() {
+ return {
+ configuration: this.configuration,
+ namespace: this.namespace,
+ };
+ },
+ skip() {
+ return !this.namespace;
+ },
+ update(data) {
+ return data?.fluxKustomizations || [];
+ },
+ error() {
+ this.kustomizationsError = KUSTOMIZATION;
+ },
+ result(result) {
+ if (!result?.error && !result.errors?.length) {
+ this.kustomizationsError = '';
+ }
+ },
+ },
+ fluxHelmReleases: {
+ query: fluxHelmReleasesQuery,
+ variables() {
+ return {
+ configuration: this.configuration,
+ namespace: this.namespace,
+ };
+ },
+ skip() {
+ return !this.namespace;
+ },
+ update(data) {
+ return data?.fluxHelmReleases || [];
+ },
+ error() {
+ this.helmReleasesError = HELM_RELEASE;
+ },
+ result(result) {
+ if (!result?.error && !result.errors?.length) {
+ this.helmReleasesError = '';
+ }
+ },
+ },
+ },
+ computed: {
+ variables() {
+ return {
+ configuration: this.configuration,
+ namespace: this.namespace,
+ };
+ },
+ loadingFluxResourcesList() {
+ return this.$apollo.loading;
+ },
+ kubernetesErrors() {
+ const errors = [];
+ if (this.kustomizationsError) {
+ errors.push(this.kustomizationsError);
+ }
+ if (this.helmReleasesError) {
+ errors.push(this.helmReleasesError);
+ }
+ return errors;
+ },
+ fluxResourcesDropdownToggleText() {
+ const selectedResourceParts = this.fluxResourcePath ? this.fluxResourcePath.split('/') : [];
+ return selectedResourceParts.length
+ ? selectedResourceParts.at(-1)
+ : this.$options.i18n.fluxResourcesHelpText;
+ },
+ fluxKustomizationsList() {
+ return (
+ this.fluxKustomizations?.map((item) => {
+ return {
+ value: `${item.apiVersion}/namespaces/${item.metadata.namespace}/${KUSTOMIZATIONS_RESOURCE_TYPE}/${item.metadata.name}`,
+ text: item.metadata.name,
+ };
+ }) || []
+ );
+ },
+ fluxHelmReleasesList() {
+ return (
+ this.fluxHelmReleases?.map((item) => {
+ return {
+ value: `${item.apiVersion}/namespaces/${item.metadata.namespace}/${HELM_RELEASES_RESOURCE_TYPE}/${item.metadata.name}`,
+ text: item.metadata.name,
+ };
+ }) || []
+ );
+ },
+ filteredKustomizationsList() {
+ const lowerCasedSearchTerm = this.fluxResourceSearchTerm.toLowerCase();
+ return this.fluxKustomizationsList.filter((item) =>
+ item.text.toLowerCase().includes(lowerCasedSearchTerm),
+ );
+ },
+ filteredHelmResourcesList() {
+ const lowerCasedSearchTerm = this.fluxResourceSearchTerm.toLowerCase();
+ return this.fluxHelmReleasesList.filter((item) =>
+ item.text.toLowerCase().includes(lowerCasedSearchTerm),
+ );
+ },
+ fluxResourcesList() {
+ const list = [];
+ if (this.filteredKustomizationsList?.length) {
+ list.push({
+ text: this.$options.i18n.kustomizationsGroupLabel,
+ options: this.filteredKustomizationsList,
+ });
+ }
+
+ if (this.filteredHelmResourcesList?.length) {
+ list.push({
+ text: this.$options.i18n.helmReleasesGroupLabel,
+ options: this.filteredHelmResourcesList,
+ });
+ }
+ return list;
+ },
+ },
+ methods: {
+ onChange(event) {
+ this.$emit('change', event);
+ },
+ onSearch(search) {
+ this.fluxResourceSearchTerm = search;
+ },
+ },
+};
+</script>
+<template>
+ <gl-form-group :label="$options.i18n.fluxResourceLabel" label-for="environment_flux_resource">
+ <gl-alert v-if="kubernetesErrors.length" variant="warning" :dismissible="false" class="gl-mb-5">
+ {{ $options.i18n.errorTitle }}
+ <ul class="gl-mb-0 gl-pl-6">
+ <li v-for="(error, index) of kubernetesErrors" :key="index">{{ error }}</li>
+ </ul>
+ </gl-alert>
+
+ <gl-collapsible-listbox
+ id="environment_flux_resource_path"
+ class="gl-w-full"
+ block
+ :selected="fluxResourcePath"
+ :items="fluxResourcesList"
+ :loading="loadingFluxResourcesList"
+ :toggle-text="fluxResourcesDropdownToggleText"
+ :header-text="$options.i18n.fluxResourcesHelpText"
+ :reset-button-label="$options.i18n.reset"
+ searchable
+ @search="onSearch"
+ @select="onChange"
+ @reset="onChange(null)"
+ />
+ </gl-form-group>
+</template>